diff --git a/dist/iife/no.js b/dist/iife/no.js index d53cac04..40dc5110 100644 --- a/dist/iife/no.js +++ b/dist/iife/no.js @@ -6,10 +6,10 @@ * @license MIT * @see https://github.com/no-js-dev/nojs */ -(()=>{var Ti=Object.defineProperty;var dr=(e,t)=>()=>(e&&(t=e(e=0)),t);var Li=(e,t)=>{for(var n in t)Ti(e,n,{get:t[n],enumerable:!0})};function On(e){Zt=e}function Nn(e){ht=e}function ct(e){he=e}function Pn(e){de=e}function ee(...e){g.debug&&console.log("[No.JS]",...e)}function w(...e){console.warn("[No.JS]",...e)}function Mt(e){let t=(g.router.base||"/").replace(/\/$/,"");if(!t)return e||"/";let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.replace(new RegExp("^"+n),"")||"/"}function Ft(e){if(typeof e!="string")return null;let t=Oi.exec(e);return t?t[1]:null}function Cn(e){for(let t of[...e]){if(t._el&&!t._el.isConnected){e.delete(t);continue}try{t()}catch(n){w("store watcher threw; continuing with remaining watchers:",n)}}}function it(e){if(e){let t=tt.get(e);t&&Cn(t);let n=tt.get("*");n&&Cn(n)}else for(let t of tt.values())Cn(t)}function In(e,t){let n=tt.get(t);n||(n=new Set,tt.set(t,n)),n.add(e),e._storePartition=t}function xt(e){let t=e._storePartition;if(t){let n=tt.get(t);n&&(n.delete(e),n.size===0&&tt.delete(t))}else for(let[n,r]of tt)r.delete(e),r.size===0&&tt.delete(n)}function $n(){for(let e of[...Yt]){if(e._el&&!e._el.isConnected){Yt.delete(e);continue}try{e()}catch(t){w("route watcher threw; continuing with remaining watchers:",t)}}}function kn(e){Yt.add(e)}function Ht(e){Yt.delete(e)}function gt(e){return We.add(e),()=>We.delete(e)}function hr(e){Tn=e}function ue(e,t,n){if(Tn&&!n._unkeyed){let i=Tn(e);if(i===null)n._unkeyed=!0,n._keys=void 0;else if(n._keys){n._keysShared&&(n._keys=new Set(n._keys),n._keysShared=!1);for(let o of i)n._keys.add(o)}else n._keys=i,n._keysShared=!0}he&&(n._el=he);let r=t;for(;r&&r.__isProxy;)r.__listeners.add(n),r=r.$parent;if(he&&!he.__gatedDirs?(n._wctx=t,(he.__watcherFns||(he.__watcherFns=[])).push(n)):M(()=>{let i=t;for(;i&&i.__isProxy;)i.__listeners.delete(n),i=i.$parent;xt(n),Ht(n),We.delete(n)}),typeof e=="string"&&e.includes("$store")){let i=Ft(e)||"*";In(n,i),n._el=he}typeof e=="string"&&e.includes("$route")&&(kn(n),n._el=he),typeof e=="string"&&e.includes("$i18n")&&(gt(n),n._el=he)}function M(e){he&&(he.__disposers=he.__disposers||[],he.__disposers.push(e))}function Ke(e,t){(nt[e]||[]).forEach(n=>n(t))}var g,Je,nt,le,tt,We,Yt,Y,Ln,Ye,rt,de,qe,De,mt,Zt,ht,At,pr,mr,he,Oi,Tn,Bt,Ct,Ut,_e=dr(()=>{g={baseApiUrl:"",headers:{},timeout:1e4,retries:0,retryDelay:1e3,credentials:"same-origin",csrf:null,cache:{strategy:"none",ttl:3e5},templates:{cache:!0},router:{useHash:!1,base:"/",scrollBehavior:"top",templates:"pages",ext:".tpl",suppressHashWarning:!1,focusBehavior:"none",viewTransition:!0},i18n:{defaultLocale:"en",fallbackLocale:"en",detectBrowser:!1,loadPath:null,ns:[],supportedLocales:[],cache:!0,persist:!1},debug:!1,devtools:!1,sanitize:!0,dangerouslyDisableSanitize:!1,sanitizeHtml:null,exprCacheSize:500,maxEventListeners:100,appId:""},Je={request:[],response:[]},nt={},le={},tt=new Map,We=new Set,Yt=new Set,Y={},Ln={},Ye=new Map,rt={},de=null,qe=new Map,De=Object.create(null),mt=Object.create(null),Zt=!1;ht=null;At=new Set(["authorization","x-api-key","x-auth-token","cookie","proxy-authorization","set-cookie","x-csrf-token"]),pr=new Set(["token","password","secret","key","auth","credential","session"]),mr=new Set(["set-cookie","x-csrf-token","x-auth-token","www-authenticate","proxy-authenticate"]),he=null;Oi=/\$store\.(\w+)/;Tn=null;Bt=Symbol("nojs.cancel"),Ct=Symbol("nojs.respond"),Ut=Symbol("nojs.replace")});var tn={};Li(tn,{_i18n:()=>pe,_i18nProxy:()=>Lt,_i18nTranslationCache:()=>_t,_loadI18nForLocale:()=>Rn,_loadI18nNamespace:()=>Dn,_notifyI18n:()=>Tt});function Tt(){_t.clear();for(let e of We){if(e._el&&!e._el.isConnected){We.delete(e);continue}e()}}function _r(e,t){let n={...e};for(let r of Object.keys(t))Ni.has(r)||(t[r]&&typeof t[r]=="object"&&!Array.isArray(t[r])&&e[r]&&typeof e[r]=="object"&&!Array.isArray(e[r])?n[r]=_r(e[r],t[r]):n[r]=t[r]);return n}async function Qt(e,t){let n=t?`${e}:${t}`:e;if(g.i18n.cache&&gr.has(n))return;let r=g.i18n.loadPath.replace("{locale}",encodeURIComponent(e));if(t)r=r.replace("{ns}",encodeURIComponent(t));else if(r.includes("{ns}"))return;try{let i=await fetch(r);if(!i.ok){w(`i18n: failed to load ${r} (${i.status})`);return}let o=await i.json();pe.locales[e]=_r(pe.locales[e]||{},o),_t.clear(),g.i18n.cache&&gr.set(n,o)}catch(i){w(`i18n: error loading ${r}`,i)}}async function Rn(e){if(!g.i18n.loadPath)return;let t=g.i18n.ns;!t.length||!g.i18n.loadPath.includes("{ns}")?await Qt(e,null):await Promise.all(t.map(n=>Qt(e,n)))}async function Dn(e){if(!g.i18n.loadPath)return;yr.add(e);let t=new Set([pe.locale,g.i18n.fallbackLocale]);await Promise.all([...t].map(n=>Qt(n,e)))}function en(e){return new Proxy(Object.create(null),{get(t,n){if(typeof n!="string")return;let r=e?e+"."+n:n,i=pe.locale,o=pe.locales[i],s=r.split(".").reduce((l,u)=>l?.[u],o||{});if(s!=null&&typeof s=="object"&&!Array.isArray(s))return en(r);if(s!=null)return s;let a=g.i18n.fallbackLocale;if(a&&a!==i){let l=pe.locales[a],u=r.split(".").reduce((d,p)=>d?.[p],l||{});if(u!=null&&typeof u=="object"&&!Array.isArray(u))return en(r);if(u!=null)return u}}})}var Ni,_t,gr,yr,pe,Lt,ot=dr(()=>{_e();Ni=new Set(["__proto__","constructor","prototype"]);_t=new Map,gr=new Map,yr=new Set;pe={_locale:"en",_locales:{},get locales(){return this._locales},set locales(e){this._locales=e,_t.clear()},get locale(){return this._locale},set locale(e){let t=g.i18n.supportedLocales;if(Array.isArray(t)&&t.length&&!t.includes(e)){w(`i18n: locale "${e}" is not in supportedLocales; ignoring`);return}if(this._locale!==e){if(this._locale=e,_t.clear(),g.i18n.persist&&typeof localStorage<"u")try{localStorage.setItem("nojs-locale",e)}catch{}if(g.i18n.loadPath){let n=new Set([...g.i18n.ns,...yr]);Promise.all([...n].map(r=>Qt(e,r))).then(()=>Tt())}else Tt()}},t(e,t={}){let n=`${pe.locale}:${e}`,r=_t.get(n);if(r===void 0){let i=o=>e.split(".").reduce((s,a)=>s?.[a],pe.locales[o]||{});r=i(pe.locale),r==null&&g.i18n.fallbackLocale&&g.i18n.fallbackLocale!==pe.locale&&(r=i(g.i18n.fallbackLocale)),_t.set(n,r??null)}if(r==null)return e;if(typeof r=="string"&&r.includes("|")&&t.count!=null){let i=r.split("|").map(o=>o.trim());r=Number(t.count)===1?i[0]:i[1]||i[0]}return typeof r=="string"&&(r=r.replace(/\{(\w+)\}/g,(i,o)=>t[o]!=null?t[o]:"")),r}};Lt=new Proxy(pe,{get(e,t){if(typeof t!="string"||t==="locale"||t==="locales"||t==="t")return e[t];if(t==="setLocale")return s=>{e.locale=s};let n=e.locale,i=e.locales[n]?.[t];if(i!=null&&typeof i=="object"&&!Array.isArray(i))return en(t);if(i!=null)return i;let o=g.i18n.fallbackLocale;if(o&&o!==n){let a=e.locales[o]?.[t];if(a!=null&&typeof a=="object"&&!Array.isArray(a))return en(t);if(a!=null)return a}}})});_e();ot();_e();ot();_e();ot();var bt=new Map;function Pi(e){return e===void 0&&(e=typeof window<"u"&&window.location?window.location.hostname:""),e===""||e==="localhost"||e==="127.0.0.1"||e==="::1"||e==="0.0.0.0"||e.endsWith(".localhost")}function Te(e,t){!g.devtools||typeof window>"u"||window.dispatchEvent(new CustomEvent("nojs:devtools",{detail:{type:e,data:t,timestamp:Date.now()}}))}function on(e,t){if(!e||!e.__isProxy)return null;let n=e.__raw;if(t||(t=new WeakSet),n&&t.has(n))return"[Circular]";n&&t.add(n);let r={};for(let i of Object.keys(n)){if(i.startsWith("__"))continue;let o=n[i];if(o&&typeof o=="object"&&o.__isProxy)r[i]=on(o,t);else try{JSON.stringify(o),r[i]=o}catch{r[i]=String(o)}}return r}function br(e){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e):e}function Er(e){if(!e||!e.tagName)return null;let t=e.tagName.toLowerCase(),n=e.id?`#${br(e.id)}`:"",r=e.className&&typeof e.className=="string"?e.className.trim().split(/\s+/).filter(Boolean).map(i=>"."+br(i)).join(""):"";return t+n+r}function Sr(e){let t=document.querySelector(e);if(!t)return{error:"Element not found",selector:e};let n=t.__ctx;return{selector:e,tag:Er(t),hasContext:!!n,contextId:n?.__raw?.__devtoolsId??null,data:n?on(n):null,directives:[...t.attributes].filter(r=>!["class","id","style"].includes(r.name)).map(r=>({name:r.name,value:r.value}))}}function Ar(e){let t=le[e];return t?{name:e,contextId:t.__raw?.__devtoolsId??null,data:on(t)}:{error:"Store not found",name:e}}function xr(e){let t=e?document.querySelector(e):document.body;if(!t)return{error:"Root not found",selector:e};function n(r){let i=r.__ctx,o={tag:Er(r),contextId:i?.__raw?.__devtoolsId??null,children:[]};for(let s of r.children)s.tagName==="TEMPLATE"||s.tagName==="SCRIPT"||(s.__ctx||s.__declared)&&o.children.push(n(s));return o}return n(t)}function Cr(e,t,n){let r=bt.get(e);return r?(r[t]=n,{ok:!0,id:e,key:t}):{error:"Context not found",id:e}}function Tr(e,t,n){let r=le[e];return r?(r[t]=n,{ok:!0,name:e,key:t}):{error:"Store not found",name:e}}function Lr(){let e=0;for(let[,t]of bt)t.__listeners&&(e+=t.__listeners.size);return{contexts:bt.size,stores:Object.keys(le).length,listeners:e,refs:Object.keys(rt).length,hasRouter:!!de,locale:pe.locale}}var st=null,nn=null,yt=null;function wr(){if(!st||!nn)return;let e=nn.getBoundingClientRect();Object.assign(st.style,{top:e.top+"px",left:e.left+"px",width:e.width+"px",height:e.height+"px"})}function Or(e){sn();let t=document.querySelector(e);t&&(nn=t,st=document.createElement("div"),st.id="__nojs_devtools_highlight__",Object.assign(st.style,{position:"fixed",background:"rgba(66, 133, 244, 0.25)",border:"2px solid rgba(66, 133, 244, 0.8)",pointerEvents:"none",zIndex:"2147483647",borderRadius:"3px"}),document.body.appendChild(st),wr(),yt=()=>wr(),window.addEventListener("scroll",yt,!0),window.addEventListener("resize",yt))}function sn(){yt&&(window.removeEventListener("scroll",yt,!0),window.removeEventListener("resize",yt),yt=null),st&&(st.remove(),st=null),nn=null}function vr(e){let{command:t,args:n={}}=e.detail||{},r;switch(t){case"inspect:element":r=Sr(n.selector);break;case"inspect:store":r=Ar(n.name);break;case"inspect:tree":r=xr(n.selector);break;case"mutate:context":r=Cr(n.id,n.key,n.value);break;case"mutate:store":r=Tr(n.name,n.key,n.value);break;case"get:config":r={...g},r.csrf&&(r.csrf={...r.csrf,token:"[REDACTED]"}),r.headers&&(r.headers="[REDACTED]");break;case"get:routes":r=de?de.routes||[]:[];break;case"get:stats":r=Lr();break;case"highlight:element":Or(n.selector),r={ok:!0};break;case"unhighlight":sn(),r={ok:!0};break;default:r={error:"Unknown command",command:t}}window.dispatchEvent(new CustomEvent("nojs:devtools:response",{detail:{command:t,result:r,timestamp:Date.now()}}))}var rn=null;function Nr(){sn(),rn&&rn()}function Pr(e){if(!(!g.devtools||typeof window>"u")){if(!Pi()){console.warn("[No.JS] devtools: true is ignored outside local environments. Remove devtools: true before deploying to production.");return}window.addEventListener("nojs:devtools:cmd",vr),rn=()=>{window.removeEventListener("nojs:devtools:cmd",vr),delete window.__NOJS_DEVTOOLS__,rn=null},window.__NOJS_DEVTOOLS__={get stores(){return Object.fromEntries(Object.entries(le).map(([t,n])=>[t,on(n)]))},get config(){let t={...g};return t.headers&&(t.headers={...t.headers}),t.router&&(t.router={...t.router}),t.cache&&(t.cache={...t.cache}),t.csrf&&(t.csrf={...t.csrf}),t.i18n&&(t.i18n={...t.i18n}),t},get refs(){return{...rt}},router:de,version:e.version,get plugins(){return new Map(qe)},get globals(){return{...De}},inspect:t=>Sr(t),inspectStore:t=>Ar(t),inspectTree:t=>xr(t),stats:()=>Lr(),mutate:(t,n,r)=>Cr(t,n,r),mutateStore:(t,n,r)=>Tr(t,n,r),highlight:t=>Or(t),unhighlight:()=>sn(),on:(t,n)=>{let r=i=>{(!t||i.detail.type===t)&&n(i.detail)};return window.addEventListener("nojs:devtools",r),()=>window.removeEventListener("nojs:devtools",r)}},console.log("[No.JS DevTools] enabled \u2014 access via window.__NOJS_DEVTOOLS__")}}var Ir=new Set(["__proto__","constructor","prototype"]),wt=0,lt=new Set,Ii=0,an=0;function Mn(){wt++,Te("batch:start",{depth:wt})}function Fn(){if(wt--,wt===0&<.size>0){Te("batch:end",{depth:0,queueSize:lt.size});let e=0;for(;lt.size>0;){if(++e>100){w("batch drain exceeded 100 rounds \u2014 possible update cycle; aborting drain"),lt=new Set;break}let t=lt;lt=new Set,wt++;try{t.forEach(n=>{if(!(n._el&&!n._el.isConnected)){lt.delete(n);try{n()}catch(r){w("batched listener threw; continuing with remaining listeners:",r)}}})}finally{wt--}}}}var Ve=Symbol("no.js");function jn(e,t){let n=e.listeners;if(!n||n.size===0)return;let r=wt===0;r&&Mn();for(let i of n){if(i._el&&!i._el.isConnected){n.delete(i);continue}t!==void 0&&i._keys&&!i._keys.has(t)||lt.add(i)}r&&Fn()}var $i={get(e,t){if(typeof t!="string")return e[t];let n=t.charCodeAt(0);if(n!==36&&n!==95){if(t in e)return e[t];let o=e[Ve].parent;return o&&o.__isProxy?o[t]:void 0}if(n===95){if(t==="__isProxy")return!0;if(t==="__raw")return e;if(t==="__listeners"){let s=e[Ve];return s.listeners||(s.listeners=new Set)}if(t in e)return e[t];let o=e[Ve].parent;return o&&o.__isProxy?o[t]:void 0}switch(t){case"$watch":{let o=e[Ve];return o.watchFn||(o.watchFn=s=>(he&&(s._el=he),(o.listeners||(o.listeners=new Set)).add(s),()=>{o.listeners&&o.listeners.delete(s)}))}case"$notify":{let o=e[Ve];return o.notifyFn||(o.notifyFn=s=>jn(o,typeof s=="string"?s:void 0))}case"$set":{let o=e[Ve];return o.setFn||(o.setFn=(s,a)=>{let l=s.split(".");if(!l.some(u=>Ir.has(u)))if(l.length===1)o.proxy[s]=a;else{let u=o.proxy;for(let y=0;y=r&&e.delete(e.keys().next().value),e.set(t,n)},get size(){return e.size}}}var kr=Mr(),Hn=Mr(),ki=new Set(["true","false","null","undefined","typeof","in","instanceof"]),Ri=new Set(["__proto__","constructor","prototype"]),Rr=["===","!==","...","??","?.","==","!=",">=","<=","&&","||","+=","-=","*=","/=","%=","++","--","=>"],Di=new Set(["+","-","*","/","%",">","<","!","=","|"]),ji=new Set(["(",")","[","]","{","}",".",",",":",";","?"]);function Wt(e){if(typeof e!="string")return[];let t=[],n=e.length,r=0;for(;r{var Oi=Object.defineProperty;var pr=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ni=(e,t)=>{for(var n in t)Oi(e,n,{get:t[n],enumerable:!0})};function In(e){en=e}function $n(e){_t=e}function lt(e){fe=e}function kn(e){me=e}function te(...e){_.debug&&console.log("[No.JS]",...e)}function w(...e){console.warn("[No.JS]",...e)}function Ht(e){let t=(_.router.base||"/").replace(/\/$/,"");if(!t)return e||"/";let n=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.replace(new RegExp("^"+n),"")||"/"}function yt(e){if(typeof e!="string")return null;let t=Pi.exec(e);return t?t[1]:null}function On(e){for(let t of[...e]){if(t._el&&!t._el.isConnected){e.delete(t);continue}try{t()}catch(n){w("store watcher threw; continuing with remaining watchers:",n)}}}function Ve(e){if(e){let t=nt.get(e);t&&On(t);let n=nt.get("*");n&&On(n)}else for(let t of nt.values())On(t)}function Bt(e,t){let n=nt.get(t);n||(n=new Set,nt.set(t,n)),n.add(e),e._storePartition=t}function ut(e){let t=e._storePartition;if(t){let n=nt.get(t);n&&(n.delete(e),n.size===0&&nt.delete(t))}else for(let[n,r]of nt)r.delete(e),r.size===0&&nt.delete(n)}function Rn(){for(let e of[...Qt]){if(e._el&&!e._el.isConnected){Qt.delete(e);continue}try{e()}catch(t){w("route watcher threw; continuing with remaining watchers:",t)}}}function Ut(e){Qt.add(e)}function bt(e){Qt.delete(e)}function ot(e){return We.add(e),()=>We.delete(e)}function gr(e){Nn=e}function de(e,t,n){if(Nn&&!n._unkeyed){let i=Nn(e);if(i===null)n._unkeyed=!0,n._keys=void 0;else if(n._keys){n._keysShared&&(n._keys=new Set(n._keys),n._keysShared=!1);for(let o of i)n._keys.add(o)}else n._keys=i,n._keysShared=!0}fe&&(n._el=fe);let r=t;for(;r&&r.__isProxy;)r.__listeners.add(n),r=r.$parent;if(fe&&!fe.__gatedDirs?(n._wctx=t,(fe.__watcherFns||(fe.__watcherFns=[])).push(n)):D(()=>{let i=t;for(;i&&i.__isProxy;)i.__listeners.delete(n),i=i.$parent;ut(n),bt(n),We.delete(n)}),typeof e=="string"&&e.includes("$store")){let i=yt(e)||"*";Bt(n,i),n._el=fe}typeof e=="string"&&e.includes("$route")&&(Ut(n),n._el=fe),typeof e=="string"&&e.includes("$i18n")&&(ot(n),n._el=fe)}function D(e){fe&&(fe.__disposers=fe.__disposers||[],fe.__disposers.push(e))}function Ge(e,t){(rt[e]||[]).forEach(n=>n(t))}var _,Ke,rt,se,nt,We,Qt,Q,Pn,Ze,it,me,Je,De,gt,en,_t,Tt,mr,hr,fe,Pi,Nn,zt,Lt,Wt,ge=pr(()=>{_={baseApiUrl:"",headers:{},timeout:1e4,retries:0,retryDelay:1e3,credentials:"same-origin",csrf:null,cache:{strategy:"none",ttl:3e5},templates:{cache:!0},router:{useHash:!1,base:"/",scrollBehavior:"top",templates:"pages",ext:".tpl",suppressHashWarning:!1,focusBehavior:"none",viewTransition:!0},i18n:{defaultLocale:"en",fallbackLocale:"en",detectBrowser:!1,loadPath:null,ns:[],supportedLocales:[],cache:!0,persist:!1},debug:!1,devtools:!1,sanitize:!0,dangerouslyDisableSanitize:!1,sanitizeHtml:null,exprCacheSize:500,maxEventListeners:100,appId:""},Ke={request:[],response:[]},rt={},se={},nt=new Map,We=new Set,Qt=new Set,Q={},Pn={},Ze=new Map,it={},me=null,Je=new Map,De=Object.create(null),gt=Object.create(null),en=!1;_t=null;Tt=new Set(["authorization","x-api-key","x-auth-token","cookie","proxy-authorization","set-cookie","x-csrf-token"]),mr=new Set(["token","password","secret","key","auth","credential","session"]),hr=new Set(["set-cookie","x-csrf-token","x-auth-token","www-authenticate","proxy-authenticate"]),fe=null;Pi=/\$store\.(\w+)/;Nn=null;zt=Symbol("nojs.cancel"),Lt=Symbol("nojs.respond"),Wt=Symbol("nojs.replace")});var rn={};Ni(rn,{_i18n:()=>he,_i18nProxy:()=>Nt,_i18nTranslationCache:()=>wt,_loadI18nForLocale:()=>Dn,_loadI18nNamespace:()=>jn,_notifyI18n:()=>Ot});function Ot(){wt.clear();for(let e of We){if(e._el&&!e._el.isConnected){We.delete(e);continue}e()}}function yr(e,t){let n={...e};for(let r of Object.keys(t))Ii.has(r)||(t[r]&&typeof t[r]=="object"&&!Array.isArray(t[r])&&e[r]&&typeof e[r]=="object"&&!Array.isArray(e[r])?n[r]=yr(e[r],t[r]):n[r]=t[r]);return n}async function tn(e,t){let n=t?`${e}:${t}`:e;if(_.i18n.cache&&_r.has(n))return;let r=_.i18n.loadPath.replace("{locale}",encodeURIComponent(e));if(t)r=r.replace("{ns}",encodeURIComponent(t));else if(r.includes("{ns}"))return;try{let i=await fetch(r);if(!i.ok){w(`i18n: failed to load ${r} (${i.status})`);return}let o=await i.json();he.locales[e]=yr(he.locales[e]||{},o),wt.clear(),_.i18n.cache&&_r.set(n,o)}catch(i){w(`i18n: error loading ${r}`,i)}}async function Dn(e){if(!_.i18n.loadPath)return;let t=_.i18n.ns;!t.length||!_.i18n.loadPath.includes("{ns}")?await tn(e,null):await Promise.all(t.map(n=>tn(e,n)))}async function jn(e){if(!_.i18n.loadPath)return;br.add(e);let t=new Set([he.locale,_.i18n.fallbackLocale]);await Promise.all([...t].map(n=>tn(n,e)))}function nn(e){return new Proxy(Object.create(null),{get(t,n){if(typeof n!="string")return;let r=e?e+"."+n:n,i=he.locale,o=he.locales[i],s=r.split(".").reduce((l,u)=>l?.[u],o||{});if(s!=null&&typeof s=="object"&&!Array.isArray(s))return nn(r);if(s!=null)return s;let a=_.i18n.fallbackLocale;if(a&&a!==i){let l=he.locales[a],u=r.split(".").reduce((d,p)=>d?.[p],l||{});if(u!=null&&typeof u=="object"&&!Array.isArray(u))return nn(r);if(u!=null)return u}}})}var Ii,wt,_r,br,he,Nt,st=pr(()=>{ge();Ii=new Set(["__proto__","constructor","prototype"]);wt=new Map,_r=new Map,br=new Set;he={_locale:"en",_locales:{},get locales(){return this._locales},set locales(e){this._locales=e,wt.clear()},get locale(){return this._locale},set locale(e){let t=_.i18n.supportedLocales;if(Array.isArray(t)&&t.length&&!t.includes(e)){w(`i18n: locale "${e}" is not in supportedLocales; ignoring`);return}if(this._locale!==e){if(this._locale=e,wt.clear(),_.i18n.persist&&typeof localStorage<"u")try{localStorage.setItem("nojs-locale",e)}catch{}if(_.i18n.loadPath){let n=new Set([..._.i18n.ns,...br]);Promise.all([...n].map(r=>tn(e,r))).then(()=>Ot())}else Ot()}},t(e,t={}){let n=`${he.locale}:${e}`,r=wt.get(n);if(r===void 0){let i=o=>e.split(".").reduce((s,a)=>s?.[a],he.locales[o]||{});r=i(he.locale),r==null&&_.i18n.fallbackLocale&&_.i18n.fallbackLocale!==he.locale&&(r=i(_.i18n.fallbackLocale)),wt.set(n,r??null)}if(r==null)return e;if(typeof r=="string"&&r.includes("|")&&t.count!=null){let i=r.split("|").map(o=>o.trim());r=Number(t.count)===1?i[0]:i[1]||i[0]}return typeof r=="string"&&(r=r.replace(/\{(\w+)\}/g,(i,o)=>t[o]!=null?t[o]:"")),r}};Nt=new Proxy(he,{get(e,t){if(typeof t!="string"||t==="locale"||t==="locales"||t==="t")return e[t];if(t==="setLocale")return s=>{e.locale=s};let n=e.locale,i=e.locales[n]?.[t];if(i!=null&&typeof i=="object"&&!Array.isArray(i))return nn(t);if(i!=null)return i;let o=_.i18n.fallbackLocale;if(o&&o!==n){let a=e.locales[o]?.[t];if(a!=null&&typeof a=="object"&&!Array.isArray(a))return nn(t);if(a!=null)return a}}})});ge();st();ge();st();ge();st();var Et=new Map;function $i(e){return e===void 0&&(e=typeof window<"u"&&window.location?window.location.hostname:""),e===""||e==="localhost"||e==="127.0.0.1"||e==="::1"||e==="0.0.0.0"||e.endsWith(".localhost")}function Te(e,t){!_.devtools||typeof window>"u"||window.dispatchEvent(new CustomEvent("nojs:devtools",{detail:{type:e,data:t,timestamp:Date.now()}}))}function an(e,t){if(!e||!e.__isProxy)return null;let n=e.__raw;if(t||(t=new WeakSet),n&&t.has(n))return"[Circular]";n&&t.add(n);let r={};for(let i of Object.keys(n)){if(i.startsWith("__"))continue;let o=n[i];if(o&&typeof o=="object"&&o.__isProxy)r[i]=an(o,t);else try{JSON.stringify(o),r[i]=o}catch{r[i]=String(o)}}return r}function wr(e){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(e):e}function Sr(e){if(!e||!e.tagName)return null;let t=e.tagName.toLowerCase(),n=e.id?`#${wr(e.id)}`:"",r=e.className&&typeof e.className=="string"?e.className.trim().split(/\s+/).filter(Boolean).map(i=>"."+wr(i)).join(""):"";return t+n+r}function Ar(e){let t=document.querySelector(e);if(!t)return{error:"Element not found",selector:e};let n=t.__ctx;return{selector:e,tag:Sr(t),hasContext:!!n,contextId:n?.__raw?.__devtoolsId??null,data:n?an(n):null,directives:[...t.attributes].filter(r=>!["class","id","style"].includes(r.name)).map(r=>({name:r.name,value:r.value}))}}function xr(e){let t=se[e];return t?{name:e,contextId:t.__raw?.__devtoolsId??null,data:an(t)}:{error:"Store not found",name:e}}function Cr(e){let t=e?document.querySelector(e):document.body;if(!t)return{error:"Root not found",selector:e};function n(r){let i=r.__ctx,o={tag:Sr(r),contextId:i?.__raw?.__devtoolsId??null,children:[]};for(let s of r.children)s.tagName==="TEMPLATE"||s.tagName==="SCRIPT"||(s.__ctx||s.__declared)&&o.children.push(n(s));return o}return n(t)}function Tr(e,t,n){let r=Et.get(e);return r?(r[t]=n,{ok:!0,id:e,key:t}):{error:"Context not found",id:e}}function Lr(e,t,n){let r=se[e];return r?(r[t]=n,{ok:!0,name:e,key:t}):{error:"Store not found",name:e}}function Or(){let e=0;for(let[,t]of Et)t.__listeners&&(e+=t.__listeners.size);return{contexts:Et.size,stores:Object.keys(se).length,listeners:e,refs:Object.keys(it).length,hasRouter:!!me,locale:he.locale}}var at=null,on=null,vt=null;function vr(){if(!at||!on)return;let e=on.getBoundingClientRect();Object.assign(at.style,{top:e.top+"px",left:e.left+"px",width:e.width+"px",height:e.height+"px"})}function Nr(e){cn();let t=document.querySelector(e);t&&(on=t,at=document.createElement("div"),at.id="__nojs_devtools_highlight__",Object.assign(at.style,{position:"fixed",background:"rgba(66, 133, 244, 0.25)",border:"2px solid rgba(66, 133, 244, 0.8)",pointerEvents:"none",zIndex:"2147483647",borderRadius:"3px"}),document.body.appendChild(at),vr(),vt=()=>vr(),window.addEventListener("scroll",vt,!0),window.addEventListener("resize",vt))}function cn(){vt&&(window.removeEventListener("scroll",vt,!0),window.removeEventListener("resize",vt),vt=null),at&&(at.remove(),at=null),on=null}function Er(e){let{command:t,args:n={}}=e.detail||{},r;switch(t){case"inspect:element":r=Ar(n.selector);break;case"inspect:store":r=xr(n.name);break;case"inspect:tree":r=Cr(n.selector);break;case"mutate:context":r=Tr(n.id,n.key,n.value);break;case"mutate:store":r=Lr(n.name,n.key,n.value);break;case"get:config":r={..._},r.csrf&&(r.csrf={...r.csrf,token:"[REDACTED]"}),r.headers&&(r.headers="[REDACTED]");break;case"get:routes":r=me?me.routes||[]:[];break;case"get:stats":r=Or();break;case"highlight:element":Nr(n.selector),r={ok:!0};break;case"unhighlight":cn(),r={ok:!0};break;default:r={error:"Unknown command",command:t}}window.dispatchEvent(new CustomEvent("nojs:devtools:response",{detail:{command:t,result:r,timestamp:Date.now()}}))}var sn=null;function Pr(){cn(),sn&&sn()}function Ir(e){if(!(!_.devtools||typeof window>"u")){if(!$i()){console.warn("[No.JS] devtools: true is ignored outside local environments. Remove devtools: true before deploying to production.");return}window.addEventListener("nojs:devtools:cmd",Er),sn=()=>{window.removeEventListener("nojs:devtools:cmd",Er),delete window.__NOJS_DEVTOOLS__,sn=null},window.__NOJS_DEVTOOLS__={get stores(){return Object.fromEntries(Object.entries(se).map(([t,n])=>[t,an(n)]))},get config(){let t={..._};return t.headers&&(t.headers={...t.headers}),t.router&&(t.router={...t.router}),t.cache&&(t.cache={...t.cache}),t.csrf&&(t.csrf={...t.csrf}),t.i18n&&(t.i18n={...t.i18n}),t},get refs(){return{...it}},router:me,version:e.version,get plugins(){return new Map(Je)},get globals(){return{...De}},inspect:t=>Ar(t),inspectStore:t=>xr(t),inspectTree:t=>Cr(t),stats:()=>Or(),mutate:(t,n,r)=>Tr(t,n,r),mutateStore:(t,n,r)=>Lr(t,n,r),highlight:t=>Nr(t),unhighlight:()=>cn(),on:(t,n)=>{let r=i=>{(!t||i.detail.type===t)&&n(i.detail)};return window.addEventListener("nojs:devtools",r),()=>window.removeEventListener("nojs:devtools",r)}},console.log("[No.JS DevTools] enabled \u2014 access via window.__NOJS_DEVTOOLS__")}}var $r=new Set(["__proto__","constructor","prototype"]),St=0,ft=new Set,ki=0,ln=0;function Fn(){St++,Te("batch:start",{depth:St})}function Hn(){if(St--,St===0&&ft.size>0){Te("batch:end",{depth:0,queueSize:ft.size});let e=0;for(;ft.size>0;){if(++e>100){w("batch drain exceeded 100 rounds \u2014 possible update cycle; aborting drain"),ft=new Set;break}let t=ft;ft=new Set,St++;try{t.forEach(n=>{if(!(n._el&&!n._el.isConnected)){ft.delete(n);try{n()}catch(r){w("batched listener threw; continuing with remaining listeners:",r)}}})}finally{St--}}}}var Xe=Symbol("no.js");function Mn(e,t){let n=e.listeners;if(!n||n.size===0)return;let r=St===0;r&&Fn();for(let i of n){if(i._el&&!i._el.isConnected){n.delete(i);continue}t!==void 0&&i._keys&&!i._keys.has(t)||ft.add(i)}r&&Hn()}var Ri={get(e,t){if(typeof t!="string")return e[t];let n=t.charCodeAt(0);if(n!==36&&n!==95){if(t in e)return e[t];let o=e[Xe].parent;return o&&o.__isProxy?o[t]:void 0}if(n===95){if(t==="__isProxy")return!0;if(t==="__raw")return e;if(t==="__listeners"){let s=e[Xe];return s.listeners||(s.listeners=new Set)}if(t in e)return e[t];let o=e[Xe].parent;return o&&o.__isProxy?o[t]:void 0}switch(t){case"$watch":{let o=e[Xe];return o.watchFn||(o.watchFn=s=>(fe&&(s._el=fe),(o.listeners||(o.listeners=new Set)).add(s),()=>{o.listeners&&o.listeners.delete(s)}))}case"$notify":{let o=e[Xe];return o.notifyFn||(o.notifyFn=s=>Mn(o,typeof s=="string"?s:void 0))}case"$set":{let o=e[Xe];return o.setFn||(o.setFn=(s,a)=>{let l=s.split(".");if(!l.some(u=>$r.has(u)))if(l.length===1)o.proxy[s]=a;else{let u=o.proxy;for(let b=0;b=r&&e.delete(e.keys().next().value),e.set(t,n)},get size(){return e.size}}}var Rr=Fr(),Bn=Fr(),Di=new Set(["true","false","null","undefined","typeof","in","instanceof"]),ji=new Set(["__proto__","constructor","prototype"]),Dr=["===","!==","...","??","?.","==","!=",">=","<=","&&","||","+=","-=","*=","/=","%=","++","--","=>"],Mi=new Set(["+","-","*","/","%",">","<","!","=","|"]),Fi=new Set(["(",")","[","]","{","}",".",",",":",";","?"]);function Kt(e){if(typeof e!="string")return[];let t=[],n=e.length,r=0;for(;r0;){if(e[r]==="{")d++;else if(e[r]==="}"){if(d--,d===0)break}else if(e[r]==="'"||e[r]==='"'||e[r]==="`"){let y=e[r];for(p+=y,r++;r="0"&&i<="9"||i==="."&&r+1="0"&&e[r+1]<="9"){let s=r,a="";for(;r="0"&&e[r]<="9"||e[r]===".");)a+=e[r++];t.push({type:"Number",value:a,pos:s});continue}if(i>="a"&&i<="z"||i>="A"&&i<="Z"||i==="_"||i==="$"){let s=r,a="";for(;r="a"&&l<="z"||l>="A"&&l<="Z"||l>="0"&&l<="9"||l==="_"||l==="$")a+=l,r++;else break}Ri.has(a)?t.push({type:"Forbidden",value:a,pos:s}):ki.has(a)?t.push({type:"Keyword",value:a,pos:s}):t.push({type:"Ident",value:a,pos:s});continue}let o=!1;for(let s=0;s=","<=",">","<"];if(f.type==="Op"&&h.indexOf(f.value)!==-1||f.type==="Keyword"&&(f.value==="in"||f.value==="instanceof")){let N=r().value,P=v();c={type:"BinaryExpr",op:N,left:c,right:P}}return c}function v(){let c=I();for(;n()&&n().type==="Op"&&(n().value==="+"||n().value==="-");){let f=r().value,h=I();c={type:"BinaryExpr",op:f,left:c,right:h}}return c}function I(){let c=T();for(;n()&&n().type==="Op"&&(n().value==="*"||n().value==="/"||n().value==="%");){let f=r().value,h=T();c={type:"BinaryExpr",op:f,left:c,right:h}}return c}function T(){let c=n();return c?c.type==="Keyword"&&c.value==="typeof"?(r(),{type:"UnaryExpr",op:"typeof",argument:T()}):c.type==="Op"&&(c.value==="!"||c.value==="-"||c.value==="+")?(r(),{type:"UnaryExpr",op:c.value,argument:T()}):c.type==="Op"&&(c.value==="++"||c.value==="--")?(r(),{type:"UnaryExpr",op:c.value,argument:T(),prefix:!0}):$():{type:"Literal",value:void 0}}function $(){let c=J(),f=n();return f&&f.type==="Op"&&(f.value==="++"||f.value==="--")&&(r(),c={type:"PostfixExpr",op:f.value,argument:c}),c}function J(){let c=A();for(;;){let f=n();if(!f)break;if(f.type==="Punc"&&f.value==="."){r();let h=n();if(h&&(h.type==="Ident"||h.type==="Keyword"))r(),c={type:"MemberExpr",object:c,property:{type:"Identifier",name:h.value},computed:!1};else if(h&&h.type==="Forbidden")r(),c={type:"Forbidden"};else break;continue}if(f.type==="Punc"&&f.value==="?."){r();let h=n();if(h&&h.type==="Punc"&&h.value==="("){r();let N=me();o("Punc",")"),c={type:"OptionalCallExpr",callee:c,args:N}}else if(h&&(h.type==="Ident"||h.type==="Keyword"))r(),c={type:"OptionalMemberExpr",object:c,property:{type:"Identifier",name:h.value},computed:!1};else if(h&&h.type==="Punc"&&h.value==="["){r();let N=s();o("Punc","]"),c={type:"OptionalMemberExpr",object:c,property:N,computed:!0}}else break;continue}if(f.type==="Punc"&&f.value==="["){r();let h=s();o("Punc","]"),c={type:"MemberExpr",object:c,property:h,computed:!0};continue}if(f.type==="Punc"&&f.value==="("){r();let h=me();o("Punc",")"),c={type:"CallExpr",callee:c,args:h};continue}break}return c}function me(){let c=[];if(i("Punc",")"))return c;for(c.push(x());i("Punc",",")&&(r(),!i("Punc",")"));)c.push(x());return c}function x(){return i("Punc","...")?(r(),{type:"SpreadElement",argument:s()}):s()}function m(){let c=t;if(i("Punc",")")){let f=e[t+1];return f&&f.type==="Op"&&f.value==="=>"?(t=c,!0):(t=c,!1)}for(;t"?(t=c,!0):(t=c,!1)}return t=c,!1}if(f.type==="Punc"&&f.value==="..."){if(r(),i("Ident")&&r(),i("Punc",")")){let h=e[t+1];if(h&&h.type==="Op"&&h.value==="=>")return t=c,!0}return t=c,!1}return t=c,!1}return t=c,!1}function b(){let c=[];if(i("Punc",")"))return c;for(i("Punc","...")?(r(),i("Ident")&&c.push("..."+r().value)):i("Ident")&&c.push(r().value);i("Punc",",")&&(r(),!i("Punc",")"));)i("Punc","...")?(r(),i("Ident")&&c.push("..."+r().value)):i("Ident")&&c.push(r().value);return c}function A(){let c=n();if(!c)return{type:"Literal",value:void 0};if(c.type==="Forbidden")return r(),{type:"Forbidden"};if(c.type==="Number")return r(),{type:"Literal",value:Number(c.value)};if(c.type==="String")return r(),{type:"Literal",value:c.value};if(c.type==="Template")return r(),{type:"TemplateLiteral",parts:c.parts,expressions:c.exprs.map(function(f){return zn(f)})};if(c.type==="Keyword"){if(c.value==="true")return r(),{type:"Literal",value:!0};if(c.value==="false")return r(),{type:"Literal",value:!1};if(c.value==="null")return r(),{type:"Literal",value:null};if(c.value==="undefined")return r(),{type:"Literal",value:void 0}}if(c.type==="Punc"&&c.value==="["){r();let f=[];for(;!i("Punc","]")&&t");let N=s();return{type:"ArrowFunction",params:h,body:N}}let f=s();return o("Punc",")"),f}if(c.type==="Ident"){if(r(),i("Op","=>")){r();let f=s();return{type:"ArrowFunction",params:[c.value],body:f}}return{type:"Identifier",name:c.value}}return c.type==="Op"&&(c.value==="="||c.value==="+="||c.value==="-="||c.value==="*="||c.value==="/="||c.value==="%=")?(r(),{type:"Literal",value:void 0}):c.type==="Punc"&&c.value==="..."?(r(),{type:"SpreadElement",argument:s()}):(r(),{type:"Literal",value:void 0})}function _(){r();let c=[];for(;!i("Punc","}")&&tObject.prototype.hasOwnProperty.call(e,t)}),qn={Array,Object:Mi,String,Number,Boolean,Math,Date,RegExp,Map,Set,JSON,parseInt,parseFloat,isNaN,isFinite,Infinity:1/0,NaN:NaN,undefined:void 0,Error,Symbol,console},un=Object.prototype.hasOwnProperty;function Un(e,t){let n=e;for(;n&&n!==Object.prototype;){if(un.call(n,t))return!0;n=Object.getPrototypeOf(n)}return!1}function fn(e){return un.call(qn,e)}var Fi=new Set(["fetch","XMLHttpRequest","localStorage","sessionStorage","WebSocket","indexedDB","eval","Function","importScripts","open","postMessage"]),It={},Dr=new Set(["cookie","domain","write","writeln","execCommand"]),$t=typeof globalThis<"u"&&typeof globalThis.window<"u"?new Proxy(globalThis.window,{get(e,t,n){if(!(typeof t=="string"&&Fi.has(t)))return typeof t=="string"&&t in It?It[t]:Reflect.get(e,t,n)},set(){return!0}}):void 0,vt=typeof globalThis<"u"&&typeof globalThis.document<"u"?new Proxy(globalThis.document,{get(e,t,n){if(!(typeof t=="string"&&Dr.has(t)))return t==="defaultView"?$t:t==="location"?kt:Reflect.get(e,t,n)},set(e,t,n){return typeof t=="string"&&Dr.has(t)||t==="location"||(e[t]=n),!0}}):void 0,Hi=["href","pathname","search","hash","origin","hostname","port","protocol","host"],ut=()=>{},kt=typeof globalThis<"u"&&typeof globalThis.location<"u"?(()=>{let e={};for(let t of Hi)Object.defineProperty(e,t,{get(){return globalThis.location[t]},set(){},enumerable:!0,configurable:!1});return e.assign=ut,e.replace=ut,e.reload=ut,e.toString=()=>globalThis.location.href,Object.freeze(e)})():void 0,Bi=["length","state","scrollRestoration"],zt=typeof globalThis<"u"&&typeof globalThis.history<"u"?(()=>{let e={};for(let t of Bi)Object.defineProperty(e,t,{get(){return globalThis.history[t]},enumerable:!0,configurable:!1});return e.pushState=ut,e.replaceState=ut,e.back=ut,e.forward=ut,e.go=ut,Object.freeze(e)})():void 0,Ui=new Set(["sendBeacon","credentials"]),qt=typeof globalThis<"u"&&typeof globalThis.navigator<"u"?new Proxy(globalThis.navigator,{get(e,t,n){if(!(typeof t=="string"&&Ui.has(t)))return Reflect.get(e,t,n)},set(){return!0}}):void 0;kt&&(It.location=kt);vt&&(It.document=vt);zt&&(It.history=zt);qt&&(It.navigator=qt);var Pt=new Set([$t,vt,kt,qt,zt].filter(Boolean)),dn=new Set(["window","document","console","location","history","navigator","screen","performance","crypto","setTimeout","clearTimeout","setInterval","clearInterval","requestAnimationFrame","cancelAnimationFrame","alert","confirm","prompt","CustomEvent","Event","URL","URLSearchParams","FormData","FileReader","Blob","Promise"]),Wn=new Set(["setTimeout","setInterval","requestAnimationFrame"]);function zi(e){let t=typeof globalThis<"u"?globalThis[e]:void 0;if(t)return e==="requestAnimationFrame"?function(r){if(typeof r=="function")return t.call(globalThis,r)}:function(r,i,...o){if(typeof r=="function")return t.call(globalThis,r,i,...o)}}var Jn={};for(let e of Wn)Jn[e]=zi(e);function ft(e){if(!(e===Function||e===eval)){if(e instanceof Document||e===globalThis.document)return vt;if(e===globalThis.window||e===globalThis)return $t;if(e&&typeof e=="object"){let t;try{t=e.nodeType}catch{t=void 0}if(t===9)return vt;let n;try{n=e.window}catch{n=void 0}if(n===e)return $t}return e}}function jr(e,t){let n=[];for(let r=0;r":return n>r;case"<":return n=":return n>=r;case"<=":return n<=r;case"in":return r&&typeof r=="object"?n in r:void 0;case"instanceof":return n instanceof r;case"&":return n&r;case"|":return n|r;case"^":return n^r;case"<<":return n<>":return n>>r;case">>>":return n>>>r;default:return}}case"UnaryExpr":{if(e.op==="typeof")return e.argument&&e.argument.type==="Identifier"&&!Un(t,e.argument.name)&&!fn(e.argument.name)&&!dn.has(e.argument.name)?"undefined":typeof Z(e.argument,t);if(e.op==="++"||e.op==="--"){let r=Z(e.argument,t),i=e.op==="++"?r+1:r-1;return e.prefix?i:r}let n=Z(e.argument,t);switch(e.op){case"!":return!n;case"-":return-n;case"+":return+n;case"~":return~n;case"void":return;default:return}}case"ConditionalExpr":return Z(e.test,t)?Z(e.consequent,t):Z(e.alternate,t);case"MemberExpr":case"OptionalMemberExpr":{let n=Z(e.object,t);if(n==null)return;let r=e.computed?Z(e.property,t):e.property.name||e.property.value;if(je[r]||Nt.has(r)&&!Pt.has(n))return;let i=n[r];return ft(i)}case"CallExpr":case"OptionalCallExpr":{if(e.callee.type==="MemberExpr"||e.callee.type==="OptionalMemberExpr"){let i=Z(e.callee.object,t);if(i==null)return e.type==="OptionalCallExpr"||e.callee.type==="OptionalMemberExpr",void 0;let o=e.callee.computed?Z(e.callee.property,t):e.callee.property.name;if(je[o]||Nt.has(o)&&!Pt.has(i))return;let s=i[o];if(typeof s!="function")return;let a=s.apply(i,jr(e.args,t));return ft(a)}let n=Z(e.callee,t);if(n==null&&e.type==="OptionalCallExpr"||typeof n!="function")return;let r=n.apply(void 0,jr(e.args,t));return ft(r)}case"ArrayExpr":{let n=[];for(let r=0;r{};function ce(e,t){return function(n,r){try{return t(n,r)}catch(i){w("_evalNode error:",e,i?.message||i);return}}}var Hr=[];function Ji(e){let t=e.length;if(t===0)return()=>Hr;let n=!1,r=new Array(t),i=new Array(t);for(let o=0;o{let a=[];for(let l=0;l{let a=new Array(t);for(let l=0;lt}case"Identifier":{let t=e.name;return(n,r)=>Wi(t,n,r)}case"Forbidden":return Ot;case"BinaryExpr":{let t=e.op,n=fe(e.left);if(t==="&&"){let i=fe(e.right);return(o,s)=>{let a=n(o,s);return a&&i(o,s)}}if(t==="||"){let i=fe(e.right);return(o,s)=>{let a=n(o,s);return a||i(o,s)}}if(t==="??"){let i=fe(e.right);return(o,s)=>{let a=n(o,s);return a??i(o,s)}}let r=fe(e.right);switch(t){case"+":return ce(e.type,(i,o)=>n(i,o)+r(i,o));case"-":return ce(e.type,(i,o)=>n(i,o)-r(i,o));case"*":return ce(e.type,(i,o)=>n(i,o)*r(i,o));case"/":return ce(e.type,(i,o)=>n(i,o)/r(i,o));case"%":return ce(e.type,(i,o)=>n(i,o)%r(i,o));case"**":return ce(e.type,(i,o)=>n(i,o)**r(i,o));case"===":return(i,o)=>n(i,o)===r(i,o);case"!==":return(i,o)=>n(i,o)!==r(i,o);case"==":return ce(e.type,(i,o)=>n(i,o)==r(i,o));case"!=":return ce(e.type,(i,o)=>n(i,o)!=r(i,o));case">":return ce(e.type,(i,o)=>n(i,o)>r(i,o));case"<":return ce(e.type,(i,o)=>n(i,o)=":return ce(e.type,(i,o)=>n(i,o)>=r(i,o));case"<=":return ce(e.type,(i,o)=>n(i,o)<=r(i,o));case"in":return ce(e.type,(i,o)=>{let s=n(i,o),a=r(i,o);return a&&typeof a=="object"?s in a:void 0});case"instanceof":return ce(e.type,(i,o)=>n(i,o)instanceof r(i,o));case"&":return ce(e.type,(i,o)=>n(i,o)&r(i,o));case"|":return ce(e.type,(i,o)=>n(i,o)|r(i,o));case"^":return ce(e.type,(i,o)=>n(i,o)^r(i,o));case"<<":return ce(e.type,(i,o)=>n(i,o)<>":return ce(e.type,(i,o)=>n(i,o)>>r(i,o));case">>>":return ce(e.type,(i,o)=>n(i,o)>>>r(i,o));default:return Ot}}case"UnaryExpr":{let t=e.op;if(t==="typeof"){let r=fe(e.argument);return(i,o)=>typeof r(i,o)}if(t==="++"||t==="--"){let r=fe(e.argument),i=t==="++",o=!!e.prefix;return ce(e.type,(s,a)=>{let l=r(s,a),u=i?l+1:l-1;return o?u:l})}let n=fe(e.argument);switch(t){case"!":return(r,i)=>!n(r,i);case"-":return ce(e.type,(r,i)=>-n(r,i));case"+":return ce(e.type,(r,i)=>+n(r,i));case"~":return ce(e.type,(r,i)=>~n(r,i));case"void":return(r,i)=>{n(r,i)};default:return(r,i)=>{n(r,i)}}}case"ConditionalExpr":{let t=fe(e.test),n=fe(e.consequent),r=fe(e.alternate);return(i,o)=>t(i,o)?n(i,o):r(i,o)}case"MemberExpr":case"OptionalMemberExpr":{let t=fe(e.object);if(!e.computed){let r=e.property.name||e.property.value;if(je[r])return Ot;let i=Nt.has(r);return ce(e.type,(o,s)=>{let a=t(o,s);if(a!=null&&!(i&&!Pt.has(a)))return ft(a[r])})}let n=fe(e.property);return ce(e.type,(r,i)=>{let o=t(r,i);if(o==null)return;let s=n(r,i);if(!je[s]&&!(Nt.has(s)&&!Pt.has(o)))return ft(o[s])})}case"CallExpr":case"OptionalCallExpr":{let t=Ji(e.args),n=e.callee;if(n.type==="MemberExpr"||n.type==="OptionalMemberExpr"){let o=fe(n.object);if(!n.computed){let a=n.property.name;if(je[a])return Ot;let l=Nt.has(a);return ce(e.type,(u,d)=>{let p=o(u,d);if(p==null||l&&!Pt.has(p))return;let y=p[a];if(typeof y=="function")return ft(y.apply(p,t(u,d)))})}let s=fe(n.property);return ce(e.type,(a,l)=>{let u=o(a,l);if(u==null)return;let d=s(a,l);if(je[d]||Nt.has(d)&&!Pt.has(u))return;let p=u[d];if(typeof p=="function")return ft(p.apply(u,t(a,l)))})}let r=fe(n),i=e.type==="OptionalCallExpr";return ce(e.type,(o,s)=>{let a=r(o,s);if(!(a==null&&i)&&typeof a=="function")return ft(a.apply(void 0,t(o,s)))})}case"ArrayExpr":{let t=e.elements.length,n=new Array(t),r=new Array(t);for(let i=0;i{let s=[];for(let a=0;an.spread?{spread:!0,valueFn:fe(n.value)}:n.computed?{computed:!0,keyFn:fe(n.key),valueFn:fe(n.value)}:{key:n.key,valueFn:fe(n.value),forbidden:!!je[n.key]});return ce(e.type,(n,r)=>{let i={};for(let o=0;ofunction(...o){let s=Object.create(i||null);for(let a=0;a{let o=t[0];for(let s=0;s0&&n.push(zn(o)),r=i+1}return Hn.set(e,n),n}function Bn(e,t,n){if(e.type==="Identifier")n[e.name]=t;else if(e.type==="MemberExpr"||e.type==="OptionalMemberExpr"){let r=Z(e.object,n);if(r==null)return;let i=e.computed?Z(e.property,n):e.property.name||e.property.value;if(je[i])return;r[i]=t}}function Xi(e,t){if(e)switch(e.type){case"AssignExpr":{let n=Z(e.right,t),r;if(e.op==="=")r=n;else{let i=Z(e.left,t);switch(e.op){case"+=":r=i+n;break;case"-=":r=i-n;break;case"*=":r=i*n;break;case"/=":r=i/n;break;case"%=":r=i%n;break;default:r=n}}return Bn(e.left,r,t),r}case"PostfixExpr":{let n=Z(e.argument,t),r=e.op==="++"?n+1:n-1;return Bn(e.argument,r,t),n}case"UnaryExpr":{if(e.op==="++"||e.op==="--"){let n=Z(e.argument,t),r=e.op==="++"?n+1:n-1;return Bn(e.argument,r,t),r}return Z(e,t)}default:{if(e.type==="CallExpr"&&e.callee.type==="Identifier"){let n=e.callee.name;if(!Un(t,n)&&!fn(n)&&!dn.has(n))throw new ReferenceError(n+" is not defined")}return Z(e,t)}}}function Br(e){if(!e.includes("|"))return[e.trim()];let t=[],n="",r=0,i=!1,o="";for(let s=0;s=0&&e[u]==="\\";u--)l++;l%2===0&&(i=!1)}continue}if(a==="'"||a==='"'||a==="`"){i=!0,o=a,n+=a;continue}if(a==="("||a==="["||a==="{"){r++,n+=a;continue}if(a===")"||a==="]"||a==="}"){r--,n+=a;continue}if(a==="|"&&r===0&&e[s+1]!=="|"&&e[s-1]!=="|"){t.push(n.trim()),n="";continue}n+=a}return t.push(n.trim()),t}function Yi(e){let t=[],n="",r=!1,i="";for(let o of e){if(r){if(o===i){r=!1;continue}n+=o;continue}if(o==="'"||o==='"'){r=!0,i=o;continue}if(o===","){t.push(n.trim()),n="";continue}n+=o}return n.trim()&&t.push(n.trim()),t.map(o=>{let s=Number(o);return isNaN(s)?o:s})}var cn=new Map,Ur=500;function Zi(e){let t=cn.get(e);if(t!==void 0)return t;let n=Qi(e);return cn.size>=Ur&&cn.clear(),cn.set(e,n),n}function Qi(e){if(typeof e!="string"||e.trim()==="")return null;let t;try{let r=Br(e);if(r.length>1)return null;t=Wt(r[0])}catch{return null}if(!t||t.length===0)return null;let n=new Set;for(let r=0;r")||i.type==="Punc"&&i.value==="(")return null;if(i.type==="Ident"){let o=t[r-1];if(o&&o.type==="Punc"&&(o.value==="."||o.value==="?."))continue;if(i.value.charCodeAt(0)===36&&i.value!=="$store"&&i.value!=="$route"&&i.value!=="$i18n")return null;n.add(i.value)}}return n.size>0?n:null}hr(Zi);var eo=new Set(["$store","$route","$i18n"]),to=new Set(["$event","$el","$error"]),ln=new Map;function no(e){let t=ln.get(e);if(t!==void 0)return t;t={roots:null,hasGlobalRoot:!1};let n=new Set,r=!0;try{let i=Wt(e);if(!i||i.length===0)r=!1;else for(let o=0;o=Ur&&ln.clear(),ln.set(e,t),t}var ro={roots:null,hasGlobalRoot:!1};function R(e,t){if(!(e==null||e===""))try{let n=kr.get(e);if(n===void 0&&(n=Vi(e),kr.set(e,n)),!t||!t.__isProxy){w("Expression error:",e,"requires a reactive context");return}let r=n.fn(t,null),i=n.filters;for(let o=0;o{if(!je[r])return n?.[r]},t)}function Ge(e,t){return e.replace(/\{([^}]+)\}/g,(n,r)=>{let i=R(r.trim(),t);return i==null?"":encodeURIComponent(String(i))})}_e();_e();var io=200,zr=5e3,Kn=0,oo=1,Jt=new WeakMap;function qr(e,t,n){let r;return Promise.race([e.finally(()=>clearTimeout(r)),new Promise((i,o)=>{r=setTimeout(()=>o(new Error(n)),t)})])}function Wr(e){return At.has(e.toLowerCase())||/^x-(auth|api)-/i.test(e)}function Jr(e){try{let t=new URL(e,"http://localhost");for(let n of[...t.searchParams.keys()])/token|key|secret|auth|password|credential/i.test(n)&&t.searchParams.set(n,"[REDACTED]");return e.startsWith("http")?t.href:t.pathname+t.search}catch{return e}}function so(e){let t=new Headers(e.headers);for(let i of mr)t.delete(i);let n=Jr(e.url),r=Object.freeze({status:e.status,ok:e.ok,statusText:e.statusText,headers:t,url:n});return Jt.set(r,e),r}function pn(e,t){if(e.startsWith("http://")||e.startsWith("https://")||e.startsWith("//"))return e;let n=t;for(;n;){let r=n.getAttribute?.("base");if(r)return r.replace(/\/+$/,"")+"/"+e.replace(/^\/+/,"");n=n.parentElement}return g.baseApiUrl?g.baseApiUrl.replace(/\/+$/,"")+"/"+e.replace(/^\/+/,""):e}async function mn(e,t="GET",n=null,r={},i=null,o=null,s=void 0,a=void 0,l=null){let u=pn(e,i);g.credentials!=="omit"&&u.startsWith("http://")&&w("Credentials sent over insecure HTTP:",u);let d=t.toUpperCase(),p={method:d,headers:{...g.headers||{},...r},credentials:g.credentials};if(n&&d!=="GET")if(typeof n=="string")try{JSON.parse(n),p.headers["Content-Type"]="application/json",p.body=n}catch{p.body=n}else n instanceof FormData?p.body=n:(p.headers["Content-Type"]="application/json",p.body=JSON.stringify(n));if(g.csrf&&d!=="GET"&&d!=="QUERY"){let $=!1;if(typeof window<"u")try{$=new URL(u.replace(/\\/g,"/"),window.location.href).origin===window.location.origin}catch{$=!1}$&&(p.headers[g.csrf.header||"X-CSRF-Token"]=g.csrf.token||"")}let y=Je.request.length>0,v={};if(y)for(let $ of Object.keys(p.headers))Wr($)&&(v[$]=p.headers[$],delete p.headers[$]);Kn++;try{if(Kn<=oo)for(let $=0;${w(`Request interceptor [${$}] error:`,A.message)});if(b&&b[Bt])throw ee("Request cancelled by interceptor",$),new DOMException("Request cancelled by interceptor","AbortError");if(b&&b[Ct]!==void 0)return ee("Request short-circuited by interceptor",$),b[Ct];if(b&&typeof b=="object"&&!b[Bt]&&b[Ct]===void 0&&b.headers&&typeof b.headers=="object"){let A={...p.headers};for(let[_,E]of Object.entries(b.headers))Wr(_)?x&&(v[_]=E):A[_]=E;p.headers=A}}}finally{Kn--}y&&Object.assign(p.headers,v);let I=s!==void 0?s:g.retries||0,T;for(let $=0;$<=I;$++){let J=new AbortController,me=null,x=null;try{if(me=setTimeout(()=>J.abort(),g.timeout||1e4),o){if(o.aborted)throw new DOMException("Aborted","AbortError");x=()=>J.abort(),o.addEventListener("abort",x)}p.signal=J.signal;let m=await fetch(u,p),b=m;for(let _=0;_{w(`Response interceptor [${_}] error:`,P.message)});if(N&&N[Ut]!==void 0)return ee("Response replaced by interceptor",_),l&&(l.headers=m.headers),N[Ut];N&&(m=N,Jt.has(N)?b=Jt.get(N):typeof N.text=="function"&&(b=N))}if(Jt.has(m)?m=Jt.get(m):typeof m.text!="function"&&(m=b),!m.ok){let _=await m.json().catch(()=>({})),E=new Error(_.message||`HTTP ${m.status}`);throw E.status=m.status,E.body=_,E}l&&(l.headers=m.headers);let A=await m.text();try{return JSON.parse(A)}catch{return A}}catch(m){if(m.name==="AbortError")throw m;T=m,$setTimeout(b,a!==void 0?a:g.retryDelay||1e3))}finally{me!==null&&clearTimeout(me),o&&x&&o.removeEventListener("abort",x)}}throw T}function Kr(e,t){if(t==="none")return null;if(t==="memory"){let r=Ye.get(e);return r&&Date.now()-r.time<(g.cache.ttl||3e5)?(Ye.delete(e),Ye.set(e,r),r.data):null}let n=t==="local"?localStorage:t==="session"?sessionStorage:null;if(!n)return null;try{let r=n.getItem("nojs_cache_"+e);if(!r)return null;let i=JSON.parse(r);if(Date.now()-i.time<(g.cache.ttl||3e5))return i.data;n.removeItem("nojs_cache_"+e)}catch{}return null}function Vr(e,t,n){if(n==="none")return;let r={data:t,time:Date.now()};if(n==="memory"){Ye.has(e)?Ye.delete(e):Ye.size>=io&&Ye.delete(Ye.keys().next().value),Ye.set(e,r);return}let i=n==="local"?localStorage:n==="session"?sessionStorage:null;if(i)try{i.setItem("nojs_cache_"+e,JSON.stringify(r))}catch{}}var ao=200,Ze=new Map;function co(){let e=g.templates&&g.templates.maxSize;return typeof e=="number"&&e>0?e:ao}function lo(e){if(!Ze.has(e))return;let t=Ze.get(e);return Ze.delete(e),Ze.set(e,t),t}function uo(e,t){let n=co();Ze.has(e)?Ze.delete(e):Ze.size>=n&&Ze.delete(Ze.keys().next().value),Ze.set(e,t)}var Vn=new Map,Xr=new DOMParser;function B(e){let t=e;for(;t;){if(t.__ctx)return t.__ctx;t=t.parentElement}return te()}function Ue(e){let t=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;t.nextNode();)t.currentNode.__declared=!1}function Se(e){if(!e)return null;let t=e.startsWith("#")?e.slice(1):e,n=document.getElementById(t);return n&&n.content?n.content.cloneNode(!0):null}function Gr(e){let n=Xr.parseFromString(e,"image/svg+xml").documentElement;if(n.querySelector("parsererror")||n.nodeName!=="svg"||n.getElementsByTagNameNS("http://www.mozilla.org/newlayout/xml/parsererror.xml","parsererror").length)return"";function r(i){for(let o of[...i.attributes]){let s=o.name.toLowerCase();if(s.startsWith("on")){i.removeAttribute(o.name);continue}if(s==="href"||s==="xlink:href"){let a=o.value.toLowerCase().replace(/[\u0000-\u0020]/g,"");/^(javascript|vbscript):/.test(a)&&i.removeAttribute(o.name)}}}for(let i of[...n.querySelectorAll("script")])i.remove();r(n);for(let i of n.querySelectorAll("*"))r(i);return new XMLSerializer().serializeToString(n)}function fo(e){let t=atob(e);if(typeof TextDecoder=="function"){let n=new Uint8Array(t.length);for(let r=0;r"%"+("00"+n.charCodeAt(0).toString(16)).slice(-2)).join(""))}function po(e){let t;if(typeof TextEncoder=="function"){let n=new TextEncoder().encode(e),r="";for(let i=0;i{let r=await fetch(e);if(!r.ok)return{ok:!1,status:r.status};let i=await r.text();return t&&uo(e,i),{ok:!0,html:i}})(),Vn.set(e,n));try{let r=await n;return r.ok?{html:r.html,hit:!1}:{html:null,status:r.status}}finally{Vn.delete(e)}}async function Zr(e){let t=e||document,n=t.querySelectorAll("template[src]");if(ee("[LRT] called on",t===document?"document":t.nodeName||"fragment","\u2014 found",n.length,"template[src]",[...n].map(i=>i.getAttribute("src"))),!n.length)return;let r=[...n].map(async i=>{if(i.__srcLoaded){ee("[LRT] SKIP (already loaded):",i.getAttribute("src"));return}i.__srcLoaded=!0;let o=i.getAttribute("src"),s=Gn(o,i);Yr(s,o);let a=s.substring(0,s.lastIndexOf("/")+1);try{let l=g.templates.cache!==!1,{html:u,hit:d,status:p}=await Xn(s,l);if(u===null){w("Failed to load template:",o,"HTTP",p),i.__loadFailed=!0;return}if(d&&ee("[LRT] CACHE HIT:",s),i.innerHTML=u,i.content&&(i.content.__srcBase=a),ee("Loaded remote template:",o,"\u2192",s),await Zr(i.content||i),!i.hasAttribute("route")&&i.parentNode){let v=[...i.content.childNodes],I=i.parentNode,T=i.nextSibling;I.removeChild(i);for(let $ of v)$.nodeType===1&&($.__srcBase=$.__srcBase||a),I.insertBefore($,T)}}catch(l){w("Failed to load template:",o,l.message)}});await Promise.all(r)}async function Me(e){let t=e.getAttribute("src");if(e.__srcLoaded){ee("[LTE] SKIP (already loaded):",t);return}ee("[LTE] START fetch:",t,"| route:",e.hasAttribute("route"),"| inDOM:",document.contains(e),"| loading:",e.getAttribute("loading")),e.__srcLoaded=!0;let n=Gn(t,e);Yr(n,t);let r=n.substring(0,n.lastIndexOf("/")+1),i=null,o=e.getAttribute("loading");if(o&&e.parentNode){let s=o.startsWith("#")?o.slice(1):o,a=document.getElementById(s);a&&a.content&&(i=document.createElement("span"),i.style.cssText="display:contents",i.appendChild(a.content.cloneNode(!0)),e.parentNode.insertBefore(i,e))}try{let s=g.templates.cache!==!1,{html:a,hit:l,status:u}=await Xn(n,s);if(a===null){w("Failed to load template:",t,"HTTP",u),e.__loadFailed=!0,i&&i.remove();return}if(l&&ee("[LTE] CACHE HIT:",n),e.innerHTML=a,e.content&&(e.content.__srcBase=r),ee("Loaded remote template:",t,"\u2192",n),!e.hasAttribute("route"))await Zr(e.content||e);else if(s&&e.content){let p=[...e.content.querySelectorAll("template[src]")].map(y=>{let v=y.getAttribute("src"),I=Gn(v,y);return Xn(I,!0).catch(()=>{})});e.__warmup=Promise.all(p)}if(i&&i.remove(),!e.hasAttribute("route")&&e.parentNode){let p=[...e.content.childNodes],y=e.parentNode,v=e.nextSibling;y.removeChild(e);for(let I of p)I.nodeType===1&&(I.__srcBase=I.__srcBase||r),y.insertBefore(I,v)}}catch(s){i&&i.remove(),w("Failed to load template:",t,s.message)}}function Dt(e){(e||document).querySelectorAll("template[include]").forEach(n=>{let r=n.getAttribute("include"),i=document.getElementById(r.startsWith("#")?r.slice(1):r);!i||!i.content||n.replaceWith(i.content.cloneNode(!0))})}async function Qr(e){let t=[...document.querySelectorAll("template[src]")],n=t.filter(i=>!i.__srcLoaded&&i.getAttribute("lazy")==="priority");await Promise.all(n.map(Me));let r=t.filter(i=>{if(i.__srcLoaded)return!1;let o=i.getAttribute("lazy");return o==="ondemand"||o==="priority"?!1:i.hasAttribute("route")?e!=null&&i.getAttribute("route")===e:!0});await Promise.all(r.map(Me))}function ei(){let t=[...document.querySelectorAll("template[src]")].filter(n=>n.__srcLoaded||n.getAttribute("lazy")==="ondemand"?!1:n.hasAttribute("route"));return Promise.all(t.map(Me))}_e();var jt=new Map,Qn=!1,gn=new Set;function H(e,t){if(Qn&&gn.has(e)){w(`Cannot override core directive "${e}".`);return}jt.set(e,{priority:t.priority??50,init:t.init,gated:!!t.gated}),gn.add(e),Et.clear(),Kt++}function ni(){Qn=!0}function ri(e){if(!Qn){w(`_removeCoreDirective("${e}") can only be called after init.`);return}if(!gn.has(e)){w(`_removeCoreDirective: "${e}" is not a registered core directive.`);return}gn.delete(e),jt.delete(e),Et.clear(),Kt++}var ti=Object.freeze([{pattern:"class-*",prefix:"class-"},{pattern:"on:*",prefix:"on:"},{pattern:"style-*",prefix:"style-"},{pattern:"bind-*",prefix:"bind-"}]);function go(e){if(jt.has(e))return{directive:jt.get(e),match:e};for(let t=0;to.priority-s.priority),Et.size>=_o&&Et.delete(Et.keys().next().value),Et.set(r,i)}return i}function Yn(e,t,n){if(e.__declared)return;e.__declared=!0,t||(t=ii(e));let r=!1;if(t.some(s=>s.gated)&&e.hasAttribute("if")){let s=e.getAttribute("if"),a=B(e);r=!R(s,a)}if(!n){n=new Array(t.length);for(let s=0;s0&&(e.__gatedDirsMeta=e.__gatedDirs.map(s=>({...s}))),t.length>0&&Te("directive:init",{element:e.tagName?.toLowerCase(),directives:t.map((s,a)=>({name:s.name,value:n[a]}))})}var Kt=0;function er(e){let t=[],n=(r,i)=>{if(r.tagName==="TEMPLATE"||r.tagName==="SCRIPT")return;let o=ii(r);if(o.length>0){let a=new Array(o.length);for(let l=0;li){let o=e.__disposers.splice(i);e.__gateDisposers.push(...o)}}ct(t)}function ai(e){if(e.__gateDisposers){for(let t of e.__gateDisposers)try{t()}catch(n){w("gate disposer error:",n)}e.__gateDisposers=[]}e.__gatedDirsMeta&&(e.__gatedDirs=e.__gatedDirsMeta.map(t=>({...t})))}function Zn(e,t){let n=g.devtools?e.__ctx?.__raw?.__devtoolsId:null;if(e.__ctx&&e.__ctx.__listeners){for(let r of e.__ctx.__listeners)xt(r),We.delete(r);e.__ctx.__listeners.clear()}if(e.__watcherFns){for(let r of e.__watcherFns){let i=r._wctx;for(;i&&i.__isProxy;)i.__listeners.delete(r),i=i.$parent;xt(r),Ht(r),We.delete(r)}e.__watcherFns=null}if(e.__disposers){for(let r of e.__disposers)t&&r._elOnly||r();e.__disposers=null}e.__gateDisposers&&(e.__gateDisposers.forEach(r=>r()),e.__gateDisposers=null),e.__declared=!1,n!=null&&(bt.delete(n),Te("ctx:disposed",{id:n,elementTag:e.tagName?.toLowerCase()}))}function He(e,t){if(!e)return;Zn(e,t);let n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;n.nextNode();)Zn(n.currentNode,t)}function se(e,t){if(!e)return;let n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;n.nextNode();)Zn(n.currentNode,t)}_e();var ci=!1;function _n(){if(ci||typeof document>"u")return;ci=!0;let e=` +`:d==="t"?u+=" ":d==="r"?u+="\r":u+=d,r+=2}else if(e[r]==="$"&&r+10;){if(e[r]==="{")d++;else if(e[r]==="}"){if(d--,d===0)break}else if(e[r]==="'"||e[r]==='"'||e[r]==="`"){let b=e[r];for(p+=b,r++;r="0"&&i<="9"||i==="."&&r+1="0"&&e[r+1]<="9"){let s=r,a="";for(;r="0"&&e[r]<="9"||e[r]===".");)a+=e[r++];t.push({type:"Number",value:a,pos:s});continue}if(i>="a"&&i<="z"||i>="A"&&i<="Z"||i==="_"||i==="$"){let s=r,a="";for(;r="a"&&l<="z"||l>="A"&&l<="Z"||l>="0"&&l<="9"||l==="_"||l==="$")a+=l,r++;else break}ji.has(a)?t.push({type:"Forbidden",value:a,pos:s}):Di.has(a)?t.push({type:"Keyword",value:a,pos:s}):t.push({type:"Ident",value:a,pos:s});continue}let o=!1;for(let s=0;s=","<=",">","<"];if(f.type==="Op"&&m.indexOf(f.value)!==-1||f.type==="Keyword"&&(f.value==="in"||f.value==="instanceof")){let P=r().value,N=E();c={type:"BinaryExpr",op:P,left:c,right:N}}return c}function E(){let c=L();for(;n()&&n().type==="Op"&&(n().value==="+"||n().value==="-");){let f=r().value,m=L();c={type:"BinaryExpr",op:f,left:c,right:m}}return c}function L(){let c=C();for(;n()&&n().type==="Op"&&(n().value==="*"||n().value==="/"||n().value==="%");){let f=r().value,m=C();c={type:"BinaryExpr",op:f,left:c,right:m}}return c}function C(){let c=n();return c?c.type==="Keyword"&&c.value==="typeof"?(r(),{type:"UnaryExpr",op:"typeof",argument:C()}):c.type==="Op"&&(c.value==="!"||c.value==="-"||c.value==="+")?(r(),{type:"UnaryExpr",op:c.value,argument:C()}):c.type==="Op"&&(c.value==="++"||c.value==="--")?(r(),{type:"UnaryExpr",op:c.value,argument:C(),prefix:!0}):I():{type:"Literal",value:void 0}}function I(){let c=W(),f=n();return f&&f.type==="Op"&&(f.value==="++"||f.value==="--")&&(r(),c={type:"PostfixExpr",op:f.value,argument:c}),c}function W(){let c=x();for(;;){let f=n();if(!f)break;if(f.type==="Punc"&&f.value==="."){r();let m=n();if(m&&(m.type==="Ident"||m.type==="Keyword"))r(),c={type:"MemberExpr",object:c,property:{type:"Identifier",name:m.value},computed:!1};else if(m&&m.type==="Forbidden")r(),c={type:"Forbidden"};else break;continue}if(f.type==="Punc"&&f.value==="?."){r();let m=n();if(m&&m.type==="Punc"&&m.value==="("){r();let P=ce();o("Punc",")"),c={type:"OptionalCallExpr",callee:c,args:P}}else if(m&&(m.type==="Ident"||m.type==="Keyword"))r(),c={type:"OptionalMemberExpr",object:c,property:{type:"Identifier",name:m.value},computed:!1};else if(m&&m.type==="Punc"&&m.value==="["){r();let P=s();o("Punc","]"),c={type:"OptionalMemberExpr",object:c,property:P,computed:!0}}else break;continue}if(f.type==="Punc"&&f.value==="["){r();let m=s();o("Punc","]"),c={type:"MemberExpr",object:c,property:m,computed:!0};continue}if(f.type==="Punc"&&f.value==="("){r();let m=ce();o("Punc",")"),c={type:"CallExpr",callee:c,args:m};continue}break}return c}function ce(){let c=[];if(i("Punc",")"))return c;for(c.push(T());i("Punc",",")&&(r(),!i("Punc",")"));)c.push(T());return c}function T(){return i("Punc","...")?(r(),{type:"SpreadElement",argument:s()}):s()}function h(){let c=t;if(i("Punc",")")){let f=e[t+1];return f&&f.type==="Op"&&f.value==="=>"?(t=c,!0):(t=c,!1)}for(;t"?(t=c,!0):(t=c,!1)}return t=c,!1}if(f.type==="Punc"&&f.value==="..."){if(r(),i("Ident")&&r(),i("Punc",")")){let m=e[t+1];if(m&&m.type==="Op"&&m.value==="=>")return t=c,!0}return t=c,!1}return t=c,!1}return t=c,!1}function v(){let c=[];if(i("Punc",")"))return c;for(i("Punc","...")?(r(),i("Ident")&&c.push("..."+r().value)):i("Ident")&&c.push(r().value);i("Punc",",")&&(r(),!i("Punc",")"));)i("Punc","...")?(r(),i("Ident")&&c.push("..."+r().value)):i("Ident")&&c.push(r().value);return c}function x(){let c=n();if(!c)return{type:"Literal",value:void 0};if(c.type==="Forbidden")return r(),{type:"Forbidden"};if(c.type==="Number")return r(),{type:"Literal",value:Number(c.value)};if(c.type==="String")return r(),{type:"Literal",value:c.value};if(c.type==="Template")return r(),{type:"TemplateLiteral",parts:c.parts,expressions:c.exprs.map(function(f){return Wn(f)})};if(c.type==="Keyword"){if(c.value==="true")return r(),{type:"Literal",value:!0};if(c.value==="false")return r(),{type:"Literal",value:!1};if(c.value==="null")return r(),{type:"Literal",value:null};if(c.value==="undefined")return r(),{type:"Literal",value:void 0}}if(c.type==="Punc"&&c.value==="["){r();let f=[];for(;!i("Punc","]")&&t");let P=s();return{type:"ArrowFunction",params:m,body:P}}let f=s();return o("Punc",")"),f}if(c.type==="Ident"){if(r(),i("Op","=>")){r();let f=s();return{type:"ArrowFunction",params:[c.value],body:f}}return{type:"Identifier",name:c.value}}return c.type==="Op"&&(c.value==="="||c.value==="+="||c.value==="-="||c.value==="*="||c.value==="/="||c.value==="%=")?(r(),{type:"Literal",value:void 0}):c.type==="Punc"&&c.value==="..."?(r(),{type:"SpreadElement",argument:s()}):(r(),{type:"Literal",value:void 0})}function y(){r();let c=[];for(;!i("Punc","}")&&tObject.prototype.hasOwnProperty.call(e,t)}),qn={Array,Object:Hi,String,Number,Boolean,Math,Date,RegExp,Map,Set,JSON,parseInt,parseFloat,isNaN,isFinite,Infinity:1/0,NaN:NaN,undefined:void 0,Error,Symbol,console},dn=Object.prototype.hasOwnProperty;function zn(e,t){let n=e;for(;n&&n!==Object.prototype;){if(dn.call(n,t))return!0;n=Object.getPrototypeOf(n)}return!1}function pn(e){return dn.call(qn,e)}var Bi=new Set(["fetch","XMLHttpRequest","localStorage","sessionStorage","WebSocket","indexedDB","eval","Function","importScripts","open","postMessage"]),kt={},jr=new Set(["cookie","domain","write","writeln","execCommand"]),Rt=typeof globalThis<"u"&&typeof globalThis.window<"u"?new Proxy(globalThis.window,{get(e,t,n){if(!(typeof t=="string"&&Bi.has(t)))return typeof t=="string"&&t in kt?kt[t]:Reflect.get(e,t,n)},set(){return!0}}):void 0,At=typeof globalThis<"u"&&typeof globalThis.document<"u"?new Proxy(globalThis.document,{get(e,t,n){if(!(typeof t=="string"&&jr.has(t)))return t==="defaultView"?Rt:t==="location"?Dt:Reflect.get(e,t,n)},set(e,t,n){return typeof t=="string"&&jr.has(t)||t==="location"||(e[t]=n),!0}}):void 0,Ui=["href","pathname","search","hash","origin","hostname","port","protocol","host"],dt=()=>{},Dt=typeof globalThis<"u"&&typeof globalThis.location<"u"?(()=>{let e={};for(let t of Ui)Object.defineProperty(e,t,{get(){return globalThis.location[t]},set(){},enumerable:!0,configurable:!1});return e.assign=dt,e.replace=dt,e.reload=dt,e.toString=()=>globalThis.location.href,Object.freeze(e)})():void 0,zi=["length","state","scrollRestoration"],qt=typeof globalThis<"u"&&typeof globalThis.history<"u"?(()=>{let e={};for(let t of zi)Object.defineProperty(e,t,{get(){return globalThis.history[t]},enumerable:!0,configurable:!1});return e.pushState=dt,e.replaceState=dt,e.back=dt,e.forward=dt,e.go=dt,Object.freeze(e)})():void 0,Wi=new Set(["sendBeacon","credentials"]),Jt=typeof globalThis<"u"&&typeof globalThis.navigator<"u"?new Proxy(globalThis.navigator,{get(e,t,n){if(!(typeof t=="string"&&Wi.has(t)))return Reflect.get(e,t,n)},set(){return!0}}):void 0;Dt&&(kt.location=Dt);At&&(kt.document=At);qt&&(kt.history=qt);Jt&&(kt.navigator=Jt);var $t=new Set([Rt,At,Dt,Jt,qt].filter(Boolean)),mn=new Set(["window","document","console","location","history","navigator","screen","performance","crypto","setTimeout","clearTimeout","setInterval","clearInterval","requestAnimationFrame","cancelAnimationFrame","alert","confirm","prompt","CustomEvent","Event","URL","URLSearchParams","FormData","FileReader","Blob","Promise"]),Jn=new Set(["setTimeout","setInterval","requestAnimationFrame"]);function qi(e){let t=typeof globalThis<"u"?globalThis[e]:void 0;if(t)return e==="requestAnimationFrame"?function(r){if(typeof r=="function")return t.call(globalThis,r)}:function(r,i,...o){if(typeof r=="function")return t.call(globalThis,r,i,...o)}}var Kn={};for(let e of Jn)Kn[e]=qi(e);function pt(e){if(!(e===Function||e===eval)){if(e instanceof Document||e===globalThis.document)return At;if(e===globalThis.window||e===globalThis)return Rt;if(e&&typeof e=="object"){let t;try{t=e.nodeType}catch{t=void 0}if(t===9)return At;let n;try{n=e.window}catch{n=void 0}if(n===e)return Rt}return e}}function Mr(e,t){let n=[];for(let r=0;r":return n>r;case"<":return n=":return n>=r;case"<=":return n<=r;case"in":return r&&typeof r=="object"?n in r:void 0;case"instanceof":return n instanceof r;case"&":return n&r;case"|":return n|r;case"^":return n^r;case"<<":return n<>":return n>>r;case">>>":return n>>>r;default:return}}case"UnaryExpr":{if(e.op==="typeof")return e.argument&&e.argument.type==="Identifier"&&!zn(t,e.argument.name)&&!pn(e.argument.name)&&!mn.has(e.argument.name)?"undefined":typeof ee(e.argument,t);if(e.op==="++"||e.op==="--"){let r=ee(e.argument,t),i=e.op==="++"?r+1:r-1;return e.prefix?i:r}let n=ee(e.argument,t);switch(e.op){case"!":return!n;case"-":return-n;case"+":return+n;case"~":return~n;case"void":return;default:return}}case"ConditionalExpr":return ee(e.test,t)?ee(e.consequent,t):ee(e.alternate,t);case"MemberExpr":case"OptionalMemberExpr":{let n=ee(e.object,t);if(n==null)return;let r=e.computed?ee(e.property,t):e.property.name||e.property.value;if(je[r]||It.has(r)&&!$t.has(n))return;let i=n[r];return pt(i)}case"CallExpr":case"OptionalCallExpr":{if(e.callee.type==="MemberExpr"||e.callee.type==="OptionalMemberExpr"){let i=ee(e.callee.object,t);if(i==null)return e.type==="OptionalCallExpr"||e.callee.type==="OptionalMemberExpr",void 0;let o=e.callee.computed?ee(e.callee.property,t):e.callee.property.name;if(je[o]||It.has(o)&&!$t.has(i))return;let s=i[o];if(typeof s!="function")return;let a=s.apply(i,Mr(e.args,t));return pt(a)}let n=ee(e.callee,t);if(n==null&&e.type==="OptionalCallExpr"||typeof n!="function")return;let r=n.apply(void 0,Mr(e.args,t));return pt(r)}case"ArrayExpr":{let n=[];for(let r=0;r{};function ue(e,t){return function(n,r){try{return t(n,r)}catch(i){w("_evalNode error:",e,i?.message||i);return}}}var Br=[];function Vi(e){let t=e.length;if(t===0)return()=>Br;let n=!1,r=new Array(t),i=new Array(t);for(let o=0;o{let a=[];for(let l=0;l{let a=new Array(t);for(let l=0;lt}case"Identifier":{let t=e.name;return(n,r)=>Ki(t,n,r)}case"Forbidden":return Pt;case"BinaryExpr":{let t=e.op,n=pe(e.left);if(t==="&&"){let i=pe(e.right);return(o,s)=>{let a=n(o,s);return a&&i(o,s)}}if(t==="||"){let i=pe(e.right);return(o,s)=>{let a=n(o,s);return a||i(o,s)}}if(t==="??"){let i=pe(e.right);return(o,s)=>{let a=n(o,s);return a??i(o,s)}}let r=pe(e.right);switch(t){case"+":return ue(e.type,(i,o)=>n(i,o)+r(i,o));case"-":return ue(e.type,(i,o)=>n(i,o)-r(i,o));case"*":return ue(e.type,(i,o)=>n(i,o)*r(i,o));case"/":return ue(e.type,(i,o)=>n(i,o)/r(i,o));case"%":return ue(e.type,(i,o)=>n(i,o)%r(i,o));case"**":return ue(e.type,(i,o)=>n(i,o)**r(i,o));case"===":return(i,o)=>n(i,o)===r(i,o);case"!==":return(i,o)=>n(i,o)!==r(i,o);case"==":return ue(e.type,(i,o)=>n(i,o)==r(i,o));case"!=":return ue(e.type,(i,o)=>n(i,o)!=r(i,o));case">":return ue(e.type,(i,o)=>n(i,o)>r(i,o));case"<":return ue(e.type,(i,o)=>n(i,o)=":return ue(e.type,(i,o)=>n(i,o)>=r(i,o));case"<=":return ue(e.type,(i,o)=>n(i,o)<=r(i,o));case"in":return ue(e.type,(i,o)=>{let s=n(i,o),a=r(i,o);return a&&typeof a=="object"?s in a:void 0});case"instanceof":return ue(e.type,(i,o)=>n(i,o)instanceof r(i,o));case"&":return ue(e.type,(i,o)=>n(i,o)&r(i,o));case"|":return ue(e.type,(i,o)=>n(i,o)|r(i,o));case"^":return ue(e.type,(i,o)=>n(i,o)^r(i,o));case"<<":return ue(e.type,(i,o)=>n(i,o)<>":return ue(e.type,(i,o)=>n(i,o)>>r(i,o));case">>>":return ue(e.type,(i,o)=>n(i,o)>>>r(i,o));default:return Pt}}case"UnaryExpr":{let t=e.op;if(t==="typeof"){let r=pe(e.argument);return(i,o)=>typeof r(i,o)}if(t==="++"||t==="--"){let r=pe(e.argument),i=t==="++",o=!!e.prefix;return ue(e.type,(s,a)=>{let l=r(s,a),u=i?l+1:l-1;return o?u:l})}let n=pe(e.argument);switch(t){case"!":return(r,i)=>!n(r,i);case"-":return ue(e.type,(r,i)=>-n(r,i));case"+":return ue(e.type,(r,i)=>+n(r,i));case"~":return ue(e.type,(r,i)=>~n(r,i));case"void":return(r,i)=>{n(r,i)};default:return(r,i)=>{n(r,i)}}}case"ConditionalExpr":{let t=pe(e.test),n=pe(e.consequent),r=pe(e.alternate);return(i,o)=>t(i,o)?n(i,o):r(i,o)}case"MemberExpr":case"OptionalMemberExpr":{let t=pe(e.object);if(!e.computed){let r=e.property.name||e.property.value;if(je[r])return Pt;let i=It.has(r);return ue(e.type,(o,s)=>{let a=t(o,s);if(a!=null&&!(i&&!$t.has(a)))return pt(a[r])})}let n=pe(e.property);return ue(e.type,(r,i)=>{let o=t(r,i);if(o==null)return;let s=n(r,i);if(!je[s]&&!(It.has(s)&&!$t.has(o)))return pt(o[s])})}case"CallExpr":case"OptionalCallExpr":{let t=Vi(e.args),n=e.callee;if(n.type==="MemberExpr"||n.type==="OptionalMemberExpr"){let o=pe(n.object);if(!n.computed){let a=n.property.name;if(je[a])return Pt;let l=It.has(a);return ue(e.type,(u,d)=>{let p=o(u,d);if(p==null||l&&!$t.has(p))return;let b=p[a];if(typeof b=="function")return pt(b.apply(p,t(u,d)))})}let s=pe(n.property);return ue(e.type,(a,l)=>{let u=o(a,l);if(u==null)return;let d=s(a,l);if(je[d]||It.has(d)&&!$t.has(u))return;let p=u[d];if(typeof p=="function")return pt(p.apply(u,t(a,l)))})}let r=pe(n),i=e.type==="OptionalCallExpr";return ue(e.type,(o,s)=>{let a=r(o,s);if(!(a==null&&i)&&typeof a=="function")return pt(a.apply(void 0,t(o,s)))})}case"ArrayExpr":{let t=e.elements.length,n=new Array(t),r=new Array(t);for(let i=0;i{let s=[];for(let a=0;an.spread?{spread:!0,valueFn:pe(n.value)}:n.computed?{computed:!0,keyFn:pe(n.key),valueFn:pe(n.value)}:{key:n.key,valueFn:pe(n.value),forbidden:!!je[n.key]});return ue(e.type,(n,r)=>{let i={};for(let o=0;ofunction(...o){let s=Object.create(i||null);for(let a=0;a{let o=t[0];for(let s=0;s0&&n.push(Wn(o)),r=i+1}return Bn.set(e,n),n}function Un(e,t,n){if(e.type==="Identifier")n[e.name]=t;else if(e.type==="MemberExpr"||e.type==="OptionalMemberExpr"){let r=ee(e.object,n);if(r==null)return;let i=e.computed?ee(e.property,n):e.property.name||e.property.value;if(je[i])return;r[i]=t}}function Zi(e,t){if(e)switch(e.type){case"AssignExpr":{let n=ee(e.right,t),r;if(e.op==="=")r=n;else{let i=ee(e.left,t);switch(e.op){case"+=":r=i+n;break;case"-=":r=i-n;break;case"*=":r=i*n;break;case"/=":r=i/n;break;case"%=":r=i%n;break;default:r=n}}return Un(e.left,r,t),r}case"PostfixExpr":{let n=ee(e.argument,t),r=e.op==="++"?n+1:n-1;return Un(e.argument,r,t),n}case"UnaryExpr":{if(e.op==="++"||e.op==="--"){let n=ee(e.argument,t),r=e.op==="++"?n+1:n-1;return Un(e.argument,r,t),r}return ee(e,t)}default:{if(e.type==="CallExpr"&&e.callee.type==="Identifier"){let n=e.callee.name;if(!zn(t,n)&&!pn(n)&&!mn.has(n))throw new ReferenceError(n+" is not defined")}return ee(e,t)}}}function Ur(e){if(!e.includes("|"))return[e.trim()];let t=[],n="",r=0,i=!1,o="";for(let s=0;s=0&&e[u]==="\\";u--)l++;l%2===0&&(i=!1)}continue}if(a==="'"||a==='"'||a==="`"){i=!0,o=a,n+=a;continue}if(a==="("||a==="["||a==="{"){r++,n+=a;continue}if(a===")"||a==="]"||a==="}"){r--,n+=a;continue}if(a==="|"&&r===0&&e[s+1]!=="|"&&e[s-1]!=="|"){t.push(n.trim()),n="";continue}n+=a}return t.push(n.trim()),t}function Qi(e){let t=[],n="",r=!1,i="";for(let o of e){if(r){if(o===i){r=!1;continue}n+=o;continue}if(o==="'"||o==='"'){r=!0,i=o;continue}if(o===","){t.push(n.trim()),n="";continue}n+=o}return n.trim()&&t.push(n.trim()),t.map(o=>{let s=Number(o);return isNaN(s)?o:s})}var un=new Map,zr=500;function eo(e){let t=un.get(e);if(t!==void 0)return t;let n=to(e);return un.size>=zr&&un.clear(),un.set(e,n),n}function to(e){if(typeof e!="string"||e.trim()==="")return null;let t;try{let r=Ur(e);if(r.length>1)return null;t=Kt(r[0])}catch{return null}if(!t||t.length===0)return null;let n=new Set;for(let r=0;r")||i.type==="Punc"&&i.value==="(")return null;if(i.type==="Ident"){let o=t[r-1];if(o&&o.type==="Punc"&&(o.value==="."||o.value==="?."))continue;if(i.value.charCodeAt(0)===36&&i.value!=="$store"&&i.value!=="$route"&&i.value!=="$i18n")return null;n.add(i.value)}}return n.size>0?n:null}gr(eo);var no=new Set(["$store","$route","$i18n"]),ro=new Set(["$event","$el","$error"]),fn=new Map;function io(e){let t=fn.get(e);if(t!==void 0)return t;t={roots:null,hasGlobalRoot:!1};let n=new Set,r=!0;try{let i=Kt(e);if(!i||i.length===0)r=!1;else for(let o=0;o=zr&&fn.clear(),fn.set(e,t),t}var oo={roots:null,hasGlobalRoot:!1};function R(e,t){if(!(e==null||e===""))try{let n=Rr.get(e);if(n===void 0&&(n=Xi(e),Rr.set(e,n)),!t||!t.__isProxy){w("Expression error:",e,"requires a reactive context");return}let r=n.fn(t,null),i=n.filters;for(let o=0;o{if(!je[r])return n?.[r]},t)}function Ue(e,t){return e.replace(/\{([^}]+)\}/g,(n,r)=>{let i=R(r.trim(),t);return i==null?"":encodeURIComponent(String(i))})}ge();ge();var so=200,Wr=5e3,Vn=0,ao=1,Vt=new WeakMap;function qr(e,t,n){let r;return Promise.race([e.finally(()=>clearTimeout(r)),new Promise((i,o)=>{r=setTimeout(()=>o(new Error(n)),t)})])}function Jr(e){return Tt.has(e.toLowerCase())||/^x-(auth|api)-/i.test(e)}function Kr(e){try{let t=new URL(e,"http://localhost");for(let n of[...t.searchParams.keys()])/token|key|secret|auth|password|credential/i.test(n)&&t.searchParams.set(n,"[REDACTED]");return e.startsWith("http")?t.href:t.pathname+t.search}catch{return e}}function co(e){let t=new Headers(e.headers);for(let i of hr)t.delete(i);let n=Kr(e.url),r=Object.freeze({status:e.status,ok:e.ok,statusText:e.statusText,headers:t,url:n});return Vt.set(r,e),r}function hn(e,t){if(e.startsWith("http://")||e.startsWith("https://")||e.startsWith("//"))return e;let n=t;for(;n;){let r=n.getAttribute?.("base");if(r)return r.replace(/\/+$/,"")+"/"+e.replace(/^\/+/,"");n=n.parentElement}return _.baseApiUrl?_.baseApiUrl.replace(/\/+$/,"")+"/"+e.replace(/^\/+/,""):e}async function gn(e,t="GET",n=null,r={},i=null,o=null,s=void 0,a=void 0,l=null){let u=hn(e,i);_.credentials!=="omit"&&u.startsWith("http://")&&w("Credentials sent over insecure HTTP:",u);let d=t.toUpperCase(),p={method:d,headers:{..._.headers||{},...r},credentials:_.credentials};if(n&&d!=="GET")if(typeof n=="string")try{JSON.parse(n),p.headers["Content-Type"]="application/json",p.body=n}catch{p.body=n}else n instanceof FormData?p.body=n:(p.headers["Content-Type"]="application/json",p.body=JSON.stringify(n));if(_.csrf&&d!=="GET"&&d!=="QUERY"){let I=!1;if(typeof window<"u")try{I=new URL(u.replace(/\\/g,"/"),window.location.href).origin===window.location.origin}catch{I=!1}I&&(p.headers[_.csrf.header||"X-CSRF-Token"]=_.csrf.token||"")}let b=Ke.request.length>0,E={};if(b)for(let I of Object.keys(p.headers))Jr(I)&&(E[I]=p.headers[I],delete p.headers[I]);Vn++;try{if(Vn<=ao)for(let I=0;I{w(`Request interceptor [${I}] error:`,x.message)});if(v&&v[zt])throw te("Request cancelled by interceptor",I),new DOMException("Request cancelled by interceptor","AbortError");if(v&&v[Lt]!==void 0)return te("Request short-circuited by interceptor",I),v[Lt];if(v&&typeof v=="object"&&!v[zt]&&v[Lt]===void 0&&v.headers&&typeof v.headers=="object"){let x={...p.headers};for(let[y,g]of Object.entries(v.headers))Jr(y)?T&&(E[y]=g):x[y]=g;p.headers=x}}}finally{Vn--}b&&Object.assign(p.headers,E);let L=s!==void 0?s:_.retries||0,C;for(let I=0;I<=L;I++){let W=new AbortController,ce=null,T=null;try{if(ce=setTimeout(()=>W.abort(),_.timeout||1e4),o){if(o.aborted)throw new DOMException("Aborted","AbortError");T=()=>W.abort(),o.addEventListener("abort",T)}p.signal=W.signal;let h=await fetch(u,p),v=h;for(let y=0;y{w(`Response interceptor [${y}] error:`,N.message)});if(P&&P[Wt]!==void 0)return te("Response replaced by interceptor",y),l&&(l.headers=h.headers),P[Wt];P&&(h=P,Vt.has(P)?v=Vt.get(P):typeof P.text=="function"&&(v=P))}if(Vt.has(h)?h=Vt.get(h):typeof h.text!="function"&&(h=v),!h.ok){let y=await h.json().catch(()=>({})),g=new Error(y.message||`HTTP ${h.status}`);throw g.status=h.status,g.body=y,g}l&&(l.headers=h.headers);let x=await h.text();try{return JSON.parse(x)}catch{return x}}catch(h){if(h.name==="AbortError")throw h;C=h,IsetTimeout(v,a!==void 0?a:_.retryDelay||1e3))}finally{ce!==null&&clearTimeout(ce),o&&T&&o.removeEventListener("abort",T)}}throw C}function Vr(e,t){if(t==="none")return null;if(t==="memory"){let r=Ze.get(e);return r&&Date.now()-r.time<(_.cache.ttl||3e5)?(Ze.delete(e),Ze.set(e,r),r.data):null}let n=t==="local"?localStorage:t==="session"?sessionStorage:null;if(!n)return null;try{let r=n.getItem("nojs_cache_"+e);if(!r)return null;let i=JSON.parse(r);if(Date.now()-i.time<(_.cache.ttl||3e5))return i.data;n.removeItem("nojs_cache_"+e)}catch{}return null}function Gr(e,t,n){if(n==="none")return;let r={data:t,time:Date.now()};if(n==="memory"){Ze.has(e)?Ze.delete(e):Ze.size>=so&&Ze.delete(Ze.keys().next().value),Ze.set(e,r);return}let i=n==="local"?localStorage:n==="session"?sessionStorage:null;if(i)try{i.setItem("nojs_cache_"+e,JSON.stringify(r))}catch{}}var lo=200,Qe=new Map;function uo(){let e=_.templates&&_.templates.maxSize;return typeof e=="number"&&e>0?e:lo}function fo(e){if(!Qe.has(e))return;let t=Qe.get(e);return Qe.delete(e),Qe.set(e,t),t}function po(e,t){let n=uo();Qe.has(e)?Qe.delete(e):Qe.size>=n&&Qe.delete(Qe.keys().next().value),Qe.set(e,t)}var Gn=new Map,Yr=new DOMParser;function H(e){let t=e;for(;t;){if(t.__ctx)return t.__ctx;t=t.parentElement}return q()}function ze(e){let t=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;t.nextNode();)t.currentNode.__declared=!1}function ye(e){if(!e)return null;let t=e.startsWith("#")?e.slice(1):e,n=document.getElementById(t);return n&&n.content?n.content.cloneNode(!0):null}function Xr(e){let n=Yr.parseFromString(e,"image/svg+xml").documentElement;if(n.querySelector("parsererror")||n.nodeName!=="svg"||n.getElementsByTagNameNS("http://www.mozilla.org/newlayout/xml/parsererror.xml","parsererror").length)return"";function r(i){for(let o of[...i.attributes]){let s=o.name.toLowerCase();if(s.startsWith("on")){i.removeAttribute(o.name);continue}if(s==="href"||s==="xlink:href"){let a=o.value.toLowerCase().replace(/[\u0000-\u0020]/g,"");/^(javascript|vbscript):/.test(a)&&i.removeAttribute(o.name)}}}for(let i of[...n.querySelectorAll("script")])i.remove();r(n);for(let i of n.querySelectorAll("*"))r(i);return new XMLSerializer().serializeToString(n)}function mo(e){let t=atob(e);if(typeof TextDecoder=="function"){let n=new Uint8Array(t.length);for(let r=0;r"%"+("00"+n.charCodeAt(0).toString(16)).slice(-2)).join(""))}function ho(e){let t;if(typeof TextEncoder=="function"){let n=new TextEncoder().encode(e),r="";for(let i=0;i{let r=await fetch(e);if(!r.ok)return{ok:!1,status:r.status};let i=await r.text();return t&&po(e,i),{ok:!0,html:i}})(),Gn.set(e,n));try{let r=await n;return r.ok?{html:r.html,hit:!1}:{html:null,status:r.status}}finally{Gn.delete(e)}}async function Qr(e){let t=e||document,n=t.querySelectorAll("template[src]");if(te("[LRT] called on",t===document?"document":t.nodeName||"fragment","\u2014 found",n.length,"template[src]",[...n].map(i=>i.getAttribute("src"))),!n.length)return;let r=[...n].map(async i=>{if(i.__srcLoaded){te("[LRT] SKIP (already loaded):",i.getAttribute("src"));return}i.__srcLoaded=!0;let o=i.getAttribute("src"),s=Xn(o,i);Zr(s,o);let a=s.substring(0,s.lastIndexOf("/")+1);try{let l=_.templates.cache!==!1,{html:u,hit:d,status:p}=await Yn(s,l);if(u===null){w("Failed to load template:",o,"HTTP",p),i.__loadFailed=!0;return}if(d&&te("[LRT] CACHE HIT:",s),i.innerHTML=u,i.content&&(i.content.__srcBase=a),te("Loaded remote template:",o,"\u2192",s),await Qr(i.content||i),!i.hasAttribute("route")&&i.parentNode){let E=[...i.content.childNodes],L=i.parentNode,C=i.nextSibling;L.removeChild(i);for(let I of E)I.nodeType===1&&(I.__srcBase=I.__srcBase||a),L.insertBefore(I,C)}}catch(l){w("Failed to load template:",o,l.message)}});await Promise.all(r)}async function Me(e){let t=e.getAttribute("src");if(e.__srcLoaded){te("[LTE] SKIP (already loaded):",t);return}te("[LTE] START fetch:",t,"| route:",e.hasAttribute("route"),"| inDOM:",document.contains(e),"| loading:",e.getAttribute("loading")),e.__srcLoaded=!0;let n=Xn(t,e);Zr(n,t);let r=n.substring(0,n.lastIndexOf("/")+1),i=null,o=e.getAttribute("loading");if(o&&e.parentNode){let s=o.startsWith("#")?o.slice(1):o,a=document.getElementById(s);a&&a.content&&(i=document.createElement("span"),i.style.cssText="display:contents",i.appendChild(a.content.cloneNode(!0)),e.parentNode.insertBefore(i,e))}try{let s=_.templates.cache!==!1,{html:a,hit:l,status:u}=await Yn(n,s);if(a===null){w("Failed to load template:",t,"HTTP",u),e.__loadFailed=!0,i&&i.remove();return}if(l&&te("[LTE] CACHE HIT:",n),e.innerHTML=a,e.content&&(e.content.__srcBase=r),te("Loaded remote template:",t,"\u2192",n),!e.hasAttribute("route"))await Qr(e.content||e);else if(s&&e.content){let p=[...e.content.querySelectorAll("template[src]")].map(b=>{let E=b.getAttribute("src"),L=Xn(E,b);return Yn(L,!0).catch(()=>{})});e.__warmup=Promise.all(p)}if(i&&i.remove(),!e.hasAttribute("route")&&e.parentNode){let p=[...e.content.childNodes],b=e.parentNode,E=e.nextSibling;b.removeChild(e);for(let L of p)L.nodeType===1&&(L.__srcBase=L.__srcBase||r),b.insertBefore(L,E)}}catch(s){i&&i.remove(),w("Failed to load template:",t,s.message)}}function Mt(e){(e||document).querySelectorAll("template[include]").forEach(n=>{let r=n.getAttribute("include"),i=document.getElementById(r.startsWith("#")?r.slice(1):r);!i||!i.content||n.replaceWith(i.content.cloneNode(!0))})}async function ei(e){let t=[...document.querySelectorAll("template[src]")],n=t.filter(i=>!i.__srcLoaded&&i.getAttribute("lazy")==="priority");await Promise.all(n.map(Me));let r=t.filter(i=>{if(i.__srcLoaded)return!1;let o=i.getAttribute("lazy");return o==="ondemand"||o==="priority"?!1:i.hasAttribute("route")?e!=null&&i.getAttribute("route")===e:!0});await Promise.all(r.map(Me))}function ti(){let t=[...document.querySelectorAll("template[src]")].filter(n=>n.__srcLoaded||n.getAttribute("lazy")==="ondemand"?!1:n.hasAttribute("route"));return Promise.all(t.map(Me))}ge();var Ft=new Map,er=!1,yn=new Set;function F(e,t){if(er&&yn.has(e)){w(`Cannot override core directive "${e}".`);return}Ft.set(e,{priority:t.priority??50,init:t.init,gated:!!t.gated}),yn.add(e),xt.clear(),Gt++}function ri(){er=!0}function ii(e){if(!er){w(`_removeCoreDirective("${e}") can only be called after init.`);return}if(!yn.has(e)){w(`_removeCoreDirective: "${e}" is not a registered core directive.`);return}yn.delete(e),Ft.delete(e),xt.clear(),Gt++}var ni=Object.freeze([{pattern:"class-*",prefix:"class-"},{pattern:"on:*",prefix:"on:"},{pattern:"style-*",prefix:"style-"},{pattern:"bind-*",prefix:"bind-"}]);function yo(e){if(Ft.has(e))return{directive:Ft.get(e),match:e};for(let t=0;to.priority-s.priority),xt.size>=bo&&xt.delete(xt.keys().next().value),xt.set(r,i)}return i}function Zn(e,t,n){if(e.__declared)return;e.__declared=!0,t||(t=oi(e));let r=!1;if(t.some(s=>s.gated)&&e.hasAttribute("if")){let s=e.getAttribute("if"),a=H(e);r=!R(s,a)}if(!n){n=new Array(t.length);for(let s=0;s0&&(e.__gatedDirsMeta=e.__gatedDirs.map(s=>({...s}))),t.length>0&&Te("directive:init",{element:e.tagName?.toLowerCase(),directives:t.map((s,a)=>({name:s.name,value:n[a]}))})}var Gt=0;function tr(e){let t=[],n=(r,i)=>{if(r.tagName==="TEMPLATE"||r.tagName==="SCRIPT")return;let o=oi(r);if(o.length>0){let a=new Array(o.length);for(let l=0;li){let o=e.__disposers.splice(i);e.__gateDisposers.push(...o)}}lt(t)}function ci(e){if(e.__gateDisposers){for(let t of e.__gateDisposers)try{t()}catch(n){w("gate disposer error:",n)}e.__gateDisposers=[]}e.__gatedDirsMeta&&(e.__gatedDirs=e.__gatedDirsMeta.map(t=>({...t})))}function Qn(e,t){let n=_.devtools?e.__ctx?.__raw?.__devtoolsId:null;if(e.__ctx&&e.__ctx.__listeners){for(let r of e.__ctx.__listeners)ut(r),We.delete(r);e.__ctx.__listeners.clear()}if(e.__watcherFns){for(let r of e.__watcherFns){let i=r._wctx;for(;i&&i.__isProxy;)i.__listeners.delete(r),i=i.$parent;ut(r),bt(r),We.delete(r)}e.__watcherFns=null}if(e.__disposers){for(let r of e.__disposers)t&&r._elOnly||r();e.__disposers=null}e.__gateDisposers&&(e.__gateDisposers.forEach(r=>r()),e.__gateDisposers=null),e.__declared=!1,n!=null&&(Et.delete(n),Te("ctx:disposed",{id:n,elementTag:e.tagName?.toLowerCase()}))}function He(e,t){if(!e)return;Qn(e,t);let n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;n.nextNode();)Qn(n.currentNode,t)}function ie(e,t){if(!e)return;let n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;n.nextNode();)Qn(n.currentNode,t)}ge();var li=!1;function bn(){if(li||typeof document>"u")return;li=!0;let e=` @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } @@ -98,5 +98,5 @@ animation-duration: 0.01ms !important; } } -`.trim(),t=document.createElement("style");t.setAttribute("data-nojs-animations",""),t.textContent=e,document.head.appendChild(t)}function St(e,t,n,r,i=!1){_n();let o=r||0;if(t){let s=i?e:e.firstElementChild||e;s.classList.add(t),s.style.animationName=t,s.style.animationFillMode="forwards",s.style.animationTimingFunction="ease",r&&(s.style.animationDuration=r+"ms");let a=!1,l,u=()=>{a||(a=!0,clearTimeout(l),s.removeEventListener("animationend",u),s.classList.remove(t),s.style.animationName="",s.style.animationDuration="",s.style.animationFillMode="",s.style.animationTimingFunction="")};return s.addEventListener("animationend",u,{once:!0}),l=setTimeout(u,o),()=>u()}if(n){let s=i?e:e.firstElementChild||e;s.classList.add(n+"-enter",n+"-enter-active");let a=!1,l,u=requestAnimationFrame(()=>{s.classList.remove(n+"-enter"),s.classList.add(n+"-enter-to");let d=()=>{a||(a=!0,clearTimeout(l),s.removeEventListener("transitionend",d),s.classList.remove(n+"-enter-active",n+"-enter-to"))};s.addEventListener("transitionend",d,{once:!0}),l=setTimeout(d,o)});return()=>{a=!0,cancelAnimationFrame(u),clearTimeout(l),s.classList.remove(n+"-enter",n+"-enter-active",n+"-enter-to")}}return()=>{}}function yn(e,t,n,r,i){_n();let o=i||0;if(!e.firstElementChild&&!e.childNodes.length)return r(),()=>{};if(t){let s=e.firstElementChild||e;s.classList.add(t),i&&(s.style.animationDuration=i+"ms");let a=!1,l=()=>{a||(a=!0,s.classList.remove(t),r())};s.addEventListener("animationend",l,{once:!0});let u=setTimeout(l,o);return()=>{a=!0,clearTimeout(u),s.removeEventListener("animationend",l)}}if(n){let s=e.firstElementChild||e;s.classList.add(n+"-leave",n+"-leave-active");let a=!1,l,u=requestAnimationFrame(()=>{s.classList.remove(n+"-leave"),s.classList.add(n+"-leave-to");let d=()=>{a||(a=!0,s.classList.remove(n+"-leave-active",n+"-leave-to"),r())};s.addEventListener("transitionend",d,{once:!0}),l=setTimeout(d,o)});return()=>{a=!0,cancelAnimationFrame(u),clearTimeout(l),s.classList.remove(n+"-leave",n+"-leave-active",n+"-leave-to")}}return r(),()=>{}}function yo(e,t){return e.replace(/\{([^}"'{][^}]*)\}/g,(n,r)=>{try{let i=R(r.trim(),t);return i!=null?String(i):""}catch{return""}})}function li(e){return!e||typeof e!="string"?!1:e.startsWith("/")||e.startsWith("#")||e.startsWith(".")}var tr='

404

Page not found

',fi="forward";function bo(e){let t=new Set;for(let n of e){let r=n.getAttribute("transition");r&&r!=="true"&&t.add(r)}return t.add(fi),[...t]}function ui(){return typeof document<"u"&&typeof document.startViewTransition=="function"&&g.router.viewTransition!==!1}function bn(){for(let e of document.querySelectorAll("[route-view]")){for(let t of[...e.children])He(t);e.innerHTML=""}}function di(){let e=[],t=new Map,n={path:"",params:{},query:{},hash:""},r=new Set,i=new Map,o=[];function s(x){let m=e.find(b=>b.path===x);if(!m){let b=[],A=x.replace(/:(\w+)/g,(E,L)=>(b.push(L),"([^/]+)")),_=new RegExp("^"+A+"$");m={path:x,outlets:{},regex:_,paramNames:b},e.push(m)}return m}function a(x){let m={};return new URLSearchParams(x).forEach((b,A)=>{m[A]=b}),m}function l(x){for(let m of e){let b=x.match(m.regex);if(b){let A={},_=m.paramNames;for(let E=0;E<_.length;E++)A[_[E]]=b[E+1];return{route:m,params:A}}}return null}async function u(x,m=!1,b=!1){fi=b?"backward":"forward";let A=x.indexOf("#"),_=A>=0?x.slice(A+1):"",E=A>=0?x.slice(0,A):x,[L,c=""]=E.split("?"),f=L.length>1?L.replace(/\/+$/,""):L;if(f===n.path&&_){if(n.hash="#"+_,g.router.useHash){let D="#"+x;m?window.location.replace(D):window.location.hash=x}else{let D=(g.router.base||"/").replace(/\/$/,"")+x;m?window.history.replaceState({},"",D):window.history.pushState({},"",D)}requestAnimationFrame(()=>{let D=document.getElementById(_);D&&D.scrollIntoView({behavior:"smooth"})}),$n(),r.forEach(D=>D(n));return}n={path:f,params:{},query:a(c),hash:_?"#"+_:""};let h=l(f);if(h){n.matched=!0,n.params=h.params;let D=h.route.outlets?.default,K=D?.getAttribute("guard"),z=D?.getAttribute("redirect");if(K){let ge=te({},null);if(ge.__raw.$store=le,ge.__raw.$route=n,!R(K,ge)){z&&li(z)?await u(z,!0):z?(w(`Route guard redirect blocked \u2014 "${z}" is not a relative path.`),bn()):(w(`Route guard failed for "${x}" but no redirect is defined. The route will not render.`),bn());return}}}else{n.matched=!1;let D=t.get("default");if(D){let K=D.getAttribute("guard"),z=D.getAttribute("redirect");if(K){let ge=te({},null);if(ge.__raw.$store=le,ge.__raw.$route=n,!R(K,ge)){z&&li(z)?await u(z,!0):z?(w(`Route guard redirect blocked \u2014 "${z}" is not a relative path.`),bn()):(w(`Route guard failed for "${x}" but no redirect is defined. The route will not render.`),bn());return}}}}let N=f+(c?"?"+c:"")+(_?"#"+_:"");if(g.router.useHash){let D="#"+N;m?window.location.replace(D):window.location.hash=N}else{let D=(g.router.base||"/").replace(/\/$/,"")+N;m?window.history.replaceState({},"",D):window.history.pushState({},"",D)}let P=n,ne=document.querySelectorAll("[route-view]"),O=[...ne].some(D=>D.getAttribute("transition"));if(ui()&&O){_n();for(let z of ne)if(z.getAttribute("transition")){let ge=(z.getAttribute("route-view")||"").trim();z.style.viewTransitionName=ge&&ge!=="default"?"route-content-"+ge:"route-content"}let D=bo(ne),K=document.startViewTransition({update:async()=>{await T(h,P)},types:D});K.finished.catch(z=>{z.name!=="AbortError"&&w("View transition failed:",z)}),K.ready?.catch(()=>{}),await K.updateCallbackDone}else await T(h,P);if(await v(),$n(),r.forEach(D=>D(n)),Te("route:navigate",{path:n.path,params:n.params,query:n.query,hash:n.hash}),n.hash){let D=n.hash.slice(1);requestAnimationFrame(()=>{let K=document.getElementById(D);K&&K.scrollIntoView({behavior:"smooth"})})}}function d(x,m){if(!document.head)return;let b=te({},null);b.__raw.$route=m,b.__raw.$store=le;let A=x.getAttribute("page-title");if(A){let c=R(A,b);c!=null&&(document.title=String(c))}let _=x.getAttribute("page-description");if(_){let c=R(_,b);if(c!=null){let f=document.querySelector('meta[name="description"]');f||(f=document.createElement("meta"),f.name="description",document.head.appendChild(f)),f.content=String(c)}}let E=x.getAttribute("page-canonical");if(E){let c=R(E,b);if(c!=null){let f=document.querySelector('link[rel="canonical"]');f||(f=document.createElement("link"),f.rel="canonical",document.head.appendChild(f)),f.href=String(c)}}let L=x.getAttribute("page-jsonld");if(L){let c=document.querySelector('script[type="application/ld+json"][data-nojs]');c||(c=document.createElement("script"),c.type="application/ld+json",c.setAttribute("data-nojs",""),document.head.appendChild(c)),c.textContent=yo(L,b).replace(/<\//g,"<\\/")}}function p(x,m,b,A,_){let E=x+m+b,L=A+":"+E;if(i.has(L))return i.get(L);let c=document.createElement("template");return c.setAttribute("src",E),c.setAttribute("route",_),document.body.appendChild(c),i.set(L,c),c}async function y(x,m){let b=g.router.templates||"";if(!x.hasAttribute("src")&&!b)return null;let _=(x.getAttribute("src")||b).replace(/\/?$/,"/"),E=x.getAttribute("ext")||g.router.ext||".tpl",L=x.getAttribute("route-index")||"index";if(n.path==="/"){let O=L,D=p(_,O,E,m,n.path);return ee("[ROUTER] File-based route:",n.path,"\u2192",_+O+E),x.hasAttribute("i18n-ns")&&!D.getAttribute("i18n-ns")&&D.setAttribute("i18n-ns",O),{tpl:D,remainingSegments:[],baseSrc:_,ext:E,indexName:L}}let c=n.path.replace(/^\//,"").split("/").filter(Boolean);if(c.length<=1){let O=c[0]||L,D=p(_,O,E,m,n.path);return ee("[ROUTER] File-based route:",n.path,"\u2192",_+O+E),x.hasAttribute("i18n-ns")&&!D.getAttribute("i18n-ns")&&D.setAttribute("i18n-ns",O),{tpl:D,remainingSegments:[],baseSrc:_,ext:E,indexName:L}}let f=c[0],h=m+":layout:"+_+f+E,N;if(i.has(h)){let O=i.get(h);N=O&&!O.__loadFailed}else{let O=p(_,f,E,m,"/"+f);i.set(h,O),O.__srcLoaded||await Me(O),N=!O.__loadFailed}if(N){let O=i.get(h)||p(_,f,E,m,"/"+f);return ee("[ROUTER] Hierarchical layout:",n.path,"\u2192 layout",_+f+E,"remaining:",c.slice(1)),x.hasAttribute("i18n-ns")&&!O.getAttribute("i18n-ns")&&O.setAttribute("i18n-ns",f),{tpl:O,remainingSegments:c.slice(1),baseSrc:_,ext:E,indexName:L}}let P=c.join("/"),ne=p(_,P,E,m,n.path);return ee("[ROUTER] File-based route (flat fallback):",n.path,"\u2192",_+P+E),x.hasAttribute("i18n-ns")&&!ne.getAttribute("i18n-ns")&&ne.setAttribute("i18n-ns",P),{tpl:ne,remainingSegments:[],baseSrc:_,ext:E,indexName:L}}async function v(){let x=document.querySelectorAll("[route-view][route-index]");for(let m of x){if(m.children.length>0)continue;let b=m.getAttribute("route-index");if(!b)continue;let A=(m.getAttribute("route-view")||"").trim()||"default",_=m.getAttribute("ext")||g.router.ext||".tpl",E=m.getAttribute("src");if(E&&E.startsWith("./")){let O=m.parentNode;for(;O;){if(O.__srcBase){E=O.__srcBase+E.slice(2);break}O=O.parentNode}E.startsWith("./")&&(E=E.slice(2))}let L=E?E.replace(/\/?$/,"/"):"",c=p(L,b,_,A,"/"+b);if(c.getAttribute("src")&&!c.__srcLoaded&&await Me(c),c.__loadFailed)continue;c.removeAttribute("route"),ee("[ROUTER] Nested index route:",L+b+_),m.hasAttribute("i18n-ns")&&!c.getAttribute("i18n-ns")&&c.setAttribute("i18n-ns",b),He(m),m.innerHTML="";let f=c.getAttribute("i18n-ns");if(f){let{_loadI18nNamespace:O}=await Promise.resolve().then(()=>(ot(),tn));await O(f)}let h=c.content.cloneNode(!0),N=te({$route:n},B(m)),P=document.createElement("div");P.style.display="contents",P.__ctx=N,c.content.__srcBase&&(P.__srcBase=c.content.__srcBase),P.appendChild(h),m.appendChild(P),Dt(P);let ne=[...P.querySelectorAll("template[src]")];await Promise.all(ne.map(Me)),Ue(P),Q(P)}}async function I(x,m,b,A,_,E){if(!m.length)return;let L=[...x.querySelectorAll("[route-view]")];if(!L.length)return;let c=m[0],f=m.slice(1);for(let h of L){let N=(h.getAttribute("route-view")||"").trim()||"default",P=h.getAttribute("src");if(P&&P.startsWith("./")){let V=h.parentNode;for(;V;){if(V.__srcBase){P=V.__srcBase+P.slice(2);break}V=V.parentNode}P.startsWith("./")&&(P=P.slice(2))}let ne=P?P.replace(/\/?$/,"/"):b,O=h.getAttribute("ext")||A,D=N+":"+ne+c;if(E.has(D)){w("[ROUTER] Infinite loop detected for nested outlet:",D);continue}E.add(D);let K,z=f;if(f.length>0){let V=N+":layout:"+ne+c+O;if(!i.has(V)){let Re=p(ne,c,O,N,"/"+c);i.set(V,Re),Re.__srcLoaded||await Me(Re)}let be=i.get(V);if(be&&!be.__loadFailed)K=be,ee("[ROUTER] Nested layout:",c,"\u2192",ne+c+O);else{let Re=[c,...f].join("/");K=p(ne,Re,O,N,n.path),z=[],ee("[ROUTER] Nested flat fallback:",c,"\u2192",ne+Re+O)}}else K=p(ne,c,O,N,n.path),ee("[ROUTER] Nested leaf:",c,"\u2192",ne+c+O);if(K.getAttribute("src")&&!K.__srcLoaded&&await Me(K),K.__loadFailed){let V=t.get(N)||(N!=="default"?t.get("default"):null);if(V&&!V.__loadFailed&&(K=V,K.getAttribute("src")&&!K.__srcLoaded&&await Me(K)),!K||K.__loadFailed){He(h),h.innerHTML=tr;continue}}He(h),h.innerHTML="";let ge=K.getAttribute("i18n-ns");if(ge){let{_loadI18nNamespace:V}=await Promise.resolve().then(()=>(ot(),tn));await V(ge)}let Le=K.content.cloneNode(!0),U=te({$route:n},B(h)),ye=document.createElement("div");ye.style.display="contents",ye.__ctx=U,K.content.__srcBase&&(ye.__srcBase=K.content.__srcBase),ye.appendChild(Le),h.appendChild(ye),Dt(ye);let C=[...ye.querySelectorAll("template[src]")];await Promise.all(C.map(Me)),Ue(ye),Q(ye),z.length>0&&await I(ye,z,ne,O,_,E)}}async function T(x,m=n){let b=document.querySelectorAll("[route-view]");for(let _ of b){if(!_.isConnected||_.parentElement&&_.parentElement.closest("[route-view]"))continue;let E=_.getAttribute("route-view"),L=E&&E.trim()!==""?E.trim():"default",c=x?.route?.outlets?.[L],f=[],h="",N="",P="index",ne=g.router.templates||"";if(!c&&(_.hasAttribute("src")||ne)){let O=await y(_,L);O&&(c=O.tpl,f=O.remainingSegments,h=O.baseSrc,N=O.ext,P=O.indexName)}if((!c||c.__loadFailed)&&(!x||c?.__loadFailed)){let O=t.get(L)||(L!=="default"?t.get("default"):null);O&&(c=O)}for(let O of[..._.children])He(O);if(_.innerHTML="",c&&!c.__loadFailed){if(c.getAttribute("src")&&!c.__srcLoaded&&(ee("Loading route template on demand:",c.getAttribute("src")),await Me(c)),c.__loadFailed){let U=t.get(L)||(L!=="default"?t.get("default"):null);if(U&&!U.__loadFailed&&(c=U,c.getAttribute("src")&&!c.__srcLoaded&&await Me(c)),!c||c.__loadFailed){_.innerHTML=tr;continue}}let O=c.getAttribute("i18n-ns");if(O){let{_loadI18nNamespace:U}=await Promise.resolve().then(()=>(ot(),tn));await U(O)}let D=c.content.cloneNode(!0),K=te({$route:m},B(_)),z=document.createElement("div");z.style.display="contents",z.__ctx=K,c.content.__srcBase&&(z.__srcBase=c.content.__srcBase),z.appendChild(D),_.appendChild(z),Dt(z);let ge=[...z.querySelectorAll("template[src]")];ee("[ROUTER] nested templates found in wrapper:",ge.length,ge.map(U=>U.getAttribute("src")+(U.__srcLoaded?"[LOADED]":"[NEW]"))),await Promise.all(ge.map(Me)),ee("[ROUTER] all nested loads done for route:",m.path);let Le=_.getAttribute("transition");if(Le&&!ui()&&(St(z,null,Le),w("Class-based route transitions are deprecated. The View Transition API is now used by default. Set router.viewTransition to false to keep legacy behavior.")),Ue(z),Q(z),f.length>0&&await I(z,f,h,N,P,new Set),L==="default"){let U=c.getAttribute("page-title");if(U){let ye=te({},null);ye.__raw.$route=m,ye.__raw.$store=le;let C=R(U,ye);C!=null&&(document.title=String(C))}}L==="default"&&d(c,m),L==="default"&&g.router.focusBehavior==="auto"&&requestAnimationFrame(()=>{let U=_.querySelector("[autofocus]")||_.querySelector('[tabindex="-1"]')||_.querySelector("h1")||_;U.hasAttribute("tabindex")||U.setAttribute("tabindex","-1"),U.focus({preventScroll:!0})})}else(!x||c?.__loadFailed)&&(_.innerHTML=tr)}document.querySelectorAll("[route]").forEach(_=>{let E=_.getAttribute("route"),L=_.getAttribute("route-active")||"active",c=_.getAttribute("route-active-exact");if(c)c.split(/\s+/).filter(Boolean).forEach(f=>_.classList.toggle(f,m.path===E));else if(L&&!_.hasAttribute("route-active-exact")){let f=m.path,h=E==="/"?f==="/":f===E||f.startsWith(E.replace(/\/$/,"")+"/");L.split(/\s+/).filter(Boolean).forEach(N=>_.classList.toggle(N,h))}});let A=g.router.scrollBehavior;A==="top"?window.scrollTo(0,0):A==="smooth"&&window.scrollTo({top:0,behavior:"smooth"})}function $(x,m){m.scrollIntoView({behavior:"smooth"});let b='a[href="#'+x+'"]';document.querySelectorAll('a[href^="#"]').forEach(A=>{A.hasAttribute("route")||A.classList.toggle("active",A.matches(b))})}function J(){let x=document.querySelectorAll("[route-view]");for(let m of x){if(m.parentElement&&m.parentElement.closest("[route-view]"))continue;let b=m.getAttribute("src")||g.router.templates||"";if(!b)continue;let A=b.replace(/\/?$/,"/"),_=m.getAttribute("ext")||g.router.ext||".tpl",E=m.getAttribute("route-index")||"index",L=(m.getAttribute("route-view")||"").trim()||"default",c=new Map;document.querySelectorAll("[route]:not([route-view])").forEach(N=>{let P=N.getAttribute("route");if(!P)return;let ne=P.split("?")[0].split("#")[0],O=N.getAttribute("lazy"),D=c.get(ne);(!c.has(ne)||O==="priority"||D==="ondemand"&&O!=="ondemand")&&c.set(ne,O)});let f=[],h=[];for(let[N,P]of c){if(P==="ondemand"||N===n.path||N==="*")continue;let ne=N==="/"?E:N.replace(/^\//,""),O=N==="/"?[]:N.replace(/^\//,"").split("/").filter(Boolean);if(O.length>1){let ge=O[0],Le=L+":layout:"+A+ge+_,U=i.get(Le);if(U&&!U.__loadFailed){let ye=O.join("/"),C=p(A,ye,_,L,N);C.__srcLoaded||(ee("[ROUTER] Prefetch (layout child):",N,"\u2192",A+ye+_,P==="priority"?"(priority)":"(background)"),m.hasAttribute("i18n-ns")&&C.setAttribute("i18n-ns",ye),P==="priority"?f.push(C):h.push(C));continue}}let D=A+ne+_,K=L+":"+D;if(i.has(K))continue;let z=p(A,ne,_,L,N);ee("[ROUTER] Prefetch:",N,"\u2192",D,P==="priority"?"(priority)":"(background)"),m.hasAttribute("i18n-ns")&&z.setAttribute("i18n-ns",ne),P==="priority"?f.push(z):h.push(z)}(f.length||h.length)&&Promise.all(f.map(Me)).then(()=>{h.forEach(Me)})}}return{get current(){return n},push(x){return u(x)},replace(x){return u(x,!0)},back(){window.history.back()},forward(){window.history.forward()},on(x){return r.add(x),()=>r.delete(x)},register(x,m,b="default"){if(x==="*"){t.set(b,m);return}let A=s(x);A.outlets[b]=m},async init(){g.router.useHash&&!g.router.suppressHashWarning&&w("Router is running in hash mode (useHash: true). URLs like /#/about are not indexed as separate pages by search engines. Use useHash: false with a server-side SPA fallback (try_files) for SEO-friendly routing. See: https://github.com/no-js-dev/nojs/blob/main/docs/md/routing.md#deployment"),document.querySelectorAll("template[route]").forEach(m=>{let b=m.getAttribute("route"),A=m.getAttribute("outlet")||"default";if(b==="*"){t.set(A,m);return}let _=s(b);_.outlets[A]=m});let x=m=>{let b=m.target.closest("[route]");if(b&&!b.hasAttribute("route-view")){m.preventDefault();let _=b.getAttribute("route");u(_);return}let A=m.target.closest('a[href^="#"]');if(A&&!A.hasAttribute("route")){let E=A.getAttribute("href").slice(1);if(E&&!E.startsWith("/")){let L=document.getElementById(E);L&&(m.preventDefault(),$(E,L),g.router.useHash||window.history.replaceState(null,"","#"+E))}}};if(document.addEventListener("click",x),o.push(()=>document.removeEventListener("click",x)),g.router.useHash){let m=()=>{let A=window.location.hash.slice(1)||"/";if(!A.startsWith("/")){let E=document.getElementById(A);E&&($(A,E),window.history.replaceState(null,"","#"+n.path));return}let[_]=A.split("?");_!==n.path&&u(A,!0,!0)};window.addEventListener("hashchange",m),o.push(()=>window.removeEventListener("hashchange",m));let b=window.location.hash.slice(1)||"/";await u(b,!0)}else{let m=()=>{let A=Mt(window.location.pathname);if(A===n.path){let _=window.location.hash.slice(1);if(_){let E=document.getElementById(_);E&&$(_,E)}return}u(A,!0,!0)};window.addEventListener("popstate",m),o.push(()=>window.removeEventListener("popstate",m));let b=Mt(window.location.pathname);await u(b,!0)}J()},destroy(){o.forEach(x=>x()),o.length=0,r.clear()}}}_e();Y.uppercase=e=>String(e??"").toUpperCase();Y.lowercase=e=>String(e??"").toLowerCase();Y.capitalize=e=>String(e??"").replace(/\b\w/g,t=>t.toUpperCase());Y.truncate=(e,t=100)=>{let n=String(e??"");return n.length>t?n.slice(0,t)+"...":n};Y.trim=e=>String(e??"").trim();Y.stripHtml=e=>String(e??"").replace(/<[^>]*>/g,"");Y.slugify=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");Y.nl2br=e=>String(e??"").replace(/&/g,"&").replace(//g,">").replace(/\n/g,"
");Y.encodeUri=e=>encodeURIComponent(String(e??""));var pi=(e,t=0)=>{let n=Math.floor(Number(e));return isNaN(n)?t:n<0?0:n>100?100:n};Y.number=(e,t=0)=>{let n=Number(e);if(isNaN(n))return e;let r=pi(t);return n.toLocaleString(void 0,{minimumFractionDigits:r,maximumFractionDigits:r})};Y.currency=(e,t="USD")=>{let n=Number(e);if(isNaN(n))return e;try{return n.toLocaleString(void 0,{style:"currency",currency:t})}catch{return`${t} ${n.toFixed(2)}`}};Y.percent=(e,t=0)=>{let n=Number(e);return isNaN(n)?e:(n*100).toFixed(pi(t))+"%"};Y.filesize=e=>{let t=Number(e);if(isNaN(t))return e;let n=["B","KB","MB","GB","TB"],r=t<0?"-":"",i=0,o=Math.abs(t);for(;o>=1024&&i0?1:0)+" "+n[i]};Y.ordinal=e=>{let t=Number(e);if(isNaN(t))return e;let n=["th","st","nd","rd"],r=t%100;return t+(n[(r-20)%10]||n[r]||n[0])};Y.count=e=>Array.isArray(e)?e.length:0;Y.first=e=>Array.isArray(e)?e[0]:e;Y.last=e=>Array.isArray(e)?e[e.length-1]:e;Y.join=(e,t=", ")=>Array.isArray(e)?e.join(t):e;Y.reverse=e=>Array.isArray(e)?[...e].reverse():e;Y.unique=e=>Array.isArray(e)?[...new Set(e)]:e;Y.pluck=(e,t)=>Array.isArray(e)?e.map(n=>n?.[t]):e;Y.sortBy=(e,t)=>{if(!Array.isArray(e))return e;let n=t?.startsWith("-"),r=n?t.slice(1):t,i=o=>o==null||typeof o=="number"&&isNaN(o);return[...e].sort((o,s)=>{let a=o?.[r],l=s?.[r],u=i(a),d=i(l);if(u&&d)return 0;if(u)return 1;if(d)return-1;let p=al?1:0;return n?-p:p})};Y.where=(e,t,n)=>Array.isArray(e)?e.filter(r=>r?.[t]===n):e;var wo=/^\d{4}-\d{2}-\d{2}$/,wn=e=>typeof e=="string"&&wo.test(e)?new Date(e+"T00:00:00"):new Date(e);Y.date=(e,t="short")=>{let n=wn(e);if(isNaN(n))return e;let r=t==="long"?{dateStyle:"long"}:t==="full"?{dateStyle:"full"}:{dateStyle:"short"};return n.toLocaleDateString(void 0,r)};Y.datetime=e=>{let t=wn(e);return isNaN(t)?e:t.toLocaleString()};Y.relative=e=>{let t=wn(e);if(isNaN(t))return e;let n=(Date.now()-t.getTime())/1e3;return n<0?Y.fromNow(e):n<60?"just now":n<3600?Math.floor(n/60)+"m ago":n<86400?Math.floor(n/3600)+"h ago":n<2592e3?Math.floor(n/86400)+"d ago":t.toLocaleDateString()};Y.fromNow=e=>{let t=wn(e);if(isNaN(t))return e;let n=(t.getTime()-Date.now())/1e3;return n<0?Y.relative(e):n<60?"in a moment":n<3600?"in "+Math.floor(n/60)+"m":n<86400?"in "+Math.floor(n/3600)+"h":"in "+Math.floor(n/86400)+"d"};Y.default=(e,t="")=>e==null||e===""?t:e;Y.json=(e,t=2)=>JSON.stringify(e,null,t);Y.debug=e=>(console.log("[No.JS debug]",e),e);Y.keys=e=>e&&typeof e=="object"?Object.keys(e):[];Y.values=e=>e&&typeof e=="object"?Object.values(e):[];_e();_e();var mi=["foreach","each","for","from","filter","sort","limit","offset","key","index","template","animate-enter","animate-leave","animate-stagger","animate-duration","animate","get","post","put","patch","delete","page-title","page-description","page-canonical","page-jsonld","else-if"];function vo(e,t){for(let n=0;n>1;e[t[u]]0&&(n[o]=t[a-1]),t[a]=o}let r=new Set,i=t.length?t[t.length-1]:-1;for(;i!==-1;)r.add(i),i=n[i];return r}function nr(e,t,n,r){t&&(e.classList.add(t),e.addEventListener("animationend",()=>e.classList.remove(t),{once:!0}),n&&(e.style.animationDelay=r*n+"ms"))}var rr={priority:10,init(e,t,n){let r=B(e),i,o,s=n.match(/^(\w+)\s+in\s+(\S+)$/);if(s)[,i,o]=s;else{let C=e.getAttribute("from");if(!C||!/^\w+$/.test(n))return;i=n,o=C,console.warn(`[NoJS] "${t}" with "from" is deprecated. Use ${t}="${i} in ${o}" instead.`)}let a=e.getAttribute("index")||"$index",l=e.hasAttribute("if")||e.hasAttribute("else-if"),u=l?null:e.getAttribute("else"),d=e.getAttribute("filter"),p=e.getAttribute("sort"),y=parseInt(e.getAttribute("limit"))||1/0,v=parseInt(e.getAttribute("offset"))||0,I=e.getAttribute("template"),T=e.getAttribute("key"),$=e.getAttribute("animate-enter")||e.getAttribute("animate"),J=e.getAttribute("animate-leave"),me=parseInt(e.getAttribute("animate-stagger"))||0,x=parseInt(e.getAttribute("animate-duration"))||0,m=null,b=null,A=!1,_=!1,E=!!(d||p||v),L=e.parentNode,c=document.createComment("foreach"),f=document.createComment("/foreach");L.insertBefore(c,e),L.insertBefore(f,e.nextSibling),L.removeChild(e);let h=new Map,N=null,P=null,ne=0,O=-1;function D(){if(N&&(P.registryVersion!==Kt&&(P=er(N)),!I||O===ne))return;O=ne;let C=I?document.getElementById(I):null;N=e.cloneNode(!0),vo(N,!l),C&&(N.innerHTML="",N.appendChild(C.content.cloneNode(!0))),P=er(N)}function K(C){D();let V=N.cloneNode(!0);return V.__ctx=te(C,r),V}function z(C){oi(C,P)}function ge(){ne++;let C=/[\[\]()\s+\-*\/!?:&|]/.test(o)?R(o,r):Rt(o,r);Array.isArray(C)||(C=[]);let V=vn(c,f);if(!A&&C===m&&C.length>0&&V.length>0){for(let W of V)W.__ctx&&W.__ctx.$notify&&W.__ctx.$notify();return}if(m=C,d){let W={[i]:void 0,[a]:0},re=te(W,r),Ae=re.__raw;C=C.filter((G,k)=>(Ae[i]=G,Ae[a]=k,delete Ae.__collectKeysCache,!!R(d,re)))}if(p){let W=p.startsWith("-"),re=W?p.slice(1):p;C=[...C].sort((Ae,G)=>{let k=Rt(re,Ae)??Ae?.[re],Ne=Rt(re,G)??G?.[re],q=k==null||typeof k=="number"&&Number.isNaN(k),F=Ne==null||typeof Ne=="number"&&Number.isNaN(Ne);if(q||F)return q&&F?0:q?1:-1;let ae=kNe?1:0;return W?-ae:ae})}if(C=C.slice(v,v+y),C.length===0&&u){if(A){b=null;return}Vt(c,f),h.clear();let W=Se(u);if(W){L.insertBefore(W,f);let re=c.nextSibling;for(;re&&re!==f;)re.nodeType===1&&Q(re),re=re.nextSibling;A=!0}else _||(_=!0,w(`${t}: else template "${u}" not found`,e));b=null;return}if(C.length===0){Vt(c,f),h.clear(),A=!1,b=null;return}if(A=!1,T){U(C,C.length),b=null;return}function be(){if(E||!b)return!1;let W=b.length,re=C.length;if(re<=W)return!1;let Ae=vn(c,f);if(Ae.length!==W)return!1;for(let q=0;q0){let W=Oe.length;Oe.forEach(re=>{re.classList.add(J);let Ae=()=>{re.classList.remove(J),W--,W<=0&&Re()};re.addEventListener("animationend",Ae,{once:!0}),setTimeout(Ae,x||0)})}else be()||Re()}let Le=null;if(T){let C=T.match(/^(\w+)\.(\w+)$/);C&&C[1]===i&&!["__proto__","constructor","prototype"].includes(C[2])&&(Le=C[2])}function U(C,V){h.size===0&&Vt(c,f);let be;if(Le){be=new Array(C.length);for(let F=0;F(we[i]=et,we[a]=xe,delete we.__collectKeysCache,{key:R(T,ae),item:et,i:xe}))}let Re=new Set(be.map(F=>F.key)),Oe=!1;for(let F of h.keys())if(Re.has(F)){Oe=!0;break}if(!Oe&&h.size>0)Vt(c,f),h.clear();else for(let[F,ae]of h)Re.has(F)||(He(ae,!0),ae.remove(),h.delete(F));let W=null,re=null;if(be.forEach(({key:F,item:ae,i:we})=>{let et=h.get(F);if(et){let xe=et.__ctx.__raw;(xe[i]!==ae||xe[a]!==we||xe.$count!==V)&&(xe[i]=ae,xe[a]=we,xe.$index=we,xe.$count=V,xe.$first=we===0,xe.$last=we===V-1,xe.$even=we%2===0,xe.$odd=we%2!==0,delete xe.__collectKeysCache),et.__ctx.$notify()}else{let xe=K({[i]:ae,[a]:we,$index:we,$count:V,$first:we===0,$last:we===V-1,$even:we%2===0,$odd:we%2!==0});h.set(F,xe),W||(W=document.createDocumentFragment(),re=[]),W.appendChild(xe),re.push({clone:xe,i:we})}}),W){L.insertBefore(W,f);for(let F=0;F=0;F--){let ae=h.get(be[F].key);!Ne.has(F)&&ae.nextSibling!==q&&L.insertBefore(ae,q),q=ae}}let ye=he;ct(L),ue(o,r,ge),ge(),ct(ye)}};H("foreach",rr);H("each",rr);H("for",rr);H("state",{priority:0,init(e,t,n){let r=R(n,te())||{},o=e.__ctx||(e.parentElement?B(e.parentElement):null),s=te(r,o);e.__ctx=s;let a=e.getAttribute("persist"),l=e.getAttribute("persist-key");if(a&&!l){w(`persist="${a}" requires a persist-key attribute. State will not be persisted.`);return}if(a&&l){let u=a==="localStorage"?localStorage:a==="sessionStorage"?sessionStorage:null;if(u){let d=e.getAttribute("persist-fields"),p=d?new Set(d.split(",").map(J=>J.trim())):null,y="nojs_"+(g.appId||"")+"state_"+l;try{let J=u.getItem(y);if(J){let me=JSON.parse(J),x=e.hasAttribute("persist-schema"),m=new Set(["__proto__","constructor","prototype"]);for(let[b,A]of Object.entries(me))if(!m.has(b)&&!b.startsWith("__")&&(!p||p.has(b))){if(x){if(!(b in r)){w('persist-schema: ignoring unknown key "'+b+'"');continue}if(r[b]!==null&&A!==null&&typeof A!=typeof r[b]){w('persist-schema: type mismatch for "'+b+'" (expected '+typeof r[b]+", got "+typeof A+")");continue}}s.$set(b,A)}}}catch{}let v=["token","password","secret","key","auth","credential","session"],T=Object.keys(r).filter(J=>v.some(me=>J.toLowerCase().includes(me)));T.length>0&&w("State key(s) "+T.map(J=>'"'+J+'"').join(", ")+" may contain sensitive data. Consider using persist-fields to exclude them.");let $=s.$watch(()=>{try{let J=s.__raw,me=Object.fromEntries(Object.entries(J).filter(([x])=>!x.startsWith("__")&&(!p||p.has(x))));u.setItem(y,JSON.stringify(me))}catch{}});M(()=>{$&&$()})}}ee("state",r)}});H("store",{priority:0,init(e,t,n){let r=e.getAttribute("value");if(n){if(!le[n]){let i=r?R(r,te())||{}:{};le[n]=te(i),Te("store:created",{name:n,keys:Object.keys(i)})}ee("store",n)}}});H("computed",{priority:2,gated:!0,init(e,t,n){if(ze(e))return;let r=e.getAttribute("expr");if(!n||!r)return;let i=B(e);function o(){let s=R(r,i);i.$set(n,s)}ue(r,i,o),o()}});H("watch",{priority:2,gated:!0,init(e,t,n){if(ze(e))return;let r=B(e),i=e.getAttribute("on:change"),o=R(n,r);ue(n,r,()=>{let s=R(n,r);if(s!==o){let a=o;o=s,i&&ke(i,r,{$old:a,$new:s})}})}});_e();var So=["get","post","put","patch","delete","query"];function hi(){let e=document.createElement("div");return e.setAttribute("data-nojs-sentinel",""),e.setAttribute("aria-hidden","true"),e.style.height="0",e.style.overflow="hidden",e.style.pointerEvents="none",e}function Ao(e){let t=e.parentElement;for(;t&&t!==document.documentElement;){let n=getComputedStyle(t).overflowY;if(n==="scroll"||n==="auto")return t;t=t.parentElement}return document.documentElement}for(let e of So)H(e,{priority:1,gated:!0,init(t,n,r){if(ze(t)){w(`${n}: HTTP verb directive on a loop element is not supported \u2014 move the fetch to a parent or child element`,t);return}let i=t.getAttribute("as")||"data",o=t.getAttribute("loading"),s=t.getAttribute("error"),a=t.getAttribute("empty"),l=t.getAttribute("success"),u=t.getAttribute("then"),d=t.getAttribute("redirect"),p=t.getAttribute("confirm"),y=250,v=parseInt(t.getAttribute("refresh"))||0,I=v>0?Math.max(v,y):0,T=t.getAttribute("cached"),$=t.hasAttribute("cached")?T||"memory":"none",J=t.getAttribute("body"),me=t.getAttribute("headers"),x=t.getAttribute("var"),m=t.getAttribute("into"),b=parseInt(t.getAttribute("retry"))||g.retries,A=parseInt(t.getAttribute("retry-delay"))||g.retryDelay||1e3,_=t.getAttribute("params"),E=t.getAttribute("skeleton"),L=e==="query"?"query":"get",c=t.getAttribute(`${L}-trigger`),f=t.getAttribute(`${L}-trigger-label`)||"Load More",h=e==="get"||e==="query"&&t.tagName!=="FORM",N=e==="get"||e==="query",P=e==="get"&&t.hasAttribute("get-cursor"),ne=P&&t.getAttribute("get-cursor-field")||null,O=e==="get"&&t.hasAttribute("get-page"),D=O?parseInt(t.getAttribute("get-page"),10)||1:null;P&&O&&w("get-cursor and get-page are mutually exclusive; using cursor-based pagination");let z=t.getAttribute(`${L}-threshold`)||(c==="scroll"?"200px":"0px"),ge=e==="get"?t.getAttribute("get-insert"):null,Le=e==="get"&&t.hasAttribute("get-insert")?ge==="prepend"?"prepend":"append":"replace",U=Le!=="replace",ye=t.parentElement?B(t.parentElement):te(),C=t.__ctx||te({},ye);t.__ctx=C,P?C.$set("cursor",""):O&&C.$set("page",D);let V=c==="scroll"||c==="button",be=!1,Re=!1,Oe=null,W=null;V&&!U&&w(`get-trigger="${c}" requires get-insert to be set. Falling back to "${c==="scroll"?"visible":"immediate"}" behavior.`);let re=V&&U&&I>0;re&&w(`get-trigger="${c}" is mutually exclusive with refresh. The refresh interval is being ignored.`);let Ae=[...t.childNodes].map(S=>S.cloneNode(!0)),G=null;M(()=>{G&&G.abort(),G=null});let k=null,Ne=0,q=!0;function F(){k&&k.parentNode&&k.parentNode.removeChild(k);let S=++Ne;k=hi(),Le==="append"?t.appendChild(k):t.insertBefore(k,t.firstChild),M(()=>{S===Ne&&(k&&k.parentNode&&k.parentNode.removeChild(k),k=null)})}U&&F();function ae(){if(!E)return;let S=document.getElementById(E);S&&S.style.removeProperty("display")}function we(){if(!E)return;let S=document.getElementById(E);S&&(S.style.display="none")}function et(){if(t.tagName!=="FORM")return;if(t.__nojsResetSubmitting){t.__nojsResetSubmitting();return}let S=B(t),j=S?.$form;j&&(j.submitting=!1,S.$set("$form",{...j}))}function xe(){for(let S of[...t.children])He(S);k&&k.parentNode&&k.parentNode.removeChild(k),k=null,t.innerHTML="",q=!0,F()}function bi(S,j){let oe=j.split("."),Fe=S;for(let X of oe){if(Fe==null||typeof Fe!="object")return;if(je[X]){w("Blocked access to forbidden property '"+X+"' in get-cursor-field");return}Fe=Fe[X]}return Fe}let wi=["cursor","next_cursor","nextCursor","next"];function vi(S,j){if(j&&j.headers){let oe=j.headers.get("X-NoJS-Cursor");if(oe!=null)return oe||null}if(S!=null&&typeof S=="object"&&!Array.isArray(S)){if(ne){let oe=bi(S,ne);return oe!==void 0&&oe||null}for(let oe of wi){let Fe=S[oe];if(Fe!=null&&Fe!=="")return Fe}}return null}function Ei(S){if(Array.isArray(S))return S;if(S!=null&&typeof S=="object"){for(let j of Object.keys(S))if(Array.isArray(S[j]))return S[j]}return S}async function ve(){if(V&&U&&be)return;G&&G.abort(),G=new AbortController;let S=G;if(p&&!window.confirm(p)){et();return}V&&U&&(be=!0),c==="button"&&U&&!q&&Xt(),ae();let j=Ge(r,C);if(_){let X=R(_,C);if(X&&typeof X=="object"){let Ce=new URLSearchParams;for(let[Pe,Ie]of Object.entries(X))if(Ie!=null)if(Array.isArray(Ie))for(let $e of Ie)$e!=null&&Ce.append(Pe,typeof $e=="object"?JSON.stringify($e):String($e));else typeof Ie=="object"?Ce.append(Pe,JSON.stringify(Ie)):Ce.append(Pe,String(Ie));let Ee=Ce.toString();if(Ee){let Pe=j.includes("?")?"&":"?";j+=Pe+Ee}}}let oe="";e==="query"&&(t.tagName==="FORM"?oe=JSON.stringify(Object.fromEntries(new FormData(t).entries())):J&&(oe=Ge(J,C)));let Fe=e+":"+j+(oe?":"+oe:"");if(N){let X=Kr(Fe,$);if(X!=null){we(),C.$set(i,X),Ue(t),Q(t);return}}if(o){let X=Se(o);X&&(U&&!q?Si(X):(se(t),t.innerHTML="",t.appendChild(X),Q(t)))}try{let X=null;if(J){let ie=Ge(J,C);try{X=JSON.parse(ie)}catch{X=ie}}if(t.tagName==="FORM"){let ie=new FormData(t);X=Object.fromEntries(ie.entries())}let Ce=me?JSON.parse(me):{};if(me)for(let ie of Object.keys(Ce)){let dt=ie.toLowerCase();(At.has(dt)||/^x-(auth|api)-/.test(dt))&&w(`Sensitive header "${ie}" is set inline on a headers attribute. Use NoJS.config({ headers }) or an interceptor to avoid exposing credentials in HTML source.`)}let Ee={},Pe=await mn(j,e,X,Ce,t,G.signal,b,A,Ee),Ie=null,$e=Pe;P&&(Ie=vi(Pe,Ee),(Ee.headers&&Ee.headers.get("X-NoJS-Cursor"))==null&&($e=Ei(Pe))),N&&Vr(Fe,P?$e:Pe,$);let Be=P?$e:Pe,lr=Be==null||Array.isArray(Be)&&Be.length===0||Be==="",ur=Ee.headers&&Ee.headers.get("X-NoJS-Last-Page")==="true",fr=P&&Ie==null,Uo=lr||ur||fr;if(lr){if(we(),P&&C.$set("cursor",""),V&&U&&sr(),a){let ie=Se(a);ie&&(U&&!q?(Sn(),Gt(ie),Q(ie)):(se(t),t.innerHTML="",t.appendChild(ie),Q(t)))}return}if(we(),P&&C.$set("cursor",Ie||""),U&&!q){let ie=C[i];if(Array.isArray(ie)&&Array.isArray(Be)){let dt=Le==="append"?[...ie,...Be]:[...Be,...ie];C.$set(i,dt)}else C.$set(i,Be)}else C.$set(i,Be);if(m&&(le[m]||(le[m]=te({})),le[m].$set(i,Be),it(m)),U&&!q){Sn();let ie=document.createElement("div");ie.style.display="contents";let dt=te({[i]:Be},C);ie.__ctx=dt;for(let at of Ae)ie.appendChild(at.cloneNode(!0));if(Le==="prepend"){let at=Ao(t),xn=at.scrollTop,pt=at.scrollHeight;k&&k.nextSibling?t.insertBefore(ie,k.nextSibling):t.appendChild(ie),Q(ie);let Ci=at.scrollHeight;at.scrollTop=xn+(Ci-pt)}else k?t.insertBefore(ie,k):t.appendChild(ie),Q(ie);q=!1}else{if(l){let ie=Se(l);if(ie){se(t),t.innerHTML="";let at=document.getElementById(l.replace("#",""))?.getAttribute("var")||x||"result",xn=te({[at]:Be},C),pt=document.createElement("div");pt.style.display="contents",pt.__ctx=xn,pt.appendChild(ie),t.appendChild(pt),Q(pt)}}else{se(t),t.innerHTML="";for(let ie of Ae)t.appendChild(ie.cloneNode(!0));Ue(t),Q(t)}if(U){q=!1,k&&k.parentNode&&k.parentNode.removeChild(k);let ie=++Ne;k=hi(),Le==="append"?t.appendChild(k):t.insertBefore(k,t.firstChild),M(()=>{ie===Ne&&(k&&k.parentNode&&k.parentNode.removeChild(k),k=null)})}}O&&!P&&V&&U&&C.$set("page",C.page+1),(ur||fr)&&V&&U?sr():V&&U&&!Re&&xi(),u&&ke(u,C,{result:Be}),d&&de&&de.push(d),Ke("fetch:success",{url:j,data:Be}),Te("fetch:success",{method:e,url:j})}catch(X){if(X.name==="AbortError")return;if(we(),w(`${e.toUpperCase()} ${j} failed:`,X.message),Ke("fetch:error",{url:j,error:X}),Ke("error",{url:j,error:X}),Te("fetch:error",{method:e,url:j,error:X.message}),s){let Ce=Se(s);if(Ce){let Pe=document.getElementById(s.replace("#",""))?.getAttribute("var")||"err",Ie=te({[Pe]:{message:X.message,status:X.status,body:X.body}},C),$e=document.createElement("div");$e.style.display="contents",$e.__ctx=Ie,$e.appendChild(Ce),U&&!q?(Sn(),Ai(),$e.setAttribute("data-nojs-inline-error",""),Gt($e)):(se(t),t.innerHTML="",t.appendChild($e)),Q($e)}}}finally{V&&U&&(be=!1),t.tagName==="FORM"&&e!=="get"&&!S.signal.aborted&&G===S&&et()}}function Si(S){let j=document.createElement("div");j.style.display="contents",j.setAttribute("data-nojs-inline-loading",""),j.appendChild(S),Gt(j),Q(j)}function Sn(){let S=t.querySelector("[data-nojs-inline-loading]");S&&(He(S),S.parentNode.removeChild(S))}function Ai(){let S=t.querySelector("[data-nojs-inline-error]");S&&(He(S),S.parentNode.removeChild(S))}function Gt(S){Le==="append"&&k?t.insertBefore(S,k):Le==="prepend"&&k&&k.nextSibling?t.insertBefore(S,k.nextSibling):t.appendChild(S)}function sr(){Re=!0,Oe&&(Oe.disconnect(),Oe=null),Xt(),k&&k.parentNode&&k.parentNode.removeChild(k),k=null,Ke("fetch:end",{url:r})}function xi(){c==="button"&&ar(),c==="scroll"&&(Oe?k&&Oe.observe(k):cr())}function ar(){Xt();let S=document.createElement("button");S.setAttribute("data-nojs-load-more",""),S.setAttribute("type","button"),S.setAttribute("aria-label",f),S.textContent=f,W=S;let j=()=>{Re||be||ve()};S.addEventListener("click",j),M(()=>{S.removeEventListener("click",j)}),Gt(S)}function Xt(){W&&W.parentNode&&W.parentNode.removeChild(W),W=null;let S=t.querySelector("[data-nojs-load-more]");S&&S.parentNode&&S.parentNode.removeChild(S)}function cr(){if(typeof IntersectionObserver>"u"){w('IntersectionObserver not available, get-trigger="scroll" falling back to button trigger'),ar();return}Oe=new IntersectionObserver(S=>{for(let j of S)if(j.isIntersecting&&t.isConnected&&!Re&&!be){ve();break}},{rootMargin:z}),k&&Oe.observe(k),M(()=>{Oe&&(Oe.disconnect(),Oe=null)})}function An(){Re=!1,be=!1,P?C.$set("cursor",""):O&&C.$set("page",D),Xt(),xe(),c==="scroll"&&k&&(Oe&&Oe.disconnect(),Oe=null,cr())}if(t.tagName==="FORM"&&e!=="get"){let S=j=>{j.preventDefault(),ve()};t.addEventListener("submit",S),M(()=>t.removeEventListener("submit",S))}else if(h){if(c!=="none")if(c==="visible")if(typeof IntersectionObserver<"u"){let S=new IntersectionObserver(j=>{for(let oe of j)if(oe.isIntersecting&&t.isConnected){S.disconnect(),ve();break}},{rootMargin:z});S.observe(t),M(()=>S.disconnect())}else w('IntersectionObserver not available, get-trigger="visible" falling back to immediate fetch'),queueMicrotask(()=>{t.isConnected&&ve()});else if(c==="scroll"&&U)queueMicrotask(()=>{t.isConnected&&ve()});else if(c==="scroll"&&!U)if(typeof IntersectionObserver<"u"){let S=new IntersectionObserver(j=>{for(let oe of j)if(oe.isIntersecting&&t.isConnected){S.disconnect(),ve();break}},{rootMargin:z});S.observe(t),M(()=>S.disconnect())}else queueMicrotask(()=>{t.isConnected&&ve()});else if(c==="button"&&U)queueMicrotask(()=>{t.isConnected&&ve()});else if(c==="button"&&!U)queueMicrotask(()=>{t.isConnected&&ve()});else if(c==="hover"){let S=I<=0,j=()=>{ve()};S?t.addEventListener("mouseenter",j,{once:!0}):t.addEventListener("mouseenter",j),M(()=>t.removeEventListener("mouseenter",j))}else queueMicrotask(()=>{t.isConnected&&ve()})}else{let S=j=>{j.preventDefault(),ve()};t.addEventListener("click",S),M(()=>t.removeEventListener("click",S))}if(/\{[^}]+\}/.test(r)&&c!=="none"){let Ee=function(){let Ie=Ge(r,C);if(Ie!==j){if(j=Ie,V&&U&&X){let $e=Ge(X,C);if($e!==Ce){Ce=$e,oe&&clearTimeout(oe),S>0?oe=setTimeout(()=>{An(),ve()},S):(An(),ve());return}}oe&&clearTimeout(oe),S>0?oe=setTimeout(ve,S):ve()}},S=parseInt(t.getAttribute("debounce"))||0,j=Ge(r,C),oe=null,Fe=O||P,X=P?r.replace(/\{cursor\}/g,"__CURSOR__"):O?r.replace(/\{page\}/g,"__PAGE__"):null,Ce=X?Ge(X,C):null;M(()=>{oe&&clearTimeout(oe)});let Pe=ye;for(;Pe&&Pe.__isProxy;){let Ie=Pe.$watch(Ee);M(Ie),Pe=Pe.$parent}if(r.includes("$store")){let Ie=Ft(r)||"*";In(Ee,Ie),Ee._el=he,M(()=>xt(Ee))}r.includes("$route")&&(kn(Ee),Ee._el=he,M(()=>Ht(Ee))),r.includes("$i18n")&&(gt(Ee),Ee._el=he,M(()=>We.delete(Ee)))}if(_&&c!=="none"){let Fe=function(){let Ce="";try{let Ee=R(_,C);Ce=JSON.stringify(Ee)||""}catch{return}Ce!==j&&(j=Ce,oe&&clearTimeout(oe),S>0?oe=setTimeout(ve,S):ve())},S=parseInt(t.getAttribute("debounce"))||0,j="";try{let Ce=R(_,C);j=JSON.stringify(Ce)||""}catch{}let oe=null;M(()=>{oe&&clearTimeout(oe)});let X=ye;for(;X&&X.__isProxy;){let Ce=X.$watch(Fe);M(Ce),X=X.$parent}}if(V&&U?t.refresh=function(){An(),ve()}:U?t.refresh=function(){xe(),ve()}:t.refresh=ve,M(()=>{delete t.refresh}),I>0&&!re){let S=setInterval(()=>{if(!t.isConnected){clearInterval(S);return}ve()},I);M(()=>clearInterval(S))}}});_e();H("bind",{priority:20,gated:!0,init(e,t,n){let r=B(e),i;function o(){let s=R(n,r),a=s!=null?String(s):"";a!==i&&(i=a,e.textContent=a)}ue(n,r,o),o()}});H("bind-html",{priority:20,gated:!0,init(e,t,n){let r=B(e);(g.debug||g.devtools)&&!/^['"`]/.test(n.trim())&&w(`[Security] bind-html used with dynamic expression: "${n}". Ensure the value is trusted or sanitized \u2014 use bind for plain text.`,e);let i;function o(){let s=R(n,r);if(s!=null){let a=String(s);if(a===i)return;i=a,se(e),e.innerHTML=hn(a)}}ue(n,r,o),o()}});var xo=new Set(["href","src","action","formaction","poster","data"]);function gi(e){let n=new DOMParser().parseFromString(e,"image/svg+xml").documentElement;if(n.querySelector("parsererror")||n.nodeName!=="svg"||n.getElementsByTagNameNS("http://www.mozilla.org/newlayout/xml/parsererror.xml","parsererror").length)return"";function r(i){for(let o of[...i.attributes]){let s=o.name.toLowerCase();if(s.startsWith("on")){i.removeAttribute(o.name);continue}if(s==="href"||s==="xlink:href"){let a=o.value.toLowerCase().replace(/[\u0000-\u0020]/g,"");/^(javascript|vbscript):/.test(a)&&i.removeAttribute(o.name)}}}for(let i of[...n.querySelectorAll("script")])i.remove();r(n);for(let i of n.querySelectorAll("*"))r(i);return new XMLSerializer().serializeToString(n)}function Co(e){try{let t=e.match(/^data:image\/svg\+xml;base64,(.+)$/i);if(t){let o=gi(atob(t[1]));return"data:image/svg+xml;base64,"+btoa(o)}let n=e.indexOf(",");if(n===-1)return"#";let r=e.slice(0,n+1),i=gi(decodeURIComponent(e.slice(n+1)));return r+encodeURIComponent(i)}catch{return"#"}}function To(e,t){if(xo.has(e)){let n=String(t).trimStart(),r=n.toLowerCase().replace(/[\u0000-\u0020]/g,"");if(/^(javascript|vbscript):/.test(r))return"#";if(/^data:/.test(r)){if(/^data:image\/svg\+xml/.test(r))return Co(n);if(!/^data:image\//.test(r))return"#"}}return t}var Lo=new Set(["disabled","readonly","checked","selected","hidden","required"]);H("bind-*",{priority:20,init(e,t,n){let r=t.replace("bind-",""),i=B(e);if(r==="value"&&(e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.tagName==="SELECT")){let a=()=>{let l;if(e.type==="number"){if(e.value===""||isNaN(e.valueAsNumber))return;l=e.valueAsNumber}else l=e.value;ke(`${n} = __val`,i,{__val:l})};e.addEventListener("input",a),M(()=>e.removeEventListener("input",a))}let o;function s(){let a=R(n,i);if(Lo.has(r)){let u=!!a,d=r in e?!!e[r]:e.hasAttribute(r);if(u===o&&d===u)return;o=u,u?e.setAttribute(r,""):e.removeAttribute(r),r in e&&(e[r]=u);return}let l=a!=null?String(To(r,a)):null;l===o&&e.getAttribute(r)===l||(o=l,l!=null?e.setAttribute(r,l):e.removeAttribute(r))}ue(n,i,s),s()}});H("model",{priority:20,gated:!0,init(e,t,n){let r=B(e),i=e.tagName,o=e.type;function s(){let u=R(n,r);if(i==="INPUT"&&o==="checkbox")e.checked=!!u;else if(i==="INPUT"&&o==="radio")e.checked=e.value===String(u);else if(i==="SELECT")e.value=u!=null?String(u):"";else{let d=u!=null?String(u):"";if(document.activeElement===e){if(o==="number"||o==="range"){let p=e.valueAsNumber;if(u!=null&&!isNaN(p)&&p===Number(u))return}else if(e.value===d)return}e.value=d}}let a=i==="SELECT"||o==="checkbox"||o==="radio"?"change":"input",l=()=>{let u;o==="checkbox"?u=e.checked:o==="number"||o==="range"?u=Number(e.value):u=e.value,ke(`${n} = __val`,r,{__val:u})};e.addEventListener(a,l),M(()=>e.removeEventListener(a,l)),ue(n,r,s),s()}});_e();function _i(e){let t=[],n=e.previousElementSibling;for(;n;){let r=n.getAttribute("if")||n.getAttribute("else-if");if(r)t.push(r);else break;n=n.previousElementSibling}return t}H("if",{priority:10,init(e,t,n){let r=B(e),i=e.getAttribute("then"),o=e.getAttribute("else"),s=e.getAttribute("animate-enter")||e.getAttribute("animate"),a=e.getAttribute("animate-leave"),l=e.getAttribute("transition"),u=parseInt(e.getAttribute("animate-duration"))||0,d=(e.__i18nSavedChildren||[...e.childNodes]).map(T=>T.cloneNode(!0)),p,y=null;M(()=>{y&&(y(),y=null)});function v(){let T=!!R(n,r);T!==p&&(p=T,a||l?(y&&(y(),y=null),y=yn(e,a,l,()=>{y=null,I(T)},u)):I(T))}function I(T){if(e.__ifState=T,T||ai(e),se(e),T)if(i){let $=Se(i);$&&(e.innerHTML="",e.appendChild($))}else{e.innerHTML="";for(let $ of d)e.appendChild($.cloneNode(!0))}else if(o){let $=Se(o);$&&(e.innerHTML="",e.appendChild($))}else e.innerHTML="";Ue(e),Q(e),T&&si(e),(s||l)&&St(e,s,l,u)}ue(n,r,v),v()}});H("else-if",{priority:10,init(e,t,n){if(ze(e))return;let r=B(e),i=e.getAttribute("then"),o=[...e.childNodes].map(u=>u.cloneNode(!0)),s;function a(){let u=e.previousElementSibling;for(;u;){let y=u.getAttribute("if")||u.getAttribute("else-if");if(y){if(R(y,r)){if(s==="hidden")return;s="hidden",se(e),e.innerHTML="",e.style.display="none";return}}else break;u=u.previousElementSibling}let d=!!R(n,r),p=d?"shown":"hidden";if(p!==s)if(s=p,e.style.display="",d){if(i){let y=Se(i);y&&(se(e),e.innerHTML="",e.appendChild(y))}else{se(e),e.innerHTML="";for(let y of o)e.appendChild(y.cloneNode(!0))}Ue(e),Q(e)}else se(e),e.innerHTML=""}let l=_i(e);l.push(n),ue(l.join(" "),r,a),a()}});H("else",{priority:10,init(e){if(e.hasAttribute("if")||ze(e))return;let t=B(e),n=e.getAttribute("then"),r=[...e.childNodes].map(a=>a.cloneNode(!0)),i,o=!1;function s(){let a=e.previousElementSibling,l=!1;for(;a;){let u=a.getAttribute("if")||a.getAttribute("else-if");if(u){if(l=!0,R(u,t)){if(i==="hidden")return;i="hidden",se(e),e.innerHTML="",e.style.display="none";return}}else break;a=a.previousElementSibling}if(!l&&!o&&(o=!0,w('else: no preceding if/else-if sibling found \u2014 note the sibling else pattern for loops was removed in v1.15; use else="templateId" on the loop element',e)),i!=="shown"){if(i="shown",e.style.display="",n){let u=Se(n);u&&(se(e),e.innerHTML="",e.appendChild(u))}else{se(e),e.innerHTML="";for(let u of r)e.appendChild(u.cloneNode(!0))}Ue(e),Q(e)}}ue(_i(e).join(" "),t,s),s()}});H("show",{priority:20,init(e,t,n){let r=B(e),i=e.getAttribute("animate-enter")||e.getAttribute("animate"),o=e.getAttribute("animate-leave"),s=e.getAttribute("transition"),a=parseInt(e.getAttribute("animate-duration"))||0,l;function u(){let d=!!R(n,r);d!==l&&(l=d,d?(e.style.display="",(i||s)&&St(e,i,s,a)):o||s?yn(e,o,s,()=>{e.style.display="none"},a):e.style.display="none")}ue(n,r,u),u()}});H("hide",{priority:20,init(e,t,n){let r=B(e),i=e.getAttribute("animate-enter")||e.getAttribute("animate"),o=e.getAttribute("animate-leave"),s=e.getAttribute("transition"),a=parseInt(e.getAttribute("animate-duration"))||0,l;function u(){let d=!R(n,r);d!==l&&(l=d,d?(e.style.display="",(i||s)&&St(e,i,s,a)):o||s?yn(e,o,s,()=>{e.style.display="none"},a):e.style.display="none")}ue(n,r,u),u()}});H("animate",{priority:15,init(e,t,n){if(e.hasAttribute("if")||e.hasAttribute("show")||e.hasAttribute("hide"))return;let r=e.getAttribute("animate-enter")||n,i=e.getAttribute("transition"),o=parseInt(e.getAttribute("animate-duration"))||0;(r||i)&&St(e,r,i,o,!0)}});function Oo(e){let t=[],n=0,r=null,i=0;for(let o=0;o=0&&e[l]==="\\";l--)a++;a%2===0&&(r=null)}}else s==="'"||s==='"'||s==="`"?r=s:s==="("||s==="["||s==="{"?n++:s===")"||s==="]"||s==="}"?n--:s===","&&n===0&&(t.push(e.slice(i,o)),i=o+1)}return t.push(e.slice(i)),t}H("switch",{priority:10,init(e,t,n){let r=B(e);function i(){let o=R(n,r),s=!1;for(let a of[...e.children]){let l=a.getAttribute("case"),u=a.hasAttribute("default"),d=a.getAttribute("then");if(l){let p=Oo(l).map(y=>R(y.trim(),r));if(!s&&p.includes(o))if(s=!0,a.style.display="",d){let y=Se(d);y&&(se(a),a.innerHTML="",a.appendChild(y)),a.__declared=!1,Q(a)}else a.__switchDisposed&&(a.__switchDisposed=!1,a.__declared=!1,Q(a));else se(a),a.__switchDisposed=!0,a.style.display="none"}else if(u)if(s&&(se(a),a.__switchDisposed=!0),a.style.display=s?"none":"",!s&&d){let p=Se(d);p&&(se(a),a.innerHTML="",a.appendChild(p)),a.__declared=!1,Q(a)}else!s&&a.__switchDisposed&&(a.__switchDisposed=!1,a.__declared=!1,Q(a))}}ue(n,r,i),i()}});_e();_e();H("class-*",{priority:20,init(e,t,n){let r=t.replace("class-",""),i=B(e);if(r==="map"){let a=function(){let l=R(n,i);if(l&&typeof l=="object")for(let[u,d]of Object.entries(l))u.split(/\s+/).filter(Boolean).forEach(y=>e.classList.toggle(y,!!d))};ue(n,i,a),a();return}if(r==="list"){let l=function(){let u=R(n,i);if(Array.isArray(u)){a.forEach(p=>{p&&e.classList.remove(p)});let d=u.filter(Boolean);d.forEach(p=>e.classList.add(p)),a=d}},a=[];ue(n,i,l),l();return}let o=null;function s(){let a=!!R(n,i);a===o&&e.classList.contains(r)===a||(o=a,e.classList.toggle(r,a))}ue(n,i,s),(n.includes("NoJS.locale")||n.includes("window.NoJS.locale"))&>(s),s()}});H("style-*",{priority:20,init(e,t,n){let r=t.replace("style-",""),i=B(e);if(r==="map"){let d=function(){let p=R(n,i);if(p&&typeof p=="object"){let y=Object.keys(p);for(let v of u)v in p||(v.startsWith("--")?e.style.removeProperty(v):e.style[v]="");for(let[v,I]of Object.entries(p))v.startsWith("--")?e.style.setProperty(v,I??""):e.style[v]=I??"";u=y}},u=[];ue(n,i,d),d();return}let o=r.startsWith("--"),s=o?r:r.replace(/-([a-z])/g,(u,d)=>d.toUpperCase()),a;function l(){let u=R(n,i),d=u!=null?String(u):"";d===a&&e.style.getPropertyValue(r)===d||(a=d,o?e.style.setProperty(s,d):e.style[s]=d)}ue(n,i,l),l()}});_e();var No=new Set(["mounted","init","updated","error","unmounted"]);H("on:*",{priority:20,gated:!0,init(e,t,n){let r=B(e);if(t.indexOf(".")===-1&&!e.__gatedDirs){let v=t.slice(3);if(!No.has(v)){let I=$=>ke(n,r,{$event:$,$el:e});e.addEventListener(v,I);let T=()=>e.removeEventListener(v,I);T._elOnly=!0,M(T);return}}let i=t.replace("on:","").split("."),o=i[0],s=new Set(i.slice(1));if(o==="mounted"){requestAnimationFrame(()=>ke(n,r,{$el:e}));return}if(o==="init"){ke(n,r,{$el:e});return}if(o==="updated"){let v=!1,I=new MutationObserver(()=>{if(!e.isConnected){I.disconnect();return}if(!v){v=!0;try{ke(n,r,{$el:e})}finally{Promise.resolve().then(()=>{v=!1})}}});I.observe(e,{childList:!0,subtree:!0,characterData:!0,attributes:!0}),M(()=>I.disconnect());return}if(o==="error"){let v=I=>{(e.contains(I.target)||I.target===e)&&ke(n,r,{$el:e,$error:I.error||I.message})};window.addEventListener("error",v),M(()=>window.removeEventListener("error",v));return}if(o==="unmounted"){let v=new MutationObserver(I=>{for(let T of I)for(let $ of T.removedNodes)if($===e||$.contains?.(e)){ke(n,r,{$el:e}),v.disconnect();return}});e.parentElement&&v.observe(e.parentElement,{childList:!0,subtree:!0}),M(()=>v.disconnect());return}let a=0,l=0,u=i.slice(1);for(let v=0;v{ke(n,r,{$event:v,$el:e})};if(a>0){let v=d,I;d=T=>{clearTimeout(I),I=setTimeout(()=>v(T),a)},M(()=>clearTimeout(I))}if(l>0){let v=d,I=0;d=T=>{let $=Date.now();$-I>=l&&(I=$,v(T))}}let p=v=>{if(o==="keydown"||o==="keyup"||o==="keypress"){let I=["enter","escape","tab","space","delete","backspace","up","down","left","right","ctrl","alt","shift","meta"];for(let T of s)if(I.includes(T)&&(T==="enter"&&v.key!=="Enter"||T==="escape"&&v.key!=="Escape"||T==="tab"&&v.key!=="Tab"||T==="space"&&v.key!==" "||T==="delete"&&v.key!=="Delete"&&v.key!=="Backspace"||T==="backspace"&&v.key!=="Backspace"||T==="up"&&v.key!=="ArrowUp"||T==="down"&&v.key!=="ArrowDown"||T==="left"&&v.key!=="ArrowLeft"||T==="right"&&v.key!=="ArrowRight"||T==="ctrl"&&!v.ctrlKey||T==="alt"&&!v.altKey||T==="shift"&&!v.shiftKey||T==="meta"&&!v.metaKey))return}s.has("prevent")&&v.preventDefault(),s.has("stop")&&v.stopPropagation(),!(s.has("self")&&v.target!==e)&&d(v)},y={};if(s.has("once")&&(y.once=!0),e.addEventListener(o,p,y),!y.once){let v=()=>e.removeEventListener(o,p,y);v._elOnly=!0,M(v)}}});H("trigger",{priority:20,init(e,t,n){let r=B(e),i=e.getAttribute("trigger-data"),o=()=>{let a=i?R(i,r):null;e.dispatchEvent(new CustomEvent(n,{detail:a,bubbles:!0}))};e.addEventListener("click",o);let s=()=>e.removeEventListener("click",o);s._elOnly=!0,M(s)}});_e();H("ref",{priority:5,init(e,t,n){rt[n]=e,M(()=>{rt[n]===e&&delete rt[n]})}});H("use",{priority:9,init(e,t,n){let r=B(e),i=Se(n);if(!i)return;let o={};for(let d of[...e.attributes])if(d.name.startsWith("var-")){let p=d.name.replace("var-","");o[p]=R(d.value,r)}let s=te(o,r),a={};for(let d of[...e.children]){let p=d.getAttribute("slot")||"default";a[p]||(a[p]=document.createDocumentFragment()),a[p].appendChild(d.cloneNode(!0))}let l=i.querySelectorAll("slot");for(let d of l){let p=d.getAttribute("name")||"default";a[p]&&d.replaceWith(a[p])}se(e),e.innerHTML="";let u=document.createElement("div");u.style.display="contents",u.__ctx=s,u.appendChild(i),e.appendChild(u),Q(u)}});H("call",{priority:20,init(e,t,n){let r=B(e),i=e.getAttribute("method")||"get",o=e.getAttribute("as")||"data",s=e.getAttribute("into"),a=e.getAttribute("success"),l=e.getAttribute("error"),u=e.getAttribute("loading"),d=e.getAttribute("then"),p=e.getAttribute("confirm"),y=e.getAttribute("body"),v=e.getAttribute("redirect"),I=e.getAttribute("headers"),T=[...e.childNodes].map(m=>m.cloneNode(!0)),$=null,J=null;function me(){J&&(se(J),J.remove(),J=null)}M(me);let x=async m=>{if(m.preventDefault(),p&&!window.confirm(p))return;$&&$.abort(),$=new AbortController;let b=Ge(n,r);if(u){let A=Se(u);A&&(se(e),e.innerHTML="",e.appendChild(A),Q(e),e.disabled=!0)}try{let A=null;if(y){let L=Ge(y,r);try{A=JSON.parse(L)}catch{A=L}}let _=I?JSON.parse(I):{};if(I)for(let L of Object.keys(_)){let c=L.toLowerCase();(At.has(c)||/^x-(auth|api)-/.test(c))&&w(`Sensitive header "${L}" is set inline on a headers attribute. Use NoJS.config({ headers }) or an interceptor to avoid exposing credentials in HTML source.`)}let E=await mn(b,i,A,_,e,$.signal);if(u){se(e),e.innerHTML="";for(let L of T)e.appendChild(L.cloneNode(!0));Ue(e),Q(e),e.disabled=!1}if(o&&r.$set(o,E),s&&(le[s]||(le[s]=te({})),le[s].$set(o,E),it(s)),d&&ke(d,r,{result:E}),a){let L=Se(a),c=e.closest("[route-view]")||e.parentElement;if(L&&c){let h=document.getElementById(a.replace("#",""))?.getAttribute("var")||"result",N=te({[h]:E},r);me();let P=document.createElement("div");P.style.display="contents",P.__ctx=N,P.appendChild(L),c.appendChild(P),J=P,Q(P)}}v&&de&&de.push(v),Ke("fetch:success",{url:b,data:E}),Te("fetch:success",{method:i,url:b})}catch(A){if(A.name==="AbortError")return;if(w(`call ${i.toUpperCase()} ${b} failed:`,A.message),u){se(e),e.innerHTML="";for(let _ of T)e.appendChild(_.cloneNode(!0));Ue(e),Q(e),e.disabled=!1}if(Ke("fetch:error",{url:b,error:A}),Ke("error",{url:b,error:A}),Te("fetch:error",{method:i,url:b,error:A.message}),l){let _=Se(l),E=e.closest("[route-view]")||e.parentElement;if(_&&E){let c=document.getElementById(l.replace("#",""))?.getAttribute("var")||"err",f=te({[c]:{message:A.message,status:A.status,body:A.body}},r);me();let h=document.createElement("div");h.style.display="contents",h.__ctx=f,h.appendChild(_),E.appendChild(h),J=h,Q(h)}}}};e.addEventListener("click",x),M(()=>e.removeEventListener("click",x))}});_e();var Po=Object.freeze({valid:!0,dirty:!1,touched:!1,error:null,value:""}),Io=new Proxy({},{get:()=>Po});H("validate",{priority:30,init(e,t){w('[NoJS] "validate" has moved to @no-js-dev/nojs-elements. Install the plugin and call NoJS.use(NoJSElements) to enable it.');let n=B(e);n.$form={valid:!1,dirty:!1,touched:!1,submitting:!1,pending:!1,errors:{},values:{},firstError:null,errorCount:0,fields:Io,reset(){}};let r=e.tagName==="FORM"?e:e.closest("form");if(r){let i=o=>{o.preventDefault(),w('[NoJS] Form submission blocked \u2014 "validate" requires @no-js-dev/nojs-elements.')};r.addEventListener("submit",i),M(()=>r.removeEventListener("submit",i))}}});_e();H("error-boundary",{priority:1,init(e,t,n){let r=B(e),i=!1;function o(l){if(i){w("error-boundary: secondary error inside fallback (suppressed to prevent infinite recursion):",l);return}i=!0;try{let u=Se(n);if(u){let d=te({err:{message:l}},r);se(e),e.innerHTML="";let p=document.createElement("div");p.style.display="contents",p.__ctx=d,p.appendChild(u),e.appendChild(p),Q(p)}}finally{i=!1}}let s=l=>{o(l.detail?.message||"An error occurred")};e.addEventListener("nojs:error",s),M(()=>e.removeEventListener("nojs:error",s));let a=l=>{l.target===window?e.isConnected&&o(l.message||"An error occurred"):(e.contains(l.target)||e===l.target)&&o(l.message||"An error occurred")};window.addEventListener("error",a,{capture:!0}),M(()=>window.removeEventListener("error",a,{capture:!0}))}});ot();_e();H("t",{priority:20,gated:!0,init(e,t,n){let r=B(e),i=e.hasAttribute("t-html"),o=[];for(let l of[...e.attributes])l.name.startsWith("t-")&&l.name!=="t"&&l.name!=="t-html"&&o.push(l.value);let s=o.length?n+" "+o.join(" "):n;function a(){let l={};for(let d of[...e.attributes])if(d.name.startsWith("t-")&&d.name!=="t"&&d.name!=="t-html"){let p=d.name.replace("t-","");l[p]=R(d.value,r)??d.value}let u=pe.t(n,l);i?(se(e),e.innerHTML=hn(u)):e.textContent=u}ue(s,r,a),gt(a),a()}});H("i18n-ns",{priority:1,init(e,t,n){if(!n)return;e.__i18nSavedChildren=[...e.childNodes].map(i=>i.cloneNode(!0));let r=document.createDocumentFragment();for(;e.firstChild;)r.appendChild(e.firstChild);Dn(n).then(()=>{if(e.__ifState!==void 0){Tt();return}e.appendChild(r),Q(e),Tt()})}});_e();var $o=e=>`[NoJS] "${e}" has moved to @no-js-dev/nojs-elements. Install the plugin and call NoJS.use(NoJSElements) to enable it.`;for(let e of["drag","drop","drag-list","drag-multiple"])H(e,{priority:e==="drag-multiple"?16:e==="drag-list"?10:15,init(t,n){w($o(n))}});_e();function ko(e,t){return e.replace(/\{\s*([^}"'{\s][^}]*)\}/g,(n,r)=>{try{let i=R(r.trim(),t);return i!=null?String(i):""}catch{return""}})}H("page-title",{priority:1,gated:!0,init(e,t,n){if(ze(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=B(e);function i(){let o=R(n,r);o!=null&&(document.title=String(o))}ue(n,r,i),i()}});H("page-description",{priority:1,gated:!0,init(e,t,n){if(ze(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=B(e),i=!1,o=null;function s(){let a=R(n,r);if(a==null)return;let l=document.querySelector('meta[name="description"]');l||(l=document.createElement("meta"),l.name="description",document.head.appendChild(l),i=!0),o=l,l.content=String(a)}ue(n,r,s),s(),M(()=>{i&&o&&o.isConnected&&o.remove()})}});H("page-canonical",{priority:1,gated:!0,init(e,t,n){if(ze(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=B(e),i=!1,o=null;function s(){let a=R(n,r);if(a==null)return;let l=document.querySelector('link[rel="canonical"]');l||(l=document.createElement("link"),l.rel="canonical",document.head.appendChild(l),i=!0);let u=String(a);/^\s*(javascript|vbscript|data):/i.test(u)||(o=l,l.href=u)}ue(n,r,s),s(),M(()=>{i&&o&&o.isConnected&&o.remove()})}});H("page-jsonld",{priority:1,gated:!0,init(e,t,n){if(ze(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=B(e),i=(e.textContent||e.innerHTML).trim();if(!i)return;let o=!1,s=null;function a(){let l=ko(i,r);if(!l)return;let u=document.querySelector('script[type="application/ld+json"][data-nojs]');u||(u=document.createElement("script"),u.type="application/ld+json",u.setAttribute("data-nojs",""),document.head.appendChild(u),o=!0),s=u,u.textContent=l.replace(/<\//g,"<\\/")}ue(i,r,a),a(),M(()=>{o&&s&&s.isConnected&&s.remove()})}});ni();var Xe=null,ir=!1,Ro=new Set(["store","route","router","i18n","refs","form","parent","watch","set","notify","raw","isProxy","listeners","app","config","env","debug","version","plugins","globals","el","event","self","this","super","window","document","toString","valueOf","hasOwnProperty"]),Do=typeof window<"u"?new Set([eval,Function,window.eval,window.Function].filter(Boolean)):new Set;function yi(e){return Do.has(e)}var jo=new Set(["__proto__","constructor","prototype"]),Mo=new Set(["uppercase","lowercase","capitalize","truncate","trim","stripHtml","slugify","nl","nl2br","encodeUri","number","currency","percent","filesize","ordinal","count","first","last","join","reverse","unique","sortBy","where","pluck","keys","values","json","debug","default","date","datetime","relative","fromNow"]),Fo=new Set(["required","email","url","min","max","minlength","maxlength","pattern","match","number","integer","alpha","alphanumeric"]);function or(e,t=new Set){if(!(!e||typeof e!="object"||t.has(e))){t.add(e);for(let n of Object.keys(e))if(jo.has(n))throw w("NoJS.global(): value contains a forbidden key: "+n),new Error("unsafe_global");for(let n of Object.values(e)){if(yi(n))throw w("NoJS.global(): value contains a forbidden reference (eval/Function)."),new Error("unsafe_global");n&&typeof n=="object"&&or(n,t)}}}function Ho(){return typeof window>"u"?null:(g.router||{}).useHash?window.location.hash.slice(1)||"/":Mt(window.location.pathname)}var Qe={get baseApiUrl(){return g.baseApiUrl},set baseApiUrl(e){g.baseApiUrl=e},get locale(){return pe.locale},set locale(e){pe.locale=e},config(e={}){if(ir){let s=["sanitize","dangerouslyDisableSanitize","sanitizeHtml"];for(let a of s)a in e&&(w(`config.${a} cannot be changed after init()`),delete e[a])}let t={...g.headers},n={...g.cache},r={...g.templates},i={...g.router},o={...g.i18n};if("csp"in e&&(w("csp config option removed \u2014 No.JS is now CSP-safe by default"),delete e.csp),e.exprCacheSize!==void 0){let s=parseInt(e.exprCacheSize);e.exprCacheSize=Number.isFinite(s)&&s>0?s:500}if(Object.assign(g,e),e.sanitize===!1&&w("sanitize:false is deprecated \u2014 use dangerouslyDisableSanitize:true to make the risk explicit."),e.headers&&(g.headers={...t,...e.headers}),e.csrf&&(g.csrf=e.csrf),e.cache&&(g.cache={...n,...e.cache}),e.templates&&(g.templates={...r,...e.templates}),e.router&&("mode"in e.router&&!("useHash"in e.router)&&(ee('router.mode is deprecated. Use router.useHash instead: mode: "hash" \u2192 useHash: true, mode: "history" \u2192 useHash: false',"warn"),e.router.useHash=e.router.mode==="hash",delete e.router.mode),g.router={...i,...e.router}),e.i18n&&(g.i18n={...o,...e.i18n},pe.locale=e.i18n.defaultLocale||pe.locale),e.stores){for(let[s,a]of Object.entries(e.stores))le[s]||(le[s]=te(a||{}),Te("store:created",{name:s,keys:Object.keys(a||{})}));delete g.stores}},use(e,t={}){if(Zt){w("Cannot install plugins during dispose.");return}if(typeof e=="function"){if(!e.name||e.name==="anonymous"){w('Plugin must have a unique, non-empty name. Use { name: "my-plugin", install: fn }.');return}e={name:e.name,install:e}}if(!e.name||typeof e.name!="string"||e.name==="anonymous"){w("Plugin must have a unique, non-empty name.");return}if(qe.has(e.name)){qe.get(e.name).plugin!==e&&w(`Plugin "${e.name}" name collision: a different plugin with this name is already installed.`);return}e.capabilities&&g.debug&&ee(`Plugin "${e.name}" declares capabilities:`,e.capabilities),t.trusted===!0&&w(`WARNING: Plugin "${e.name}" installed with trusted access to sensitive HTTP headers.`),Nn(e.name);try{e.install(Qe,t)}finally{Nn(null)}qe.set(e.name,{plugin:e,options:t}),Xe&&e.init&&Xe.then(()=>e.init(Qe)).catch(n=>w(`Plugin "${e.name}" init error:`,n.message)),ee(`Plugin "${e.name}" installed.`)},global(e,t){if(typeof e!="string"||!e){w("NoJS.global() requires a non-empty string name.");return}if(e==="__proto__"||e==="constructor"||e==="prototype"){w(`NoJS.global(): "${e}" is a forbidden name.`);return}if(Ro.has(e)){w(`NoJS.global(): "${e}" is reserved and cannot be used.`);return}if(!/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)){w(`NoJS.global(): "${e}" is not a valid identifier.`);return}if(yi(t)){w(`NoJS.global(): value for "${e}" is a forbidden reference (eval/Function).`);return}if(e in De&&mt[e]&&mt[e]!==ht&&w(`Global "$${e}" owned by "${mt[e]}" is being overwritten.`),t&&typeof t=="object"&&!t.__isProxy){try{t=JSON.parse(JSON.stringify(t))}catch{try{or(t)}catch(n){if(n.message==="unsafe_global")return}}t=te(t)}else if(t&&typeof t=="object"&&t.__isProxy)try{or(t.__raw??t)}catch(n){if(n.message==="unsafe_global")return}De[e]=t,ht&&(mt[e]=ht),it(),Te("global:set",{name:e,hasValue:t!=null}),ee(`Global "$${e}" registered.`)},async dispose(){On(!0);try{if(Xe)try{await Xe}catch{}let e=[...qe.entries()].reverse();for(let[t,{plugin:n}]of e)if(n.dispose)try{let r;await Promise.race([Promise.resolve(n.dispose(Qe)).finally(()=>clearTimeout(r)),new Promise((i,o)=>{r=setTimeout(()=>o(new Error("Dispose timeout")),3e3)})])}catch(r){w(`Plugin "${t}" dispose error:`,r.message)}qe.clear();for(let t in De)delete De[t];for(let t in mt)delete mt[t];Je.request.length=0,Je.response.length=0,de&&de.destroy&&de.destroy(),Pn(null),Nr(),ir=!1,Xe=null,ee("Disposed.")}finally{On(!1)}},async init(e){if(!(typeof document>"u"))return Xe||(ir=!0,Xe=(async()=>{if(e=e||document.body,ee("Initializing..."),g.i18n.loadPath){let n=new Set([pe.locale,g.i18n.fallbackLocale]);await Promise.all([...n].map(r=>Rn(r)))}Dt(e);let t=Ho();await Qr(t),document.querySelector("[route-view]")&&Pn(di()),Q(e),de&&await de.init(),ee("Initialized."),ei(),Pr(Qe);for(let[,{plugin:n}]of qe)n.init&&await n.init(Qe);Ke("plugins:ready")})(),Xe)},directive(e,t){H(e,t)},filter(e,t){if(typeof e!="string"||!e)throw new TypeError("NoJS.filter() requires a non-empty string name.");if(typeof t!="function")throw new TypeError(`NoJS.filter(): "${e}" handler must be a function.`);if(Mo.has(e)){w(`NoJS.filter(): "${e}" is a built-in filter and cannot be overridden.`);return}Y[e]=t},validator(e,t){if(typeof e!="string"||!e)throw new TypeError("NoJS.validator() requires a non-empty string name.");if(typeof t!="function")throw new TypeError(`NoJS.validator(): "${e}" handler must be a function.`);if(Fo.has(e)){w(`NoJS.validator(): "${e}" is a built-in validator and cannot be overridden.`);return}Ln[e]=t},i18n(e){if(e.loadPath!=null&&(g.i18n.loadPath=e.loadPath),e.ns&&(g.i18n.ns=e.ns),Array.isArray(e.supportedLocales)&&(g.i18n.supportedLocales=e.supportedLocales),e.cache!=null&&(g.i18n.cache=e.cache),e.persist!=null&&(g.i18n.persist=e.persist),e.locales&&(pe.locales=e.locales),e.fallbackLocale&&(g.i18n.fallbackLocale=e.fallbackLocale),e.defaultLocale&&(pe._locale=e.defaultLocale),g.i18n.persist&&typeof localStorage<"u")try{let t=localStorage.getItem("nojs-locale");if(t){pe._locale=t;return}}catch{}if(e.detectBrowser){let t=typeof navigator<"u"&&navigator.language||"en",n=t.split("-")[0],r=Array.isArray(g.i18n.supportedLocales)?g.i18n.supportedLocales:[],i=o=>pe.locales[o]||r.includes(o);i(t)?pe._locale=t:i(n)&&(pe._locale=n)}},on(e,t){return nt[e]||(nt[e]=[]),nt[e].length>=g.maxEventListeners&&w('MaxListenersExceeded: event "'+e+'" has '+nt[e].length+" listeners (max "+g.maxEventListeners+"). Possible memory leak."),nt[e].push(t),()=>{nt[e]=nt[e].filter(n=>n!==t)}},interceptor(e,t){if(Zt){w("Cannot register interceptors during dispose.");return}if(!Je[e]){w(`NoJS.interceptor(): unknown type "${e}" (expected "request" or "response").`);return}Je[e].push(ht?{fn:t,pluginName:ht}:t)},get store(){return le},notify(){it()},get router(){return de},createContext:te,evaluate:R,findContext:B,processTree:Q,resolve:Rt,get internals(){return Object.freeze({execStatement:ke,cloneTemplate:Se,disposeChildren:se,disposeTree:He,warn:w,validators:Object.freeze({...Ln}),removeCoreDirective:ri,onDispose:M})},version:"1.19.0"};Object.defineProperty(Qe,"CANCEL",{value:Bt,writable:!1,configurable:!1});Object.defineProperty(Qe,"RESPOND",{value:Ct,writable:!1,configurable:!1});Object.defineProperty(Qe,"REPLACE",{value:Ut,writable:!1,configurable:!1});Object.defineProperty(Qe,"_initialized",{get(){return Xe!==null},set(e){e||(Xe=null)},configurable:!0});var En=Qe;window.NoJS=En;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>En.init()):En.init();})(); +`.trim(),t=document.createElement("style");t.setAttribute("data-nojs-animations",""),t.textContent=e,document.head.appendChild(t)}function Ct(e,t,n,r,i=!1){bn();let o=r||0;if(t){let s=i?e:e.firstElementChild||e;s.classList.add(t),s.style.animationName=t,s.style.animationFillMode="forwards",s.style.animationTimingFunction="ease",r&&(s.style.animationDuration=r+"ms");let a=!1,l,u=()=>{a||(a=!0,clearTimeout(l),s.removeEventListener("animationend",u),s.classList.remove(t),s.style.animationName="",s.style.animationDuration="",s.style.animationFillMode="",s.style.animationTimingFunction="")};return s.addEventListener("animationend",u,{once:!0}),l=setTimeout(u,o),()=>u()}if(n){let s=i?e:e.firstElementChild||e;s.classList.add(n+"-enter",n+"-enter-active");let a=!1,l,u=requestAnimationFrame(()=>{s.classList.remove(n+"-enter"),s.classList.add(n+"-enter-to");let d=()=>{a||(a=!0,clearTimeout(l),s.removeEventListener("transitionend",d),s.classList.remove(n+"-enter-active",n+"-enter-to"))};s.addEventListener("transitionend",d,{once:!0}),l=setTimeout(d,o)});return()=>{a=!0,cancelAnimationFrame(u),clearTimeout(l),s.classList.remove(n+"-enter",n+"-enter-active",n+"-enter-to")}}return()=>{}}function wn(e,t,n,r,i){bn();let o=i||0;if(!e.firstElementChild&&!e.childNodes.length)return r(),()=>{};if(t){let s=e.firstElementChild||e;s.classList.add(t),i&&(s.style.animationDuration=i+"ms");let a=!1,l=()=>{a||(a=!0,s.classList.remove(t),r())};s.addEventListener("animationend",l,{once:!0});let u=setTimeout(l,o);return()=>{a=!0,clearTimeout(u),s.removeEventListener("animationend",l)}}if(n){let s=e.firstElementChild||e;s.classList.add(n+"-leave",n+"-leave-active");let a=!1,l,u=requestAnimationFrame(()=>{s.classList.remove(n+"-leave"),s.classList.add(n+"-leave-to");let d=()=>{a||(a=!0,s.classList.remove(n+"-leave-active",n+"-leave-to"),r())};s.addEventListener("transitionend",d,{once:!0}),l=setTimeout(d,o)});return()=>{a=!0,cancelAnimationFrame(u),clearTimeout(l),s.classList.remove(n+"-leave",n+"-leave-active",n+"-leave-to")}}return r(),()=>{}}function wo(e,t){return e.replace(/\{([^}"'{][^}]*)\}/g,(n,r)=>{try{let i=R(r.trim(),t);return i!=null?String(i):""}catch{return""}})}function ui(e){return!e||typeof e!="string"?!1:e.startsWith("/")||e.startsWith("#")||e.startsWith(".")}var nr='

404

Page not found

',di="forward";function vo(e){let t=new Set;for(let n of e){let r=n.getAttribute("transition");r&&r!=="true"&&t.add(r)}return t.add(di),[...t]}function fi(){return typeof document<"u"&&typeof document.startViewTransition=="function"&&_.router.viewTransition!==!1}function vn(){for(let e of document.querySelectorAll("[route-view]")){for(let t of[...e.children])He(t);e.innerHTML=""}}function pi(){let e=[],t=new Map,n={path:"",params:{},query:{},hash:""},r=new Set,i=new Map,o=[];function s(T){let h=e.find(v=>v.path===T);if(!h){let v=[],x=T.replace(/:(\w+)/g,(g,S)=>(v.push(S),"([^/]+)")),y=new RegExp("^"+x+"$");h={path:T,outlets:{},regex:y,paramNames:v},e.push(h)}return h}function a(T){let h={};return new URLSearchParams(T).forEach((v,x)=>{h[x]=v}),h}function l(T){for(let h of e){let v=T.match(h.regex);if(v){let x={},y=h.paramNames;for(let g=0;g=0?T.slice(x+1):"",g=x>=0?T.slice(0,x):T,[S,c=""]=g.split("?"),f=S.length>1?S.replace(/\/+$/,""):S;if(f===n.path&&y){if(n.hash="#"+y,_.router.useHash){let j="#"+T;h?window.location.replace(j):window.location.hash=T}else{let j=(_.router.base||"/").replace(/\/$/,"")+T;h?window.history.replaceState({},"",j):window.history.pushState({},"",j)}requestAnimationFrame(()=>{let j=document.getElementById(y);j&&j.scrollIntoView({behavior:"smooth"})}),Rn(),r.forEach(j=>j(n));return}n={path:f,params:{},query:a(c),hash:y?"#"+y:""};let m=l(f);if(m){n.matched=!0,n.params=m.params;let j=m.route.outlets?.default,G=j?.getAttribute("guard"),z=j?.getAttribute("redirect");if(G){let _e=q({},null);if(_e.__raw.$store=se,_e.__raw.$route=n,!R(G,_e)){z&&ui(z)?await u(z,!0):z?(w(`Route guard redirect blocked \u2014 "${z}" is not a relative path.`),vn()):(w(`Route guard failed for "${T}" but no redirect is defined. The route will not render.`),vn());return}}}else{n.matched=!1;let j=t.get("default");if(j){let G=j.getAttribute("guard"),z=j.getAttribute("redirect");if(G){let _e=q({},null);if(_e.__raw.$store=se,_e.__raw.$route=n,!R(G,_e)){z&&ui(z)?await u(z,!0):z?(w(`Route guard redirect blocked \u2014 "${z}" is not a relative path.`),vn()):(w(`Route guard failed for "${T}" but no redirect is defined. The route will not render.`),vn());return}}}}let P=f+(c?"?"+c:"")+(y?"#"+y:"");if(_.router.useHash){let j="#"+P;h?window.location.replace(j):window.location.hash=P}else{let j=(_.router.base||"/").replace(/\/$/,"")+P;h?window.history.replaceState({},"",j):window.history.pushState({},"",j)}let N=n,ne=document.querySelectorAll("[route-view]"),$=[...ne].some(j=>j.getAttribute("transition"));if(fi()&&$){bn();for(let z of ne)if(z.getAttribute("transition")){let _e=(z.getAttribute("route-view")||"").trim();z.style.viewTransitionName=_e&&_e!=="default"?"route-content-"+_e:"route-content"}let j=vo(ne),G=document.startViewTransition({update:async()=>{await C(m,N)},types:j});G.finished.catch(z=>{z.name!=="AbortError"&&w("View transition failed:",z)}),G.ready?.catch(()=>{}),await G.updateCallbackDone}else await C(m,N);if(await E(),Rn(),r.forEach(j=>j(n)),Te("route:navigate",{path:n.path,params:n.params,query:n.query,hash:n.hash}),n.hash){let j=n.hash.slice(1);requestAnimationFrame(()=>{let G=document.getElementById(j);G&&G.scrollIntoView({behavior:"smooth"})})}}function d(T,h){if(!document.head)return;let v=q({},null);v.__raw.$route=h,v.__raw.$store=se;let x=T.getAttribute("page-title");if(x){let c=R(x,v);c!=null&&(document.title=String(c))}let y=T.getAttribute("page-description");if(y){let c=R(y,v);if(c!=null){let f=document.querySelector('meta[name="description"]');f||(f=document.createElement("meta"),f.name="description",document.head.appendChild(f)),f.content=String(c)}}let g=T.getAttribute("page-canonical");if(g){let c=R(g,v);if(c!=null){let f=document.querySelector('link[rel="canonical"]');f||(f=document.createElement("link"),f.rel="canonical",document.head.appendChild(f)),f.href=String(c)}}let S=T.getAttribute("page-jsonld");if(S){let c=document.querySelector('script[type="application/ld+json"][data-nojs]');c||(c=document.createElement("script"),c.type="application/ld+json",c.setAttribute("data-nojs",""),document.head.appendChild(c)),c.textContent=wo(S,v).replace(/<\//g,"<\\/")}}function p(T,h,v,x,y){let g=T+h+v,S=x+":"+g;if(i.has(S))return i.get(S);let c=document.createElement("template");return c.setAttribute("src",g),c.setAttribute("route",y),document.body.appendChild(c),i.set(S,c),c}async function b(T,h){let v=_.router.templates||"";if(!T.hasAttribute("src")&&!v)return null;let y=(T.getAttribute("src")||v).replace(/\/?$/,"/"),g=T.getAttribute("ext")||_.router.ext||".tpl",S=T.getAttribute("route-index")||"index";if(n.path==="/"){let $=S,j=p(y,$,g,h,n.path);return te("[ROUTER] File-based route:",n.path,"\u2192",y+$+g),T.hasAttribute("i18n-ns")&&!j.getAttribute("i18n-ns")&&j.setAttribute("i18n-ns",$),{tpl:j,remainingSegments:[],baseSrc:y,ext:g,indexName:S}}let c=n.path.replace(/^\//,"").split("/").filter(Boolean);if(c.length<=1){let $=c[0]||S,j=p(y,$,g,h,n.path);return te("[ROUTER] File-based route:",n.path,"\u2192",y+$+g),T.hasAttribute("i18n-ns")&&!j.getAttribute("i18n-ns")&&j.setAttribute("i18n-ns",$),{tpl:j,remainingSegments:[],baseSrc:y,ext:g,indexName:S}}let f=c[0],m=h+":layout:"+y+f+g,P;if(i.has(m)){let $=i.get(m);P=$&&!$.__loadFailed}else{let $=p(y,f,g,h,"/"+f);i.set(m,$),$.__srcLoaded||await Me($),P=!$.__loadFailed}if(P){let $=i.get(m)||p(y,f,g,h,"/"+f);return te("[ROUTER] Hierarchical layout:",n.path,"\u2192 layout",y+f+g,"remaining:",c.slice(1)),T.hasAttribute("i18n-ns")&&!$.getAttribute("i18n-ns")&&$.setAttribute("i18n-ns",f),{tpl:$,remainingSegments:c.slice(1),baseSrc:y,ext:g,indexName:S}}let N=c.join("/"),ne=p(y,N,g,h,n.path);return te("[ROUTER] File-based route (flat fallback):",n.path,"\u2192",y+N+g),T.hasAttribute("i18n-ns")&&!ne.getAttribute("i18n-ns")&&ne.setAttribute("i18n-ns",N),{tpl:ne,remainingSegments:[],baseSrc:y,ext:g,indexName:S}}async function E(){let T=document.querySelectorAll("[route-view][route-index]");for(let h of T){if(h.children.length>0)continue;let v=h.getAttribute("route-index");if(!v)continue;let x=(h.getAttribute("route-view")||"").trim()||"default",y=h.getAttribute("ext")||_.router.ext||".tpl",g=h.getAttribute("src");if(g&&g.startsWith("./")){let $=h.parentNode;for(;$;){if($.__srcBase){g=$.__srcBase+g.slice(2);break}$=$.parentNode}g.startsWith("./")&&(g=g.slice(2))}let S=g?g.replace(/\/?$/,"/"):"",c=p(S,v,y,x,"/"+v);if(c.getAttribute("src")&&!c.__srcLoaded&&await Me(c),c.__loadFailed)continue;c.removeAttribute("route"),te("[ROUTER] Nested index route:",S+v+y),h.hasAttribute("i18n-ns")&&!c.getAttribute("i18n-ns")&&c.setAttribute("i18n-ns",v),He(h),h.innerHTML="";let f=c.getAttribute("i18n-ns");if(f){let{_loadI18nNamespace:$}=await Promise.resolve().then(()=>(st(),rn));await $(f)}let m=c.content.cloneNode(!0),P=q({$route:n},H(h)),N=document.createElement("div");N.style.display="contents",N.__ctx=P,c.content.__srcBase&&(N.__srcBase=c.content.__srcBase),N.appendChild(m),h.appendChild(N),Mt(N);let ne=[...N.querySelectorAll("template[src]")];await Promise.all(ne.map(Me)),ze(N),K(N)}}async function L(T,h,v,x,y,g){if(!h.length)return;let S=[...T.querySelectorAll("[route-view]")];if(!S.length)return;let c=h[0],f=h.slice(1);for(let m of S){let P=(m.getAttribute("route-view")||"").trim()||"default",N=m.getAttribute("src");if(N&&N.startsWith("./")){let X=m.parentNode;for(;X;){if(X.__srcBase){N=X.__srcBase+N.slice(2);break}X=X.parentNode}N.startsWith("./")&&(N=N.slice(2))}let ne=N?N.replace(/\/?$/,"/"):v,$=m.getAttribute("ext")||x,j=P+":"+ne+c;if(g.has(j)){w("[ROUTER] Infinite loop detected for nested outlet:",j);continue}g.add(j);let G,z=f;if(f.length>0){let X=P+":layout:"+ne+c+$;if(!i.has(X)){let Re=p(ne,c,$,P,"/"+c);i.set(X,Re),Re.__srcLoaded||await Me(Re)}let we=i.get(X);if(we&&!we.__loadFailed)G=we,te("[ROUTER] Nested layout:",c,"\u2192",ne+c+$);else{let Re=[c,...f].join("/");G=p(ne,Re,$,P,n.path),z=[],te("[ROUTER] Nested flat fallback:",c,"\u2192",ne+Re+$)}}else G=p(ne,c,$,P,n.path),te("[ROUTER] Nested leaf:",c,"\u2192",ne+c+$);if(G.getAttribute("src")&&!G.__srcLoaded&&await Me(G),G.__loadFailed){let X=t.get(P)||(P!=="default"?t.get("default"):null);if(X&&!X.__loadFailed&&(G=X,G.getAttribute("src")&&!G.__srcLoaded&&await Me(G)),!G||G.__loadFailed){He(m),m.innerHTML=nr;continue}}He(m),m.innerHTML="";let _e=G.getAttribute("i18n-ns");if(_e){let{_loadI18nNamespace:X}=await Promise.resolve().then(()=>(st(),rn));await X(_e)}let Oe=G.content.cloneNode(!0),U=q({$route:n},H(m)),be=document.createElement("div");be.style.display="contents",be.__ctx=U,G.content.__srcBase&&(be.__srcBase=G.content.__srcBase),be.appendChild(Oe),m.appendChild(be),Mt(be);let O=[...be.querySelectorAll("template[src]")];await Promise.all(O.map(Me)),ze(be),K(be),z.length>0&&await L(be,z,ne,$,y,g)}}async function C(T,h=n){let v=document.querySelectorAll("[route-view]");for(let y of v){if(!y.isConnected||y.parentElement&&y.parentElement.closest("[route-view]"))continue;let g=y.getAttribute("route-view"),S=g&&g.trim()!==""?g.trim():"default",c=T?.route?.outlets?.[S],f=[],m="",P="",N="index",ne=_.router.templates||"";if(!c&&(y.hasAttribute("src")||ne)){let $=await b(y,S);$&&(c=$.tpl,f=$.remainingSegments,m=$.baseSrc,P=$.ext,N=$.indexName)}if((!c||c.__loadFailed)&&(!T||c?.__loadFailed)){let $=t.get(S)||(S!=="default"?t.get("default"):null);$&&(c=$)}for(let $ of[...y.children])He($);if(y.innerHTML="",c&&!c.__loadFailed){if(c.getAttribute("src")&&!c.__srcLoaded&&(te("Loading route template on demand:",c.getAttribute("src")),await Me(c)),c.__loadFailed){let U=t.get(S)||(S!=="default"?t.get("default"):null);if(U&&!U.__loadFailed&&(c=U,c.getAttribute("src")&&!c.__srcLoaded&&await Me(c)),!c||c.__loadFailed){y.innerHTML=nr;continue}}let $=c.getAttribute("i18n-ns");if($){let{_loadI18nNamespace:U}=await Promise.resolve().then(()=>(st(),rn));await U($)}let j=c.content.cloneNode(!0),G=q({$route:h},H(y)),z=document.createElement("div");z.style.display="contents",z.__ctx=G,c.content.__srcBase&&(z.__srcBase=c.content.__srcBase),z.appendChild(j),y.appendChild(z),Mt(z);let _e=[...z.querySelectorAll("template[src]")];te("[ROUTER] nested templates found in wrapper:",_e.length,_e.map(U=>U.getAttribute("src")+(U.__srcLoaded?"[LOADED]":"[NEW]"))),await Promise.all(_e.map(Me)),te("[ROUTER] all nested loads done for route:",h.path);let Oe=y.getAttribute("transition");if(Oe&&!fi()&&(Ct(z,null,Oe),w("Class-based route transitions are deprecated. The View Transition API is now used by default. Set router.viewTransition to false to keep legacy behavior.")),ze(z),K(z),f.length>0&&await L(z,f,m,P,N,new Set),S==="default"){let U=c.getAttribute("page-title");if(U){let be=q({},null);be.__raw.$route=h,be.__raw.$store=se;let O=R(U,be);O!=null&&(document.title=String(O))}}S==="default"&&d(c,h),S==="default"&&_.router.focusBehavior==="auto"&&requestAnimationFrame(()=>{let U=y.querySelector("[autofocus]")||y.querySelector('[tabindex="-1"]')||y.querySelector("h1")||y;U.hasAttribute("tabindex")||U.setAttribute("tabindex","-1"),U.focus({preventScroll:!0})})}else(!T||c?.__loadFailed)&&(y.innerHTML=nr)}document.querySelectorAll("[route]").forEach(y=>{let g=y.getAttribute("route"),S=y.getAttribute("route-active")||"active",c=y.getAttribute("route-active-exact");if(c)c.split(/\s+/).filter(Boolean).forEach(f=>y.classList.toggle(f,h.path===g));else if(S&&!y.hasAttribute("route-active-exact")){let f=h.path,m=g==="/"?f==="/":f===g||f.startsWith(g.replace(/\/$/,"")+"/");S.split(/\s+/).filter(Boolean).forEach(P=>y.classList.toggle(P,m))}});let x=_.router.scrollBehavior;x==="top"?window.scrollTo(0,0):x==="smooth"&&window.scrollTo({top:0,behavior:"smooth"})}function I(T,h){h.scrollIntoView({behavior:"smooth"});let v='a[href="#'+T+'"]';document.querySelectorAll('a[href^="#"]').forEach(x=>{x.hasAttribute("route")||x.classList.toggle("active",x.matches(v))})}function W(){let T=document.querySelectorAll("[route-view]");for(let h of T){if(h.parentElement&&h.parentElement.closest("[route-view]"))continue;let v=h.getAttribute("src")||_.router.templates||"";if(!v)continue;let x=v.replace(/\/?$/,"/"),y=h.getAttribute("ext")||_.router.ext||".tpl",g=h.getAttribute("route-index")||"index",S=(h.getAttribute("route-view")||"").trim()||"default",c=new Map;document.querySelectorAll("[route]:not([route-view])").forEach(P=>{let N=P.getAttribute("route");if(!N)return;let ne=N.split("?")[0].split("#")[0],$=P.getAttribute("lazy"),j=c.get(ne);(!c.has(ne)||$==="priority"||j==="ondemand"&&$!=="ondemand")&&c.set(ne,$)});let f=[],m=[];for(let[P,N]of c){if(N==="ondemand"||P===n.path||P==="*")continue;let ne=P==="/"?g:P.replace(/^\//,""),$=P==="/"?[]:P.replace(/^\//,"").split("/").filter(Boolean);if($.length>1){let _e=$[0],Oe=S+":layout:"+x+_e+y,U=i.get(Oe);if(U&&!U.__loadFailed){let be=$.join("/"),O=p(x,be,y,S,P);O.__srcLoaded||(te("[ROUTER] Prefetch (layout child):",P,"\u2192",x+be+y,N==="priority"?"(priority)":"(background)"),h.hasAttribute("i18n-ns")&&O.setAttribute("i18n-ns",be),N==="priority"?f.push(O):m.push(O));continue}}let j=x+ne+y,G=S+":"+j;if(i.has(G))continue;let z=p(x,ne,y,S,P);te("[ROUTER] Prefetch:",P,"\u2192",j,N==="priority"?"(priority)":"(background)"),h.hasAttribute("i18n-ns")&&z.setAttribute("i18n-ns",ne),N==="priority"?f.push(z):m.push(z)}(f.length||m.length)&&Promise.all(f.map(Me)).then(()=>{m.forEach(Me)})}}return{get current(){return n},push(T){return u(T)},replace(T){return u(T,!0)},back(){window.history.back()},forward(){window.history.forward()},on(T){return r.add(T),()=>r.delete(T)},register(T,h,v="default"){if(T==="*"){t.set(v,h);return}let x=s(T);x.outlets[v]=h},async init(){_.router.useHash&&!_.router.suppressHashWarning&&w("Router is running in hash mode (useHash: true). URLs like /#/about are not indexed as separate pages by search engines. Use useHash: false with a server-side SPA fallback (try_files) for SEO-friendly routing. See: https://github.com/no-js-dev/nojs/blob/main/docs/md/routing.md#deployment"),document.querySelectorAll("template[route]").forEach(h=>{let v=h.getAttribute("route"),x=h.getAttribute("outlet")||"default";if(v==="*"){t.set(x,h);return}let y=s(v);y.outlets[x]=h});let T=h=>{let v=h.target.closest("[route]");if(v&&!v.hasAttribute("route-view")){h.preventDefault();let y=v.getAttribute("route");u(y);return}let x=h.target.closest('a[href^="#"]');if(x&&!x.hasAttribute("route")){let g=x.getAttribute("href").slice(1);if(g&&!g.startsWith("/")){let S=document.getElementById(g);S&&(h.preventDefault(),I(g,S),_.router.useHash||window.history.replaceState(null,"","#"+g))}}};if(document.addEventListener("click",T),o.push(()=>document.removeEventListener("click",T)),_.router.useHash){let h=()=>{let x=window.location.hash.slice(1)||"/";if(!x.startsWith("/")){let g=document.getElementById(x);g&&(I(x,g),window.history.replaceState(null,"","#"+n.path));return}let[y]=x.split("?");y!==n.path&&u(x,!0,!0)};window.addEventListener("hashchange",h),o.push(()=>window.removeEventListener("hashchange",h));let v=window.location.hash.slice(1)||"/";await u(v,!0)}else{let h=()=>{let x=Ht(window.location.pathname);if(x===n.path){let y=window.location.hash.slice(1);if(y){let g=document.getElementById(y);g&&I(y,g)}return}u(x,!0,!0)};window.addEventListener("popstate",h),o.push(()=>window.removeEventListener("popstate",h));let v=Ht(window.location.pathname);await u(v,!0)}W()},destroy(){o.forEach(T=>T()),o.length=0,r.clear()}}}ge();Q.uppercase=e=>String(e??"").toUpperCase();Q.lowercase=e=>String(e??"").toLowerCase();Q.capitalize=e=>String(e??"").replace(/\b\w/g,t=>t.toUpperCase());Q.truncate=(e,t=100)=>{let n=String(e??"");return n.length>t?n.slice(0,t)+"...":n};Q.trim=e=>String(e??"").trim();Q.stripHtml=e=>String(e??"").replace(/<[^>]*>/g,"");Q.slugify=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");Q.nl2br=e=>String(e??"").replace(/&/g,"&").replace(//g,">").replace(/\n/g,"
");Q.encodeUri=e=>encodeURIComponent(String(e??""));var mi=(e,t=0)=>{let n=Math.floor(Number(e));return isNaN(n)?t:n<0?0:n>100?100:n};Q.number=(e,t=0)=>{let n=Number(e);if(isNaN(n))return e;let r=mi(t);return n.toLocaleString(void 0,{minimumFractionDigits:r,maximumFractionDigits:r})};Q.currency=(e,t="USD")=>{let n=Number(e);if(isNaN(n))return e;try{return n.toLocaleString(void 0,{style:"currency",currency:t})}catch{return`${t} ${n.toFixed(2)}`}};Q.percent=(e,t=0)=>{let n=Number(e);return isNaN(n)?e:(n*100).toFixed(mi(t))+"%"};Q.filesize=e=>{let t=Number(e);if(isNaN(t))return e;let n=["B","KB","MB","GB","TB"],r=t<0?"-":"",i=0,o=Math.abs(t);for(;o>=1024&&i0?1:0)+" "+n[i]};Q.ordinal=e=>{let t=Number(e);if(isNaN(t))return e;let n=["th","st","nd","rd"],r=t%100;return t+(n[(r-20)%10]||n[r]||n[0])};Q.count=e=>Array.isArray(e)?e.length:0;Q.first=e=>Array.isArray(e)?e[0]:e;Q.last=e=>Array.isArray(e)?e[e.length-1]:e;Q.join=(e,t=", ")=>Array.isArray(e)?e.join(t):e;Q.reverse=e=>Array.isArray(e)?[...e].reverse():e;Q.unique=e=>Array.isArray(e)?[...new Set(e)]:e;Q.pluck=(e,t)=>Array.isArray(e)?e.map(n=>n?.[t]):e;Q.sortBy=(e,t)=>{if(!Array.isArray(e))return e;let n=t?.startsWith("-"),r=n?t.slice(1):t,i=o=>o==null||typeof o=="number"&&isNaN(o);return[...e].sort((o,s)=>{let a=o?.[r],l=s?.[r],u=i(a),d=i(l);if(u&&d)return 0;if(u)return 1;if(d)return-1;let p=al?1:0;return n?-p:p})};Q.where=(e,t,n)=>Array.isArray(e)?e.filter(r=>r?.[t]===n):e;var Eo=/^\d{4}-\d{2}-\d{2}$/,En=e=>typeof e=="string"&&Eo.test(e)?new Date(e+"T00:00:00"):new Date(e);Q.date=(e,t="short")=>{let n=En(e);if(isNaN(n))return e;let r=t==="long"?{dateStyle:"long"}:t==="full"?{dateStyle:"full"}:{dateStyle:"short"};return n.toLocaleDateString(void 0,r)};Q.datetime=e=>{let t=En(e);return isNaN(t)?e:t.toLocaleString()};Q.relative=e=>{let t=En(e);if(isNaN(t))return e;let n=(Date.now()-t.getTime())/1e3;return n<0?Q.fromNow(e):n<60?"just now":n<3600?Math.floor(n/60)+"m ago":n<86400?Math.floor(n/3600)+"h ago":n<2592e3?Math.floor(n/86400)+"d ago":t.toLocaleDateString()};Q.fromNow=e=>{let t=En(e);if(isNaN(t))return e;let n=(t.getTime()-Date.now())/1e3;return n<0?Q.relative(e):n<60?"in a moment":n<3600?"in "+Math.floor(n/60)+"m":n<86400?"in "+Math.floor(n/3600)+"h":"in "+Math.floor(n/86400)+"d"};Q.default=(e,t="")=>e==null||e===""?t:e;Q.json=(e,t=2)=>JSON.stringify(e,null,t);Q.debug=e=>(console.log("[No.JS debug]",e),e);Q.keys=e=>e&&typeof e=="object"?Object.keys(e):[];Q.values=e=>e&&typeof e=="object"?Object.values(e):[];ge();ge();var hi=["foreach","each","for","from","filter","sort","limit","offset","key","index","template","animate-enter","animate-leave","animate-stagger","animate-duration","animate","get","post","put","patch","delete","page-title","page-description","page-canonical","page-jsonld","else-if"];function So(e,t){for(let n=0;n>1;e[t[u]]0&&(n[o]=t[a-1]),t[a]=o}let r=new Set,i=t.length?t[t.length-1]:-1;for(;i!==-1;)r.add(i),i=n[i];return r}function rr(e,t,n,r){t&&(e.classList.add(t),e.addEventListener("animationend",()=>e.classList.remove(t),{once:!0}),n&&(e.style.animationDelay=r*n+"ms"))}var ir={priority:10,init(e,t,n){let r=H(e),i,o,s=n.match(/^(\w+)\s+in\s+(\S+)$/);if(s)[,i,o]=s;else{let O=e.getAttribute("from");if(!O||!/^\w+$/.test(n))return;i=n,o=O,console.warn(`[NoJS] "${t}" with "from" is deprecated. Use ${t}="${i} in ${o}" instead.`)}let a=e.getAttribute("index")||"$index",l=e.hasAttribute("if")||e.hasAttribute("else-if"),u=l?null:e.getAttribute("else"),d=e.getAttribute("filter"),p=e.getAttribute("sort"),b=parseInt(e.getAttribute("limit"))||1/0,E=parseInt(e.getAttribute("offset"))||0,L=e.getAttribute("template"),C=e.getAttribute("key"),I=e.getAttribute("animate-enter")||e.getAttribute("animate"),W=e.getAttribute("animate-leave"),ce=parseInt(e.getAttribute("animate-stagger"))||0,T=parseInt(e.getAttribute("animate-duration"))||0,h=null,v=null,x=!1,y=!1,g=!!(d||p||E),S=e.parentNode,c=document.createComment("foreach"),f=document.createComment("/foreach");S.insertBefore(c,e),S.insertBefore(f,e.nextSibling),S.removeChild(e);let m=new Map,P=null,N=null,ne=0,$=-1;function j(){if(P&&(N.registryVersion!==Gt&&(N=tr(P)),!L||$===ne))return;$=ne;let O=L?document.getElementById(L):null;P=e.cloneNode(!0),So(P,!l),O&&(P.innerHTML="",P.appendChild(O.content.cloneNode(!0))),N=tr(P)}function G(O){j();let X=P.cloneNode(!0);return X.__ctx=q(O,r),X}function z(O){si(O,N)}function _e(){ne++;let O=/[\[\]()\s+\-*\/!?:&|]/.test(o)?R(o,r):jt(o,r);Array.isArray(O)||(O=[]);let X=Sn(c,f);if(!x&&O===h&&O.length>0&&X.length>0){for(let V of X)V.__ctx&&V.__ctx.$notify&&V.__ctx.$notify();return}if(h=O,d){let V={[i]:void 0,[a]:0},re=q(V,r),Ae=re.__raw;O=O.filter((Y,k)=>(Ae[i]=Y,Ae[a]=k,delete Ae.__collectKeysCache,!!R(d,re)))}if(p){let V=p.startsWith("-"),re=V?p.slice(1):p;O=[...O].sort((Ae,Y)=>{let k=jt(re,Ae)??Ae?.[re],Pe=jt(re,Y)??Y?.[re],J=k==null||typeof k=="number"&&Number.isNaN(k),B=Pe==null||typeof Pe=="number"&&Number.isNaN(Pe);if(J||B)return J&&B?0:J?1:-1;let le=kPe?1:0;return V?-le:le})}if(O=O.slice(E,E+b),O.length===0&&u){if(x){v=null;return}Xt(c,f),m.clear();let V=ye(u);if(V){S.insertBefore(V,f);let re=c.nextSibling;for(;re&&re!==f;)re.nodeType===1&&K(re),re=re.nextSibling;x=!0}else y||(y=!0,w(`${t}: else template "${u}" not found`,e));v=null;return}if(O.length===0){Xt(c,f),m.clear(),x=!1,v=null;return}if(x=!1,C){U(O,O.length),v=null;return}function we(){if(g||!v)return!1;let V=v.length,re=O.length;if(re<=V)return!1;let Ae=Sn(c,f);if(Ae.length!==V)return!1;for(let J=0;J0){let V=Ne.length;Ne.forEach(re=>{re.classList.add(W);let Ae=()=>{re.classList.remove(W),V--,V<=0&&Re()};re.addEventListener("animationend",Ae,{once:!0}),setTimeout(Ae,T||0)})}else we()||Re()}let Oe=null;if(C){let O=C.match(/^(\w+)\.(\w+)$/);O&&O[1]===i&&!["__proto__","constructor","prototype"].includes(O[2])&&(Oe=O[2])}function U(O,X){m.size===0&&Xt(c,f);let we;if(Oe){we=new Array(O.length);for(let B=0;B(ve[i]=tt,ve[a]=xe,delete ve.__collectKeysCache,{key:R(C,le),item:tt,i:xe}))}let Re=new Set(we.map(B=>B.key)),Ne=!1;for(let B of m.keys())if(Re.has(B)){Ne=!0;break}if(!Ne&&m.size>0)Xt(c,f),m.clear();else for(let[B,le]of m)Re.has(B)||(He(le,!0),le.remove(),m.delete(B));let V=null,re=null;if(we.forEach(({key:B,item:le,i:ve})=>{let tt=m.get(B);if(tt){let xe=tt.__ctx.__raw;(xe[i]!==le||xe[a]!==ve||xe.$count!==X)&&(xe[i]=le,xe[a]=ve,xe.$index=ve,xe.$count=X,xe.$first=ve===0,xe.$last=ve===X-1,xe.$even=ve%2===0,xe.$odd=ve%2!==0,delete xe.__collectKeysCache),tt.__ctx.$notify()}else{let xe=G({[i]:le,[a]:ve,$index:ve,$count:X,$first:ve===0,$last:ve===X-1,$even:ve%2===0,$odd:ve%2!==0});m.set(B,xe),V||(V=document.createDocumentFragment(),re=[]),V.appendChild(xe),re.push({clone:xe,i:ve})}}),V){S.insertBefore(V,f);for(let B=0;B=0;B--){let le=m.get(we[B].key);!Pe.has(B)&&le.nextSibling!==J&&S.insertBefore(le,J),J=le}}let be=fe;lt(S),de(o,r,_e),_e(),lt(be)}};F("foreach",ir);F("each",ir);F("for",ir);F("state",{priority:0,init(e,t,n){let r=R(n,q())||{},o=e.__ctx||(e.parentElement?H(e.parentElement):null),s=q(r,o);e.__ctx=s;let a=e.getAttribute("persist"),l=e.getAttribute("persist-key");if(a&&!l){w(`persist="${a}" requires a persist-key attribute. State will not be persisted.`);return}if(a&&l){let u=a==="localStorage"?localStorage:a==="sessionStorage"?sessionStorage:null;if(u){let d=e.getAttribute("persist-fields"),p=d?new Set(d.split(",").map(W=>W.trim())):null,b="nojs_"+(_.appId||"")+"state_"+l;try{let W=u.getItem(b);if(W){let ce=JSON.parse(W),T=e.hasAttribute("persist-schema"),h=new Set(["__proto__","constructor","prototype"]);for(let[v,x]of Object.entries(ce))if(!h.has(v)&&!v.startsWith("__")&&(!p||p.has(v))){if(T){if(!(v in r)){w('persist-schema: ignoring unknown key "'+v+'"');continue}if(r[v]!==null&&x!==null&&typeof x!=typeof r[v]){w('persist-schema: type mismatch for "'+v+'" (expected '+typeof r[v]+", got "+typeof x+")");continue}}s.$set(v,x)}}}catch{}let E=["token","password","secret","key","auth","credential","session"],C=Object.keys(r).filter(W=>E.some(ce=>W.toLowerCase().includes(ce)));C.length>0&&w("State key(s) "+C.map(W=>'"'+W+'"').join(", ")+" may contain sensitive data. Consider using persist-fields to exclude them.");let I=s.$watch(()=>{try{let W=s.__raw,ce=Object.fromEntries(Object.entries(W).filter(([T])=>!T.startsWith("__")&&(!p||p.has(T))));u.setItem(b,JSON.stringify(ce))}catch{}});D(()=>{I&&I()})}}te("state",r)}});F("store",{priority:0,init(e,t,n){let r=e.getAttribute("value");if(n){if(!se[n]){let i=r?R(r,q())||{}:{};se[n]=q(i),Te("store:created",{name:n,keys:Object.keys(i)})}te("store",n)}}});F("computed",{priority:2,gated:!0,init(e,t,n){if(qe(e))return;let r=e.getAttribute("expr");if(!n||!r)return;let i=H(e);function o(){let s=R(r,i);i.$set(n,s)}de(r,i,o),o()}});F("watch",{priority:2,gated:!0,init(e,t,n){if(qe(e))return;let r=H(e),i=e.getAttribute("on:change"),o=R(n,r);de(n,r,()=>{let s=R(n,r);if(s!==o){let a=o;o=s,i&&Le(i,r,{$old:a,$new:s})}})}});ge();var xo=["get","post","put","patch","delete","query"];function gi(){let e=document.createElement("div");return e.setAttribute("data-nojs-sentinel",""),e.setAttribute("aria-hidden","true"),e.style.height="0",e.style.overflow="hidden",e.style.pointerEvents="none",e}function Co(e){let t=e.parentElement;for(;t&&t!==document.documentElement;){let n=getComputedStyle(t).overflowY;if(n==="scroll"||n==="auto")return t;t=t.parentElement}return document.documentElement}for(let e of xo)F(e,{priority:1,gated:!0,init(t,n,r){if(qe(t)){w(`${n}: HTTP verb directive on a loop element is not supported \u2014 move the fetch to a parent or child element`,t);return}let i=t.getAttribute("as")||"data",o=t.getAttribute("loading"),s=t.getAttribute("error"),a=t.getAttribute("empty"),l=t.getAttribute("success"),u=t.getAttribute("then"),d=t.getAttribute("redirect"),p=t.getAttribute("confirm"),b=250,E=parseInt(t.getAttribute("refresh"))||0,L=E>0?Math.max(E,b):0,C=t.getAttribute("cached"),I=t.hasAttribute("cached")?C||"memory":"none",W=t.getAttribute("body"),ce=t.getAttribute("headers"),T=t.getAttribute("var"),h=t.getAttribute("into"),v=parseInt(t.getAttribute("retry"))||_.retries,x=parseInt(t.getAttribute("retry-delay"))||_.retryDelay||1e3,y=t.getAttribute("params"),g=t.getAttribute("skeleton"),S=e==="query"?"query":"get",c=t.getAttribute(`${S}-trigger`),f=t.getAttribute(`${S}-trigger-label`)||"Load More",m=e==="get"||e==="query"&&t.tagName!=="FORM",P=e==="get"||e==="query",N=e==="get"&&t.hasAttribute("get-cursor"),ne=N&&t.getAttribute("get-cursor-field")||null,$=e==="get"&&t.hasAttribute("get-page"),j=$?parseInt(t.getAttribute("get-page"),10)||1:null;N&&$&&w("get-cursor and get-page are mutually exclusive; using cursor-based pagination");let z=t.getAttribute(`${S}-threshold`)||(c==="scroll"?"200px":"0px"),_e=e==="get"?t.getAttribute("get-insert"):null,Oe=e==="get"&&t.hasAttribute("get-insert")?_e==="prepend"?"prepend":"append":"replace",U=Oe!=="replace",be=t.parentElement?H(t.parentElement):q(),O=t.__ctx||q({},be);t.__ctx=O,N?O.$set("cursor",""):$&&O.$set("page",j);let X=c==="scroll"||c==="button",we=!1,Re=!1,Ne=null,V=null;X&&!U&&w(`get-trigger="${c}" requires get-insert to be set. Falling back to "${c==="scroll"?"visible":"immediate"}" behavior.`);let re=X&&U&&L>0;re&&w(`get-trigger="${c}" is mutually exclusive with refresh. The refresh interval is being ignored.`);let Ae=[...t.childNodes].map(A=>A.cloneNode(!0)),Y=null;D(()=>{Y&&Y.abort(),Y=null});let k=null,Pe=0,J=!0;function B(){k&&k.parentNode&&k.parentNode.removeChild(k);let A=++Pe;k=gi(),Oe==="append"?t.appendChild(k):t.insertBefore(k,t.firstChild),D(()=>{A===Pe&&(k&&k.parentNode&&k.parentNode.removeChild(k),k=null)})}U&&B();function le(){if(!g)return;let A=document.getElementById(g);A&&A.style.removeProperty("display")}function ve(){if(!g)return;let A=document.getElementById(g);A&&(A.style.display="none")}function tt(){if(t.tagName!=="FORM")return;if(t.__nojsResetSubmitting){t.__nojsResetSubmitting();return}let A=H(t),M=A?.$form;M&&(M.submitting=!1,A.$set("$form",{...M}))}function xe(){for(let A of[...t.children])He(A);k&&k.parentNode&&k.parentNode.removeChild(k),k=null,t.innerHTML="",J=!0,B()}function vi(A,M){let ae=M.split("."),Fe=A;for(let Z of ae){if(Fe==null||typeof Fe!="object")return;if(je[Z]){w("Blocked access to forbidden property '"+Z+"' in get-cursor-field");return}Fe=Fe[Z]}return Fe}let Ei=["cursor","next_cursor","nextCursor","next"];function Si(A,M){if(M&&M.headers){let ae=M.headers.get("X-NoJS-Cursor");if(ae!=null)return ae||null}if(A!=null&&typeof A=="object"&&!Array.isArray(A)){if(ne){let ae=vi(A,ne);return ae!==void 0&&ae||null}for(let ae of Ei){let Fe=A[ae];if(Fe!=null&&Fe!=="")return Fe}}return null}function Ai(A){if(Array.isArray(A))return A;if(A!=null&&typeof A=="object"){for(let M of Object.keys(A))if(Array.isArray(A[M]))return A[M]}return A}async function Ee(){if(X&&U&&we)return;Y&&Y.abort(),Y=new AbortController;let A=Y;if(p&&!window.confirm(p)){tt();return}X&&U&&(we=!0),c==="button"&&U&&!J&&Zt(),le();let M=Ue(r,O);if(y){let Z=R(y,O);if(Z&&typeof Z=="object"){let Ce=new URLSearchParams;for(let[Ie,$e]of Object.entries(Z))if($e!=null)if(Array.isArray($e))for(let ke of $e)ke!=null&&Ce.append(Ie,typeof ke=="object"?JSON.stringify(ke):String(ke));else typeof $e=="object"?Ce.append(Ie,JSON.stringify($e)):Ce.append(Ie,String($e));let Se=Ce.toString();if(Se){let Ie=M.includes("?")?"&":"?";M+=Ie+Se}}}let ae="";e==="query"&&(t.tagName==="FORM"?ae=JSON.stringify(Object.fromEntries(new FormData(t).entries())):W&&(ae=Ue(W,O)));let Fe=e+":"+M+(ae?":"+ae:"");if(P){let Z=Vr(Fe,I);if(Z!=null){ve(),O.$set(i,Z),ze(t),K(t);return}}if(o){let Z=ye(o);Z&&(U&&!J?xi(Z):(ie(t),t.innerHTML="",t.appendChild(Z),K(t)))}try{let Z=null;if(W){let oe=Ue(W,O);try{Z=JSON.parse(oe)}catch{Z=oe}}if(t.tagName==="FORM"){let oe=new FormData(t);Z=Object.fromEntries(oe.entries())}let Ce=ce?JSON.parse(ce):{};if(ce)for(let oe of Object.keys(Ce)){let mt=oe.toLowerCase();(Tt.has(mt)||/^x-(auth|api)-/.test(mt))&&w(`Sensitive header "${oe}" is set inline on a headers attribute. Use NoJS.config({ headers }) or an interceptor to avoid exposing credentials in HTML source.`)}let Se={},Ie=await gn(M,e,Z,Ce,t,Y.signal,v,x,Se),$e=null,ke=Ie;N&&($e=Si(Ie,Se),(Se.headers&&Se.headers.get("X-NoJS-Cursor"))==null&&(ke=Ai(Ie))),P&&Gr(Fe,N?ke:Ie,I);let Be=N?ke:Ie,ur=Be==null||Array.isArray(Be)&&Be.length===0||Be==="",fr=Se.headers&&Se.headers.get("X-NoJS-Last-Page")==="true",dr=N&&$e==null,qo=ur||fr||dr;if(ur){if(ve(),N&&O.$set("cursor",""),X&&U&&ar(),a){let oe=ye(a);oe&&(U&&!J?(Cn(),Yt(oe),K(oe)):(ie(t),t.innerHTML="",t.appendChild(oe),K(t)))}return}if(ve(),N&&O.$set("cursor",$e||""),U&&!J){let oe=O[i];if(Array.isArray(oe)&&Array.isArray(Be)){let mt=Oe==="append"?[...oe,...Be]:[...Be,...oe];O.$set(i,mt)}else O.$set(i,Be)}else O.$set(i,Be);if(h&&(se[h]||(se[h]=q({})),se[h].$set(i,Be),Ve(h)),U&&!J){Cn();let oe=document.createElement("div");oe.style.display="contents";let mt=q({[i]:Be},O);oe.__ctx=mt;for(let ct of Ae)oe.appendChild(ct.cloneNode(!0));if(Oe==="prepend"){let ct=Co(t),Ln=ct.scrollTop,ht=ct.scrollHeight;k&&k.nextSibling?t.insertBefore(oe,k.nextSibling):t.appendChild(oe),K(oe);let Li=ct.scrollHeight;ct.scrollTop=Ln+(Li-ht)}else k?t.insertBefore(oe,k):t.appendChild(oe),K(oe);J=!1}else{if(l){let oe=ye(l);if(oe){ie(t),t.innerHTML="";let ct=document.getElementById(l.replace("#",""))?.getAttribute("var")||T||"result",Ln=q({[ct]:Be},O),ht=document.createElement("div");ht.style.display="contents",ht.__ctx=Ln,ht.appendChild(oe),t.appendChild(ht),K(ht)}}else{ie(t),t.innerHTML="";for(let oe of Ae)t.appendChild(oe.cloneNode(!0));ze(t),K(t)}if(U){J=!1,k&&k.parentNode&&k.parentNode.removeChild(k);let oe=++Pe;k=gi(),Oe==="append"?t.appendChild(k):t.insertBefore(k,t.firstChild),D(()=>{oe===Pe&&(k&&k.parentNode&&k.parentNode.removeChild(k),k=null)})}}$&&!N&&X&&U&&O.$set("page",O.page+1),(fr||dr)&&X&&U?ar():X&&U&&!Re&&Ti(),u&&Le(u,O,{result:Be}),d&&me&&me.push(d),Ge("fetch:success",{url:M,data:Be}),Te("fetch:success",{method:e,url:M})}catch(Z){if(Z.name==="AbortError")return;if(ve(),w(`${e.toUpperCase()} ${M} failed:`,Z.message),Ge("fetch:error",{url:M,error:Z}),Ge("error",{url:M,error:Z}),Te("fetch:error",{method:e,url:M,error:Z.message}),s){let Ce=ye(s);if(Ce){let Ie=document.getElementById(s.replace("#",""))?.getAttribute("var")||"err",$e=q({[Ie]:{message:Z.message,status:Z.status,body:Z.body}},O),ke=document.createElement("div");ke.style.display="contents",ke.__ctx=$e,ke.appendChild(Ce),U&&!J?(Cn(),Ci(),ke.setAttribute("data-nojs-inline-error",""),Yt(ke)):(ie(t),t.innerHTML="",t.appendChild(ke)),K(ke)}}}finally{X&&U&&(we=!1),t.tagName==="FORM"&&e!=="get"&&!A.signal.aborted&&Y===A&&tt()}}function xi(A){let M=document.createElement("div");M.style.display="contents",M.setAttribute("data-nojs-inline-loading",""),M.appendChild(A),Yt(M),K(M)}function Cn(){let A=t.querySelector("[data-nojs-inline-loading]");A&&(He(A),A.parentNode.removeChild(A))}function Ci(){let A=t.querySelector("[data-nojs-inline-error]");A&&(He(A),A.parentNode.removeChild(A))}function Yt(A){Oe==="append"&&k?t.insertBefore(A,k):Oe==="prepend"&&k&&k.nextSibling?t.insertBefore(A,k.nextSibling):t.appendChild(A)}function ar(){Re=!0,Ne&&(Ne.disconnect(),Ne=null),Zt(),k&&k.parentNode&&k.parentNode.removeChild(k),k=null,Ge("fetch:end",{url:r})}function Ti(){c==="button"&&cr(),c==="scroll"&&(Ne?k&&Ne.observe(k):lr())}function cr(){Zt();let A=document.createElement("button");A.setAttribute("data-nojs-load-more",""),A.setAttribute("type","button"),A.setAttribute("aria-label",f),A.textContent=f,V=A;let M=()=>{Re||we||Ee()};A.addEventListener("click",M),D(()=>{A.removeEventListener("click",M)}),Yt(A)}function Zt(){V&&V.parentNode&&V.parentNode.removeChild(V),V=null;let A=t.querySelector("[data-nojs-load-more]");A&&A.parentNode&&A.parentNode.removeChild(A)}function lr(){if(typeof IntersectionObserver>"u"){w('IntersectionObserver not available, get-trigger="scroll" falling back to button trigger'),cr();return}Ne=new IntersectionObserver(A=>{for(let M of A)if(M.isIntersecting&&t.isConnected&&!Re&&!we){Ee();break}},{rootMargin:z}),k&&Ne.observe(k),D(()=>{Ne&&(Ne.disconnect(),Ne=null)})}function Tn(){Re=!1,we=!1,N?O.$set("cursor",""):$&&O.$set("page",j),Zt(),xe(),c==="scroll"&&k&&(Ne&&Ne.disconnect(),Ne=null,lr())}if(t.tagName==="FORM"&&e!=="get"){let A=M=>{M.preventDefault(),Ee()};t.addEventListener("submit",A),D(()=>t.removeEventListener("submit",A))}else if(m){if(c!=="none")if(c==="visible")if(typeof IntersectionObserver<"u"){let A=new IntersectionObserver(M=>{for(let ae of M)if(ae.isIntersecting&&t.isConnected){A.disconnect(),Ee();break}},{rootMargin:z});A.observe(t),D(()=>A.disconnect())}else w('IntersectionObserver not available, get-trigger="visible" falling back to immediate fetch'),queueMicrotask(()=>{t.isConnected&&Ee()});else if(c==="scroll"&&U)queueMicrotask(()=>{t.isConnected&&Ee()});else if(c==="scroll"&&!U)if(typeof IntersectionObserver<"u"){let A=new IntersectionObserver(M=>{for(let ae of M)if(ae.isIntersecting&&t.isConnected){A.disconnect(),Ee();break}},{rootMargin:z});A.observe(t),D(()=>A.disconnect())}else queueMicrotask(()=>{t.isConnected&&Ee()});else if(c==="button"&&U)queueMicrotask(()=>{t.isConnected&&Ee()});else if(c==="button"&&!U)queueMicrotask(()=>{t.isConnected&&Ee()});else if(c==="hover"){let A=L<=0,M=()=>{Ee()};A?t.addEventListener("mouseenter",M,{once:!0}):t.addEventListener("mouseenter",M),D(()=>t.removeEventListener("mouseenter",M))}else queueMicrotask(()=>{t.isConnected&&Ee()})}else{let A=M=>{M.preventDefault(),Ee()};t.addEventListener("click",A),D(()=>t.removeEventListener("click",A))}if(/\{[^}]+\}/.test(r)&&c!=="none"){let Se=function(){let $e=Ue(r,O);if($e!==M){if(M=$e,X&&U&&Z){let ke=Ue(Z,O);if(ke!==Ce){Ce=ke,ae&&clearTimeout(ae),A>0?ae=setTimeout(()=>{Tn(),Ee()},A):(Tn(),Ee());return}}ae&&clearTimeout(ae),A>0?ae=setTimeout(Ee,A):Ee()}},A=parseInt(t.getAttribute("debounce"))||0,M=Ue(r,O),ae=null,Fe=$||N,Z=N?r.replace(/\{cursor\}/g,"__CURSOR__"):$?r.replace(/\{page\}/g,"__PAGE__"):null,Ce=Z?Ue(Z,O):null;D(()=>{ae&&clearTimeout(ae)});let Ie=be;for(;Ie&&Ie.__isProxy;){let $e=Ie.$watch(Se);D($e),Ie=Ie.$parent}if(r.includes("$store")){let $e=yt(r)||"*";Bt(Se,$e),Se._el=fe,D(()=>ut(Se))}r.includes("$route")&&(Ut(Se),Se._el=fe,D(()=>bt(Se))),r.includes("$i18n")&&(ot(Se),Se._el=fe,D(()=>We.delete(Se)))}if(y&&c!=="none"){let Fe=function(){let Ce="";try{let Se=R(y,O);Ce=JSON.stringify(Se)||""}catch{return}Ce!==M&&(M=Ce,ae&&clearTimeout(ae),A>0?ae=setTimeout(Ee,A):Ee())},A=parseInt(t.getAttribute("debounce"))||0,M="";try{let Ce=R(y,O);M=JSON.stringify(Ce)||""}catch{}let ae=null;D(()=>{ae&&clearTimeout(ae)});let Z=be;for(;Z&&Z.__isProxy;){let Ce=Z.$watch(Fe);D(Ce),Z=Z.$parent}}if(X&&U?t.refresh=function(){Tn(),Ee()}:U?t.refresh=function(){xe(),Ee()}:t.refresh=Ee,D(()=>{delete t.refresh}),L>0&&!re){let A=setInterval(()=>{if(!t.isConnected){clearInterval(A);return}Ee()},L);D(()=>clearInterval(A))}}});ge();var An=new Map;function To(e,t){let n=An.get(e);n||(n=new Set,An.set(e,n)),n.add(t),n.size>=6&&w("SSE: "+n.size+" connections to "+e+". Browsers limit HTTP/1.1 to 6 concurrent connections per origin. Consider HTTP/2 or reducing open streams.")}function _i(e,t){let n=An.get(e);n&&(n.delete(t),n.size===0&&An.delete(e))}F("sse",{priority:1,gated:!0,init(e,t,n){let r=e.getAttribute("as")||"data",i=e.getAttribute("sse-event")||null,o=e.getAttribute("sse-insert"),s=o==="append"||o==="prepend"?o:"replace",a=e.getAttribute("sse-limit"),l=a?parseInt(a,10):0,u=e.hasAttribute("sse-credentials"),d=e.getAttribute("into"),p=e.getAttribute("error"),b=e.getAttribute("then");l>0&&s==="replace"&&w("sse-limit has no effect without sse-insert (append or prepend)."),s!=="replace"&&!l&&w('sse-insert="'+s+'" without sse-limit may cause unbounded memory growth on long-lived streams. Set sse-limit to cap the array.');let E=e.parentElement?H(e.parentElement):q(),L=e.__ctx||q({},E);e.__ctx=L,s!=="replace"&&L.$set(r,[]),L.$set("$sse",{connecting:!0,open:!1,error:!1});let C=null,I=null,W=null;function ce(g,S,c){L.$set("$sse",{connecting:g,open:S,error:c})}function T(){C&&(C.close(),I&&_i(I,C),C=null,I=null)}function h(){if(!p)return;let g=ye(p);if(!g)return;let c=document.getElementById(p.replace("#",""))?.getAttribute("var")||"err",f=q({[c]:{message:"SSE connection closed"}},L),m=document.createElement("div");m.style.display="contents",m.__ctx=f,m.appendChild(g),ie(e),e.innerHTML="",e.appendChild(m),K(m)}function v(g){T(),s!=="replace"&&L.$set(r,[]),ce(!0,!1,!1),W=g;try{I=new URL(g,window.location.origin).origin}catch{I=window.location.origin}let S=new EventSource(g,{withCredentials:u});C=S,To(I,S),D(()=>{S.close(),I&&_i(I,S)}),S.onopen=function(){if(!e.isConnected){S.close();return}ce(!1,!0,!1)},S.onerror=function(){if(!e.isConnected){S.close();return}S.readyState===EventSource.CLOSED?(ce(!1,!1,!0),h()):ce(!0,!1,!1)};function c(m){if(!e.isConnected){S.close();return}let P;try{P=JSON.parse(m.data)}catch{P=m.data}if(s==="append"){let N=Array.isArray(L[r])?[...L[r]]:[];N.push(P),l>0&&N.length>l&&N.shift(),L.$set(r,N)}else if(s==="prepend"){let N=Array.isArray(L[r])?[...L[r]]:[];N.unshift(P),l>0&&N.length>l&&N.pop(),L.$set(r,N)}else L.$set(r,P);if(d&&(se[d]||(se[d]=q({})),se[d].$set(r,L[r]),Ve(d)),b)try{Le(b,L,{$event:P})}catch(N){w("sse then expression error:",N.message)}}let f=i||"message";S.addEventListener(f,c)}let x=Ue(n,L);if(v(x),/\{[^}]+\}/.test(n)){let g=function(){let c=Ue(n,L);c!==W&&v(c)},S=E;for(;S&&S.__isProxy;){let c=S.$watch(g);D(c),S=S.$parent}if(n.includes("$store")){let c=yt(n)||"*";Bt(g,c),g._el=fe,D(()=>ut(g))}n.includes("$route")&&(Ut(g),g._el=fe,D(()=>bt(g))),n.includes("$i18n")&&(ot(g),g._el=fe,D(()=>We.delete(g)))}}});ge();F("bind",{priority:20,gated:!0,init(e,t,n){let r=H(e),i;function o(){let s=R(n,r),a=s!=null?String(s):"";a!==i&&(i=a,e.textContent=a)}de(n,r,o),o()}});F("bind-html",{priority:20,gated:!0,init(e,t,n){let r=H(e);(_.debug||_.devtools)&&!/^['"`]/.test(n.trim())&&w(`[Security] bind-html used with dynamic expression: "${n}". Ensure the value is trusted or sanitized \u2014 use bind for plain text.`,e);let i;function o(){let s=R(n,r);if(s!=null){let a=String(s);if(a===i)return;i=a,ie(e),e.innerHTML=_n(a)}}de(n,r,o),o()}});var Lo=new Set(["href","src","action","formaction","poster","data"]);function yi(e){let n=new DOMParser().parseFromString(e,"image/svg+xml").documentElement;if(n.querySelector("parsererror")||n.nodeName!=="svg"||n.getElementsByTagNameNS("http://www.mozilla.org/newlayout/xml/parsererror.xml","parsererror").length)return"";function r(i){for(let o of[...i.attributes]){let s=o.name.toLowerCase();if(s.startsWith("on")){i.removeAttribute(o.name);continue}if(s==="href"||s==="xlink:href"){let a=o.value.toLowerCase().replace(/[\u0000-\u0020]/g,"");/^(javascript|vbscript):/.test(a)&&i.removeAttribute(o.name)}}}for(let i of[...n.querySelectorAll("script")])i.remove();r(n);for(let i of n.querySelectorAll("*"))r(i);return new XMLSerializer().serializeToString(n)}function Oo(e){try{let t=e.match(/^data:image\/svg\+xml;base64,(.+)$/i);if(t){let o=yi(atob(t[1]));return"data:image/svg+xml;base64,"+btoa(o)}let n=e.indexOf(",");if(n===-1)return"#";let r=e.slice(0,n+1),i=yi(decodeURIComponent(e.slice(n+1)));return r+encodeURIComponent(i)}catch{return"#"}}function No(e,t){if(Lo.has(e)){let n=String(t).trimStart(),r=n.toLowerCase().replace(/[\u0000-\u0020]/g,"");if(/^(javascript|vbscript):/.test(r))return"#";if(/^data:/.test(r)){if(/^data:image\/svg\+xml/.test(r))return Oo(n);if(!/^data:image\//.test(r))return"#"}}return t}var Po=new Set(["disabled","readonly","checked","selected","hidden","required"]);F("bind-*",{priority:20,init(e,t,n){let r=t.replace("bind-",""),i=H(e);if(r==="value"&&(e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.tagName==="SELECT")){let a=()=>{let l;if(e.type==="number"){if(e.value===""||isNaN(e.valueAsNumber))return;l=e.valueAsNumber}else l=e.value;Le(`${n} = __val`,i,{__val:l})};e.addEventListener("input",a),D(()=>e.removeEventListener("input",a))}let o;function s(){let a=R(n,i);if(Po.has(r)){let u=!!a,d=r in e?!!e[r]:e.hasAttribute(r);if(u===o&&d===u)return;o=u,u?e.setAttribute(r,""):e.removeAttribute(r),r in e&&(e[r]=u);return}let l=a!=null?String(No(r,a)):null;l===o&&e.getAttribute(r)===l||(o=l,l!=null?e.setAttribute(r,l):e.removeAttribute(r))}de(n,i,s),s()}});F("model",{priority:20,gated:!0,init(e,t,n){let r=H(e),i=e.tagName,o=e.type;function s(){let u=R(n,r);if(i==="INPUT"&&o==="checkbox")e.checked=!!u;else if(i==="INPUT"&&o==="radio")e.checked=e.value===String(u);else if(i==="SELECT")e.value=u!=null?String(u):"";else{let d=u!=null?String(u):"";if(document.activeElement===e){if(o==="number"||o==="range"){let p=e.valueAsNumber;if(u!=null&&!isNaN(p)&&p===Number(u))return}else if(e.value===d)return}e.value=d}}let a=i==="SELECT"||o==="checkbox"||o==="radio"?"change":"input",l=()=>{let u;o==="checkbox"?u=e.checked:o==="number"||o==="range"?u=Number(e.value):u=e.value,Le(`${n} = __val`,r,{__val:u})};e.addEventListener(a,l),D(()=>e.removeEventListener(a,l)),de(n,r,s),s()}});ge();function bi(e){let t=[],n=e.previousElementSibling;for(;n;){let r=n.getAttribute("if")||n.getAttribute("else-if");if(r)t.push(r);else break;n=n.previousElementSibling}return t}F("if",{priority:10,init(e,t,n){let r=H(e),i=e.getAttribute("then"),o=e.getAttribute("else"),s=e.getAttribute("animate-enter")||e.getAttribute("animate"),a=e.getAttribute("animate-leave"),l=e.getAttribute("transition"),u=parseInt(e.getAttribute("animate-duration"))||0,d=(e.__i18nSavedChildren||[...e.childNodes]).map(C=>C.cloneNode(!0)),p,b=null;D(()=>{b&&(b(),b=null)});function E(){let C=!!R(n,r);C!==p&&(p=C,a||l?(b&&(b(),b=null),b=wn(e,a,l,()=>{b=null,L(C)},u)):L(C))}function L(C){if(e.__ifState=C,C||ci(e),ie(e),C)if(i){let I=ye(i);I&&(e.innerHTML="",e.appendChild(I))}else{e.innerHTML="";for(let I of d)e.appendChild(I.cloneNode(!0))}else if(o){let I=ye(o);I&&(e.innerHTML="",e.appendChild(I))}else e.innerHTML="";ze(e),K(e),C&&ai(e),(s||l)&&Ct(e,s,l,u)}de(n,r,E),E()}});F("else-if",{priority:10,init(e,t,n){if(qe(e))return;let r=H(e),i=e.getAttribute("then"),o=[...e.childNodes].map(u=>u.cloneNode(!0)),s;function a(){let u=e.previousElementSibling;for(;u;){let b=u.getAttribute("if")||u.getAttribute("else-if");if(b){if(R(b,r)){if(s==="hidden")return;s="hidden",ie(e),e.innerHTML="",e.style.display="none";return}}else break;u=u.previousElementSibling}let d=!!R(n,r),p=d?"shown":"hidden";if(p!==s)if(s=p,e.style.display="",d){if(i){let b=ye(i);b&&(ie(e),e.innerHTML="",e.appendChild(b))}else{ie(e),e.innerHTML="";for(let b of o)e.appendChild(b.cloneNode(!0))}ze(e),K(e)}else ie(e),e.innerHTML=""}let l=bi(e);l.push(n),de(l.join(" "),r,a),a()}});F("else",{priority:10,init(e){if(e.hasAttribute("if")||qe(e))return;let t=H(e),n=e.getAttribute("then"),r=[...e.childNodes].map(a=>a.cloneNode(!0)),i,o=!1;function s(){let a=e.previousElementSibling,l=!1;for(;a;){let u=a.getAttribute("if")||a.getAttribute("else-if");if(u){if(l=!0,R(u,t)){if(i==="hidden")return;i="hidden",ie(e),e.innerHTML="",e.style.display="none";return}}else break;a=a.previousElementSibling}if(!l&&!o&&(o=!0,w('else: no preceding if/else-if sibling found \u2014 note the sibling else pattern for loops was removed in v1.15; use else="templateId" on the loop element',e)),i!=="shown"){if(i="shown",e.style.display="",n){let u=ye(n);u&&(ie(e),e.innerHTML="",e.appendChild(u))}else{ie(e),e.innerHTML="";for(let u of r)e.appendChild(u.cloneNode(!0))}ze(e),K(e)}}de(bi(e).join(" "),t,s),s()}});F("show",{priority:20,init(e,t,n){let r=H(e),i=e.getAttribute("animate-enter")||e.getAttribute("animate"),o=e.getAttribute("animate-leave"),s=e.getAttribute("transition"),a=parseInt(e.getAttribute("animate-duration"))||0,l;function u(){let d=!!R(n,r);d!==l&&(l=d,d?(e.style.display="",(i||s)&&Ct(e,i,s,a)):o||s?wn(e,o,s,()=>{e.style.display="none"},a):e.style.display="none")}de(n,r,u),u()}});F("hide",{priority:20,init(e,t,n){let r=H(e),i=e.getAttribute("animate-enter")||e.getAttribute("animate"),o=e.getAttribute("animate-leave"),s=e.getAttribute("transition"),a=parseInt(e.getAttribute("animate-duration"))||0,l;function u(){let d=!R(n,r);d!==l&&(l=d,d?(e.style.display="",(i||s)&&Ct(e,i,s,a)):o||s?wn(e,o,s,()=>{e.style.display="none"},a):e.style.display="none")}de(n,r,u),u()}});F("animate",{priority:15,init(e,t,n){if(e.hasAttribute("if")||e.hasAttribute("show")||e.hasAttribute("hide"))return;let r=e.getAttribute("animate-enter")||n,i=e.getAttribute("transition"),o=parseInt(e.getAttribute("animate-duration"))||0;(r||i)&&Ct(e,r,i,o,!0)}});function Io(e){let t=[],n=0,r=null,i=0;for(let o=0;o=0&&e[l]==="\\";l--)a++;a%2===0&&(r=null)}}else s==="'"||s==='"'||s==="`"?r=s:s==="("||s==="["||s==="{"?n++:s===")"||s==="]"||s==="}"?n--:s===","&&n===0&&(t.push(e.slice(i,o)),i=o+1)}return t.push(e.slice(i)),t}F("switch",{priority:10,init(e,t,n){let r=H(e);function i(){let o=R(n,r),s=!1;for(let a of[...e.children]){let l=a.getAttribute("case"),u=a.hasAttribute("default"),d=a.getAttribute("then");if(l){let p=Io(l).map(b=>R(b.trim(),r));if(!s&&p.includes(o))if(s=!0,a.style.display="",d){let b=ye(d);b&&(ie(a),a.innerHTML="",a.appendChild(b)),a.__declared=!1,K(a)}else a.__switchDisposed&&(a.__switchDisposed=!1,a.__declared=!1,K(a));else ie(a),a.__switchDisposed=!0,a.style.display="none"}else if(u)if(s&&(ie(a),a.__switchDisposed=!0),a.style.display=s?"none":"",!s&&d){let p=ye(d);p&&(ie(a),a.innerHTML="",a.appendChild(p)),a.__declared=!1,K(a)}else!s&&a.__switchDisposed&&(a.__switchDisposed=!1,a.__declared=!1,K(a))}}de(n,r,i),i()}});ge();ge();F("class-*",{priority:20,init(e,t,n){let r=t.replace("class-",""),i=H(e);if(r==="map"){let a=function(){let l=R(n,i);if(l&&typeof l=="object")for(let[u,d]of Object.entries(l))u.split(/\s+/).filter(Boolean).forEach(b=>e.classList.toggle(b,!!d))};de(n,i,a),a();return}if(r==="list"){let l=function(){let u=R(n,i);if(Array.isArray(u)){a.forEach(p=>{p&&e.classList.remove(p)});let d=u.filter(Boolean);d.forEach(p=>e.classList.add(p)),a=d}},a=[];de(n,i,l),l();return}let o=null;function s(){let a=!!R(n,i);a===o&&e.classList.contains(r)===a||(o=a,e.classList.toggle(r,a))}de(n,i,s),(n.includes("NoJS.locale")||n.includes("window.NoJS.locale"))&&ot(s),s()}});F("style-*",{priority:20,init(e,t,n){let r=t.replace("style-",""),i=H(e);if(r==="map"){let d=function(){let p=R(n,i);if(p&&typeof p=="object"){let b=Object.keys(p);for(let E of u)E in p||(E.startsWith("--")?e.style.removeProperty(E):e.style[E]="");for(let[E,L]of Object.entries(p))E.startsWith("--")?e.style.setProperty(E,L??""):e.style[E]=L??"";u=b}},u=[];de(n,i,d),d();return}let o=r.startsWith("--"),s=o?r:r.replace(/-([a-z])/g,(u,d)=>d.toUpperCase()),a;function l(){let u=R(n,i),d=u!=null?String(u):"";d===a&&e.style.getPropertyValue(r)===d||(a=d,o?e.style.setProperty(s,d):e.style[s]=d)}de(n,i,l),l()}});ge();var $o=new Set(["mounted","init","updated","error","unmounted"]);F("on:*",{priority:20,gated:!0,init(e,t,n){let r=H(e);if(t.indexOf(".")===-1&&!e.__gatedDirs){let E=t.slice(3);if(!$o.has(E)){let L=I=>Le(n,r,{$event:I,$el:e});e.addEventListener(E,L);let C=()=>e.removeEventListener(E,L);C._elOnly=!0,D(C);return}}let i=t.replace("on:","").split("."),o=i[0],s=new Set(i.slice(1));if(o==="mounted"){requestAnimationFrame(()=>Le(n,r,{$el:e}));return}if(o==="init"){Le(n,r,{$el:e});return}if(o==="updated"){let E=!1,L=new MutationObserver(()=>{if(!e.isConnected){L.disconnect();return}if(!E){E=!0;try{Le(n,r,{$el:e})}finally{Promise.resolve().then(()=>{E=!1})}}});L.observe(e,{childList:!0,subtree:!0,characterData:!0,attributes:!0}),D(()=>L.disconnect());return}if(o==="error"){let E=L=>{(e.contains(L.target)||L.target===e)&&Le(n,r,{$el:e,$error:L.error||L.message})};window.addEventListener("error",E),D(()=>window.removeEventListener("error",E));return}if(o==="unmounted"){let E=new MutationObserver(L=>{for(let C of L)for(let I of C.removedNodes)if(I===e||I.contains?.(e)){Le(n,r,{$el:e}),E.disconnect();return}});e.parentElement&&E.observe(e.parentElement,{childList:!0,subtree:!0}),D(()=>E.disconnect());return}let a=0,l=0,u=i.slice(1);for(let E=0;E{Le(n,r,{$event:E,$el:e})};if(a>0){let E=d,L;d=C=>{clearTimeout(L),L=setTimeout(()=>E(C),a)},D(()=>clearTimeout(L))}if(l>0){let E=d,L=0;d=C=>{let I=Date.now();I-L>=l&&(L=I,E(C))}}let p=E=>{if(o==="keydown"||o==="keyup"||o==="keypress"){let L=["enter","escape","tab","space","delete","backspace","up","down","left","right","ctrl","alt","shift","meta"];for(let C of s)if(L.includes(C)&&(C==="enter"&&E.key!=="Enter"||C==="escape"&&E.key!=="Escape"||C==="tab"&&E.key!=="Tab"||C==="space"&&E.key!==" "||C==="delete"&&E.key!=="Delete"&&E.key!=="Backspace"||C==="backspace"&&E.key!=="Backspace"||C==="up"&&E.key!=="ArrowUp"||C==="down"&&E.key!=="ArrowDown"||C==="left"&&E.key!=="ArrowLeft"||C==="right"&&E.key!=="ArrowRight"||C==="ctrl"&&!E.ctrlKey||C==="alt"&&!E.altKey||C==="shift"&&!E.shiftKey||C==="meta"&&!E.metaKey))return}s.has("prevent")&&E.preventDefault(),s.has("stop")&&E.stopPropagation(),!(s.has("self")&&E.target!==e)&&d(E)},b={};if(s.has("once")&&(b.once=!0),e.addEventListener(o,p,b),!b.once){let E=()=>e.removeEventListener(o,p,b);E._elOnly=!0,D(E)}}});F("trigger",{priority:20,init(e,t,n){let r=H(e),i=e.getAttribute("trigger-data"),o=()=>{let a=i?R(i,r):null;e.dispatchEvent(new CustomEvent(n,{detail:a,bubbles:!0}))};e.addEventListener("click",o);let s=()=>e.removeEventListener("click",o);s._elOnly=!0,D(s)}});ge();F("ref",{priority:5,init(e,t,n){it[n]=e,D(()=>{it[n]===e&&delete it[n]})}});F("use",{priority:9,init(e,t,n){let r=H(e),i=ye(n);if(!i)return;let o={};for(let d of[...e.attributes])if(d.name.startsWith("var-")){let p=d.name.replace("var-","");o[p]=R(d.value,r)}let s=q(o,r),a={};for(let d of[...e.children]){let p=d.getAttribute("slot")||"default";a[p]||(a[p]=document.createDocumentFragment()),a[p].appendChild(d.cloneNode(!0))}let l=i.querySelectorAll("slot");for(let d of l){let p=d.getAttribute("name")||"default";a[p]&&d.replaceWith(a[p])}ie(e),e.innerHTML="";let u=document.createElement("div");u.style.display="contents",u.__ctx=s,u.appendChild(i),e.appendChild(u),K(u)}});F("call",{priority:20,init(e,t,n){let r=H(e),i=e.getAttribute("method")||"get",o=e.getAttribute("as")||"data",s=e.getAttribute("into"),a=e.getAttribute("success"),l=e.getAttribute("error"),u=e.getAttribute("loading"),d=e.getAttribute("then"),p=e.getAttribute("confirm"),b=e.getAttribute("body"),E=e.getAttribute("redirect"),L=e.getAttribute("headers"),C=[...e.childNodes].map(h=>h.cloneNode(!0)),I=null,W=null;function ce(){W&&(ie(W),W.remove(),W=null)}D(ce);let T=async h=>{if(h.preventDefault(),p&&!window.confirm(p))return;I&&I.abort(),I=new AbortController;let v=Ue(n,r);if(u){let x=ye(u);x&&(ie(e),e.innerHTML="",e.appendChild(x),K(e),e.disabled=!0)}try{let x=null;if(b){let S=Ue(b,r);try{x=JSON.parse(S)}catch{x=S}}let y=L?JSON.parse(L):{};if(L)for(let S of Object.keys(y)){let c=S.toLowerCase();(Tt.has(c)||/^x-(auth|api)-/.test(c))&&w(`Sensitive header "${S}" is set inline on a headers attribute. Use NoJS.config({ headers }) or an interceptor to avoid exposing credentials in HTML source.`)}let g=await gn(v,i,x,y,e,I.signal);if(u){ie(e),e.innerHTML="";for(let S of C)e.appendChild(S.cloneNode(!0));ze(e),K(e),e.disabled=!1}if(o&&r.$set(o,g),s&&(se[s]||(se[s]=q({})),se[s].$set(o,g),Ve(s)),d&&Le(d,r,{result:g}),a){let S=ye(a),c=e.closest("[route-view]")||e.parentElement;if(S&&c){let m=document.getElementById(a.replace("#",""))?.getAttribute("var")||"result",P=q({[m]:g},r);ce();let N=document.createElement("div");N.style.display="contents",N.__ctx=P,N.appendChild(S),c.appendChild(N),W=N,K(N)}}E&&me&&me.push(E),Ge("fetch:success",{url:v,data:g}),Te("fetch:success",{method:i,url:v})}catch(x){if(x.name==="AbortError")return;if(w(`call ${i.toUpperCase()} ${v} failed:`,x.message),u){ie(e),e.innerHTML="";for(let y of C)e.appendChild(y.cloneNode(!0));ze(e),K(e),e.disabled=!1}if(Ge("fetch:error",{url:v,error:x}),Ge("error",{url:v,error:x}),Te("fetch:error",{method:i,url:v,error:x.message}),l){let y=ye(l),g=e.closest("[route-view]")||e.parentElement;if(y&&g){let c=document.getElementById(l.replace("#",""))?.getAttribute("var")||"err",f=q({[c]:{message:x.message,status:x.status,body:x.body}},r);ce();let m=document.createElement("div");m.style.display="contents",m.__ctx=f,m.appendChild(y),g.appendChild(m),W=m,K(m)}}}};e.addEventListener("click",T),D(()=>e.removeEventListener("click",T))}});ge();var ko=Object.freeze({valid:!0,dirty:!1,touched:!1,error:null,value:""}),Ro=new Proxy({},{get:()=>ko});F("validate",{priority:30,init(e,t){w('[NoJS] "validate" has moved to @no-js-dev/nojs-elements. Install the plugin and call NoJS.use(NoJSElements) to enable it.');let n=H(e);n.$form={valid:!1,dirty:!1,touched:!1,submitting:!1,pending:!1,errors:{},values:{},firstError:null,errorCount:0,fields:Ro,reset(){}};let r=e.tagName==="FORM"?e:e.closest("form");if(r){let i=o=>{o.preventDefault(),w('[NoJS] Form submission blocked \u2014 "validate" requires @no-js-dev/nojs-elements.')};r.addEventListener("submit",i),D(()=>r.removeEventListener("submit",i))}}});ge();F("error-boundary",{priority:1,init(e,t,n){let r=H(e),i=!1;function o(l){if(i){w("error-boundary: secondary error inside fallback (suppressed to prevent infinite recursion):",l);return}i=!0;try{let u=ye(n);if(u){let d=q({err:{message:l}},r);ie(e),e.innerHTML="";let p=document.createElement("div");p.style.display="contents",p.__ctx=d,p.appendChild(u),e.appendChild(p),K(p)}}finally{i=!1}}let s=l=>{o(l.detail?.message||"An error occurred")};e.addEventListener("nojs:error",s),D(()=>e.removeEventListener("nojs:error",s));let a=l=>{l.target===window?e.isConnected&&o(l.message||"An error occurred"):(e.contains(l.target)||e===l.target)&&o(l.message||"An error occurred")};window.addEventListener("error",a,{capture:!0}),D(()=>window.removeEventListener("error",a,{capture:!0}))}});st();ge();F("t",{priority:20,gated:!0,init(e,t,n){let r=H(e),i=e.hasAttribute("t-html"),o=[];for(let l of[...e.attributes])l.name.startsWith("t-")&&l.name!=="t"&&l.name!=="t-html"&&o.push(l.value);let s=o.length?n+" "+o.join(" "):n;function a(){let l={};for(let d of[...e.attributes])if(d.name.startsWith("t-")&&d.name!=="t"&&d.name!=="t-html"){let p=d.name.replace("t-","");l[p]=R(d.value,r)??d.value}let u=he.t(n,l);i?(ie(e),e.innerHTML=_n(u)):e.textContent=u}de(s,r,a),ot(a),a()}});F("i18n-ns",{priority:1,init(e,t,n){if(!n)return;e.__i18nSavedChildren=[...e.childNodes].map(i=>i.cloneNode(!0));let r=document.createDocumentFragment();for(;e.firstChild;)r.appendChild(e.firstChild);jn(n).then(()=>{if(e.__ifState!==void 0){Ot();return}e.appendChild(r),K(e),Ot()})}});ge();var Do=e=>`[NoJS] "${e}" has moved to @no-js-dev/nojs-elements. Install the plugin and call NoJS.use(NoJSElements) to enable it.`;for(let e of["drag","drop","drag-list","drag-multiple"])F(e,{priority:e==="drag-multiple"?16:e==="drag-list"?10:15,init(t,n){w(Do(n))}});ge();function jo(e,t){return e.replace(/\{\s*([^}"'{\s][^}]*)\}/g,(n,r)=>{try{let i=R(r.trim(),t);return i!=null?String(i):""}catch{return""}})}F("page-title",{priority:1,gated:!0,init(e,t,n){if(qe(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=H(e);function i(){let o=R(n,r);o!=null&&(document.title=String(o))}de(n,r,i),i()}});F("page-description",{priority:1,gated:!0,init(e,t,n){if(qe(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=H(e),i=!1,o=null;function s(){let a=R(n,r);if(a==null)return;let l=document.querySelector('meta[name="description"]');l||(l=document.createElement("meta"),l.name="description",document.head.appendChild(l),i=!0),o=l,l.content=String(a)}de(n,r,s),s(),D(()=>{i&&o&&o.isConnected&&o.remove()})}});F("page-canonical",{priority:1,gated:!0,init(e,t,n){if(qe(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=H(e),i=!1,o=null;function s(){let a=R(n,r);if(a==null)return;let l=document.querySelector('link[rel="canonical"]');l||(l=document.createElement("link"),l.rel="canonical",document.head.appendChild(l),i=!0);let u=String(a);/^\s*(javascript|vbscript|data):/i.test(u)||(o=l,l.href=u)}de(n,r,s),s(),D(()=>{i&&o&&o.isConnected&&o.remove()})}});F("page-jsonld",{priority:1,gated:!0,init(e,t,n){if(qe(e)){w(`${t}: head directive on a loop element is not supported \u2014 move it to a parent or child element`,e);return}let r=H(e),i=(e.textContent||e.innerHTML).trim();if(!i)return;let o=!1,s=null;function a(){let l=jo(i,r);if(!l)return;let u=document.querySelector('script[type="application/ld+json"][data-nojs]');u||(u=document.createElement("script"),u.type="application/ld+json",u.setAttribute("data-nojs",""),document.head.appendChild(u),o=!0),s=u,u.textContent=l.replace(/<\//g,"<\\/")}de(i,r,a),a(),D(()=>{o&&s&&s.isConnected&&s.remove()})}});ri();var Ye=null,or=!1,Mo=new Set(["store","route","router","i18n","refs","form","sse","parent","watch","set","notify","raw","isProxy","listeners","app","config","env","debug","version","plugins","globals","el","event","self","this","super","window","document","toString","valueOf","hasOwnProperty"]),Fo=typeof window<"u"?new Set([eval,Function,window.eval,window.Function].filter(Boolean)):new Set;function wi(e){return Fo.has(e)}var Ho=new Set(["__proto__","constructor","prototype"]),Bo=new Set(["uppercase","lowercase","capitalize","truncate","trim","stripHtml","slugify","nl","nl2br","encodeUri","number","currency","percent","filesize","ordinal","count","first","last","join","reverse","unique","sortBy","where","pluck","keys","values","json","debug","default","date","datetime","relative","fromNow"]),Uo=new Set(["required","email","url","min","max","minlength","maxlength","pattern","match","number","integer","alpha","alphanumeric"]);function sr(e,t=new Set){if(!(!e||typeof e!="object"||t.has(e))){t.add(e);for(let n of Object.keys(e))if(Ho.has(n))throw w("NoJS.global(): value contains a forbidden key: "+n),new Error("unsafe_global");for(let n of Object.values(e)){if(wi(n))throw w("NoJS.global(): value contains a forbidden reference (eval/Function)."),new Error("unsafe_global");n&&typeof n=="object"&&sr(n,t)}}}function zo(){return typeof window>"u"?null:(_.router||{}).useHash?window.location.hash.slice(1)||"/":Ht(window.location.pathname)}var et={get baseApiUrl(){return _.baseApiUrl},set baseApiUrl(e){_.baseApiUrl=e},get locale(){return he.locale},set locale(e){he.locale=e},config(e={}){if(or){let s=["sanitize","dangerouslyDisableSanitize","sanitizeHtml"];for(let a of s)a in e&&(w(`config.${a} cannot be changed after init()`),delete e[a])}let t={..._.headers},n={..._.cache},r={..._.templates},i={..._.router},o={..._.i18n};if("csp"in e&&(w("csp config option removed \u2014 No.JS is now CSP-safe by default"),delete e.csp),e.exprCacheSize!==void 0){let s=parseInt(e.exprCacheSize);e.exprCacheSize=Number.isFinite(s)&&s>0?s:500}if(Object.assign(_,e),e.sanitize===!1&&w("sanitize:false is deprecated \u2014 use dangerouslyDisableSanitize:true to make the risk explicit."),e.headers&&(_.headers={...t,...e.headers}),e.csrf&&(_.csrf=e.csrf),e.cache&&(_.cache={...n,...e.cache}),e.templates&&(_.templates={...r,...e.templates}),e.router&&("mode"in e.router&&!("useHash"in e.router)&&(te('router.mode is deprecated. Use router.useHash instead: mode: "hash" \u2192 useHash: true, mode: "history" \u2192 useHash: false',"warn"),e.router.useHash=e.router.mode==="hash",delete e.router.mode),_.router={...i,...e.router}),e.i18n&&(_.i18n={...o,...e.i18n},he.locale=e.i18n.defaultLocale||he.locale),e.stores){for(let[s,a]of Object.entries(e.stores))se[s]||(se[s]=q(a||{}),Te("store:created",{name:s,keys:Object.keys(a||{})}));delete _.stores}},use(e,t={}){if(en){w("Cannot install plugins during dispose.");return}if(typeof e=="function"){if(!e.name||e.name==="anonymous"){w('Plugin must have a unique, non-empty name. Use { name: "my-plugin", install: fn }.');return}e={name:e.name,install:e}}if(!e.name||typeof e.name!="string"||e.name==="anonymous"){w("Plugin must have a unique, non-empty name.");return}if(Je.has(e.name)){Je.get(e.name).plugin!==e&&w(`Plugin "${e.name}" name collision: a different plugin with this name is already installed.`);return}e.capabilities&&_.debug&&te(`Plugin "${e.name}" declares capabilities:`,e.capabilities),t.trusted===!0&&w(`WARNING: Plugin "${e.name}" installed with trusted access to sensitive HTTP headers.`),$n(e.name);try{e.install(et,t)}finally{$n(null)}Je.set(e.name,{plugin:e,options:t}),Ye&&e.init&&Ye.then(()=>e.init(et)).catch(n=>w(`Plugin "${e.name}" init error:`,n.message)),te(`Plugin "${e.name}" installed.`)},global(e,t){if(typeof e!="string"||!e){w("NoJS.global() requires a non-empty string name.");return}if(e==="__proto__"||e==="constructor"||e==="prototype"){w(`NoJS.global(): "${e}" is a forbidden name.`);return}if(Mo.has(e)){w(`NoJS.global(): "${e}" is reserved and cannot be used.`);return}if(!/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)){w(`NoJS.global(): "${e}" is not a valid identifier.`);return}if(wi(t)){w(`NoJS.global(): value for "${e}" is a forbidden reference (eval/Function).`);return}if(e in De&>[e]&>[e]!==_t&&w(`Global "$${e}" owned by "${gt[e]}" is being overwritten.`),t&&typeof t=="object"&&!t.__isProxy){try{t=JSON.parse(JSON.stringify(t))}catch{try{sr(t)}catch(n){if(n.message==="unsafe_global")return}}t=q(t)}else if(t&&typeof t=="object"&&t.__isProxy)try{sr(t.__raw??t)}catch(n){if(n.message==="unsafe_global")return}De[e]=t,_t&&(gt[e]=_t),Ve(),Te("global:set",{name:e,hasValue:t!=null}),te(`Global "$${e}" registered.`)},async dispose(){In(!0);try{if(Ye)try{await Ye}catch{}let e=[...Je.entries()].reverse();for(let[t,{plugin:n}]of e)if(n.dispose)try{let r;await Promise.race([Promise.resolve(n.dispose(et)).finally(()=>clearTimeout(r)),new Promise((i,o)=>{r=setTimeout(()=>o(new Error("Dispose timeout")),3e3)})])}catch(r){w(`Plugin "${t}" dispose error:`,r.message)}Je.clear();for(let t in De)delete De[t];for(let t in gt)delete gt[t];Ke.request.length=0,Ke.response.length=0,me&&me.destroy&&me.destroy(),kn(null),Pr(),or=!1,Ye=null,te("Disposed.")}finally{In(!1)}},async init(e){if(!(typeof document>"u"))return Ye||(or=!0,Ye=(async()=>{if(e=e||document.body,te("Initializing..."),_.i18n.loadPath){let n=new Set([he.locale,_.i18n.fallbackLocale]);await Promise.all([...n].map(r=>Dn(r)))}Mt(e);let t=zo();await ei(t),document.querySelector("[route-view]")&&kn(pi()),K(e),me&&await me.init(),te("Initialized."),ti(),Ir(et);for(let[,{plugin:n}]of Je)n.init&&await n.init(et);Ge("plugins:ready")})(),Ye)},directive(e,t){F(e,t)},filter(e,t){if(typeof e!="string"||!e)throw new TypeError("NoJS.filter() requires a non-empty string name.");if(typeof t!="function")throw new TypeError(`NoJS.filter(): "${e}" handler must be a function.`);if(Bo.has(e)){w(`NoJS.filter(): "${e}" is a built-in filter and cannot be overridden.`);return}Q[e]=t},validator(e,t){if(typeof e!="string"||!e)throw new TypeError("NoJS.validator() requires a non-empty string name.");if(typeof t!="function")throw new TypeError(`NoJS.validator(): "${e}" handler must be a function.`);if(Uo.has(e)){w(`NoJS.validator(): "${e}" is a built-in validator and cannot be overridden.`);return}Pn[e]=t},i18n(e){if(e.loadPath!=null&&(_.i18n.loadPath=e.loadPath),e.ns&&(_.i18n.ns=e.ns),Array.isArray(e.supportedLocales)&&(_.i18n.supportedLocales=e.supportedLocales),e.cache!=null&&(_.i18n.cache=e.cache),e.persist!=null&&(_.i18n.persist=e.persist),e.locales&&(he.locales=e.locales),e.fallbackLocale&&(_.i18n.fallbackLocale=e.fallbackLocale),e.defaultLocale&&(he._locale=e.defaultLocale),_.i18n.persist&&typeof localStorage<"u")try{let t=localStorage.getItem("nojs-locale");if(t){he._locale=t;return}}catch{}if(e.detectBrowser){let t=typeof navigator<"u"&&navigator.language||"en",n=t.split("-")[0],r=Array.isArray(_.i18n.supportedLocales)?_.i18n.supportedLocales:[],i=o=>he.locales[o]||r.includes(o);i(t)?he._locale=t:i(n)&&(he._locale=n)}},on(e,t){return rt[e]||(rt[e]=[]),rt[e].length>=_.maxEventListeners&&w('MaxListenersExceeded: event "'+e+'" has '+rt[e].length+" listeners (max "+_.maxEventListeners+"). Possible memory leak."),rt[e].push(t),()=>{rt[e]=rt[e].filter(n=>n!==t)}},interceptor(e,t){if(en){w("Cannot register interceptors during dispose.");return}if(!Ke[e]){w(`NoJS.interceptor(): unknown type "${e}" (expected "request" or "response").`);return}Ke[e].push(_t?{fn:t,pluginName:_t}:t)},get store(){return se},notify(){Ve()},get router(){return me},createContext:q,evaluate:R,findContext:H,processTree:K,resolve:jt,get internals(){return Object.freeze({execStatement:Le,cloneTemplate:ye,disposeChildren:ie,disposeTree:He,warn:w,validators:Object.freeze({...Pn}),removeCoreDirective:ii,onDispose:D})},version:"1.19.0"};Object.defineProperty(et,"CANCEL",{value:zt,writable:!1,configurable:!1});Object.defineProperty(et,"RESPOND",{value:Lt,writable:!1,configurable:!1});Object.defineProperty(et,"REPLACE",{value:Wt,writable:!1,configurable:!1});Object.defineProperty(et,"_initialized",{get(){return Ye!==null},set(e){e||(Ye=null)},configurable:!0});var xn=et;window.NoJS=xn;document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>xn.init()):xn.init();})(); //# sourceMappingURL=no.js.map diff --git a/dist/iife/no.js.map b/dist/iife/no.js.map index e01d748b..e7d917df 100644 --- a/dist/iife/no.js.map +++ b/dist/iife/no.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../../src/globals.js", "../../src/i18n.js", "../../src/index.js", "../../src/context.js", "../../src/devtools.js", "../../src/evaluate.js", "../../src/dom.js", "../../src/fetch.js", "../../src/registry.js", "../../src/router.js", "../../src/animations.js", "../../src/filters.js", "../../src/directives/state.js", "../../src/directives/loops.js", "../../src/directives/http.js", "../../src/directives/binding.js", "../../src/directives/conditionals.js", "../../src/directives/styling.js", "../../src/directives/events.js", "../../src/directives/refs.js", "../../src/directives/validate-stub.js", "../../src/directives/error-boundary.js", "../../src/directives/i18n.js", "../../src/directives/dnd-stub.js", "../../src/directives/head.js", "../../src/cdn.js"], - "sourcesContent": ["// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// SHARED STATE & UTILITIES\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nexport const _config = {\n baseApiUrl: \"\",\n headers: {},\n timeout: 10000,\n retries: 0,\n retryDelay: 1000,\n credentials: \"same-origin\",\n csrf: null,\n cache: { strategy: \"none\", ttl: 300000 },\n templates: { cache: true },\n router: { useHash: false, base: \"/\", scrollBehavior: \"top\", templates: \"pages\", ext: \".tpl\", suppressHashWarning: false, focusBehavior: \"none\", viewTransition: true },\n i18n: { defaultLocale: \"en\", fallbackLocale: \"en\", detectBrowser: false, loadPath: null, ns: [], supportedLocales: [], cache: true, persist: false },\n debug: false,\n devtools: false,\n sanitize: true,\n dangerouslyDisableSanitize: false,\n sanitizeHtml: null,\n exprCacheSize: 500,\n maxEventListeners: 100,\n appId: \"\",\n};\n\nexport const _interceptors = { request: [], response: [] };\nexport const _eventBus = {};\nexport const _stores = {};\nexport const _storeWatchers = new Map(); // storeName \u2192 Set, '*' = wildcard\nexport const _i18nListeners = new Set(); // fns watching $i18n expressions\nexport const _routeWatchers = new Set(); // fns watching $route expressions\nexport const _filters = {};\nexport const _validators = {};\nexport const _cache = new Map();\nexport const _refs = {};\nexport let _routerInstance = null;\n\n// \u2500\u2500\u2500 Plugin system shared state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport const _plugins = new Map(); // name \u2192 { plugin, options }\nexport const _globals = Object.create(null); // name \u2192 reactive value (prototype-free)\nexport const _globalOwners = Object.create(null); // name \u2192 plugin name (collision tracking)\nexport let _disposing = false;\n// Internal: used by index.js dispose() only \u2014 plugins receive the NoJS API, not module imports\nexport function _setDisposing(v) { _disposing = v; }\nexport let _currentPluginName = null;\nexport function _setCurrentPluginName(v) { _currentPluginName = v; }\n\nexport const _SENSITIVE_HEADERS = new Set([\n 'authorization', 'x-api-key', 'x-auth-token', 'cookie',\n 'proxy-authorization', 'set-cookie', 'x-csrf-token',\n]);\n\nexport const _SENSITIVE_KEYS = new Set([\n 'token', 'password', 'secret', 'key', 'auth', 'credential', 'session',\n]);\n\nexport const _SENSITIVE_RESPONSE_HEADERS = new Set([\n 'set-cookie', 'x-csrf-token', 'x-auth-token',\n 'www-authenticate', 'proxy-authenticate',\n]);\n\n// \u2500\u2500\u2500 Lifecycle: tracks the element being processed by processElement \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Used by ctx.$watch and _onDispose to transparently tag watchers/disposers\n// with the owning DOM element \u2014 no changes needed in directive files.\nexport let _currentEl = null;\n\nexport function _setCurrentEl(el) {\n _currentEl = el;\n}\n\nexport function setRouterInstance(r) {\n _routerInstance = r;\n}\n\nexport function _log(...args) {\n if (_config.debug) console.log(\"[No.JS]\", ...args);\n}\n\nexport function _warn(...args) {\n console.warn(\"[No.JS]\", ...args);\n}\n\n// \u2500\u2500\u2500 Shared URL utility \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function _stripBase(pathname) {\n const base = (_config.router.base || \"/\").replace(/\\/$/, \"\");\n if (!base) return pathname || \"/\";\n const escaped = base.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n return pathname.replace(new RegExp(\"^\" + escaped), \"\") || \"/\";\n}\n\n// Regex to extract the first store name from expressions like $store.cart.items\nconst _STORE_NAME_RE = /\\$store\\.(\\w+)/;\n\nexport function _extractStoreName(expr) {\n if (typeof expr !== \"string\") return null;\n const m = _STORE_NAME_RE.exec(expr);\n return m ? m[1] : null;\n}\n\nfunction _notifyPartition(set) {\n // Snapshot before iterating: a watcher may synchronously add/delete watchers\n // in this same partition, which would otherwise skip or re-run listeners.\n // Isolate each listener so one throwing watcher doesn't abort the rest.\n for (const fn of [...set]) {\n if (fn._el && !fn._el.isConnected) {\n set.delete(fn);\n continue;\n }\n try {\n fn();\n } catch (err) {\n _warn(\"store watcher threw; continuing with remaining watchers:\", err);\n }\n }\n}\n\nexport function _notifyStoreWatchers(storeName) {\n if (storeName) {\n // Notify only the targeted partition + wildcards\n const partition = _storeWatchers.get(storeName);\n if (partition) _notifyPartition(partition);\n const wildcard = _storeWatchers.get(\"*\");\n if (wildcard) _notifyPartition(wildcard);\n } else {\n // No store name \u2014 notify ALL partitions (backward compat)\n for (const set of _storeWatchers.values()) {\n _notifyPartition(set);\n }\n }\n}\n\nexport function _addStoreWatcher(fn, partition) {\n let set = _storeWatchers.get(partition);\n if (!set) {\n set = new Set();\n _storeWatchers.set(partition, set);\n }\n set.add(fn);\n fn._storePartition = partition;\n}\n\nexport function _deleteStoreWatcher(fn) {\n const partition = fn._storePartition;\n if (partition) {\n const set = _storeWatchers.get(partition);\n if (set) {\n set.delete(fn);\n if (set.size === 0) _storeWatchers.delete(partition);\n }\n } else {\n // Fallback: scan all partitions (legacy safety net)\n for (const [key, set] of _storeWatchers) {\n set.delete(fn);\n if (set.size === 0) _storeWatchers.delete(key);\n }\n }\n}\n\nexport function _notifyRouteWatchers() {\n for (const fn of [..._routeWatchers]) {\n if (fn._el && !fn._el.isConnected) {\n _routeWatchers.delete(fn);\n continue;\n }\n try {\n fn();\n } catch (err) {\n _warn(\"route watcher threw; continuing with remaining watchers:\", err);\n }\n }\n}\n\nexport function _addRouteWatcher(fn) {\n _routeWatchers.add(fn);\n}\n\nexport function _deleteRouteWatcher(fn) {\n _routeWatchers.delete(fn);\n}\n\nexport function _watchI18n(fn) {\n _i18nListeners.add(fn);\n return () => _i18nListeners.delete(fn);\n}\n\n// Root-key extractor, injected by evaluate.js at load time (avoids a\n// globals \u2194 evaluate import cycle). Returns Set | null.\nlet _exprRootKeysFn = null;\nexport function _setExprRootKeysFn(f) { _exprRootKeysFn = f; }\n\nexport function _watchExpr(expr, ctx, fn) {\n // Key-scope the watcher: notify(key) skips fn when the changed key cannot\n // appear in the expression. null roots (calls, filters, $-specials, parse\n // failure) lock fn to unkeyed \u2014 it fires on every notification, exactly\n // the pre-scoping behavior. A fn watched under several exprs unions their\n // roots; one ambiguous expr makes it permanently unkeyed.\n if (_exprRootKeysFn && !fn._unkeyed) {\n const roots = _exprRootKeysFn(expr);\n if (roots === null) {\n fn._unkeyed = true;\n fn._keys = undefined;\n } else if (fn._keys) {\n // Union branch mutates \u2014 a fn still holding the shared memoized Set\n // must take a private copy first (copy-on-write) so every other\n // watcher of the same expression keeps its clean shared Set.\n if (fn._keysShared) {\n fn._keys = new Set(fn._keys);\n fn._keysShared = false;\n }\n for (const k of roots) fn._keys.add(k);\n } else {\n // roots is the shared memoized Set from evaluate.js \u2014 adopt it\n // directly instead of copying. The common case (one expression per\n // watcher, i.e. every loop-row binding) then shares one Set across\n // all rows; the union branch above copies lazily if a second\n // expression ever lands on this fn.\n fn._keys = roots;\n fn._keysShared = true;\n }\n }\n\n // Register fn on ctx and every parent context so that changes to inherited\n // variables (e.g. outer state modified from an outer button) fire fn even\n // when ctx is a nested child context. This generalises the per-directive\n // ancestor-walk proven in http.js and fixes the nested-state one-behind /\n // dead-reactivity gap (audit finding 1). Set.add is a no-op for duplicates,\n // so the same fn registered twice on the same context is harmless.\n //\n // Registration goes through __listeners directly instead of $watch: the\n // per-registration unwatch closures $watch returns (one per chain level per\n // watcher) dominated per-row watcher memory; a single dispose closure that\n // re-walks the same chain replaces them all.\n if (_currentEl) fn._el = _currentEl;\n let c = ctx;\n while (c && c.__isProxy) {\n c.__listeners.add(fn);\n c = c.$parent;\n }\n\n // Cleanup: registry's _disposeElement walks fn._wctx's chain deleting fn\n // (plus the store/route/i18n registries) for every fn in el.__watcherFns \u2014\n // pure data instead of one dispose closure per watcher. Gated elements\n // still need a real disposer: gate deactivation runs __gateDisposers, not\n // element disposal.\n if (_currentEl && !_currentEl.__gatedDirs) {\n fn._wctx = ctx;\n (_currentEl.__watcherFns || (_currentEl.__watcherFns = [])).push(fn);\n } else {\n _onDispose(() => {\n let d = ctx;\n while (d && d.__isProxy) {\n d.__listeners.delete(fn);\n d = d.$parent;\n }\n _deleteStoreWatcher(fn);\n _deleteRouteWatcher(fn);\n _i18nListeners.delete(fn);\n });\n }\n if (typeof expr === \"string\" && expr.includes(\"$store\")) {\n const partition = _extractStoreName(expr) || \"*\";\n _addStoreWatcher(fn, partition);\n fn._el = _currentEl;\n }\n if (typeof expr === \"string\" && expr.includes(\"$route\")) {\n _addRouteWatcher(fn);\n fn._el = _currentEl;\n }\n if (typeof expr === \"string\" && expr.includes(\"$i18n\")) {\n _watchI18n(fn);\n fn._el = _currentEl;\n }\n}\n\n// Register a dispose callback on the element currently being processed.\n// Called from directives to clean up intervals, observers, window listeners.\nexport function _onDispose(fn) {\n if (_currentEl) {\n _currentEl.__disposers = _currentEl.__disposers || [];\n _currentEl.__disposers.push(fn);\n }\n}\n\nexport function _emitEvent(name, data) {\n (_eventBus[name] || []).forEach((fn) => fn(data));\n}\n\n// \u2500\u2500\u2500 Plugin sentinel symbols \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport const _CANCEL = Symbol(\"nojs.cancel\");\nexport const _RESPOND = Symbol(\"nojs.respond\");\nexport const _REPLACE = Symbol(\"nojs.replace\");\n", "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// i18n SYSTEM\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nimport { _config, _warn, _i18nListeners } from \"./globals.js\";\n\n// \u2500\u2500\u2500 Notify all i18n listeners (shared by setter + directive) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function _notifyI18n() {\n _i18nTranslationCache.clear();\n for (const fn of _i18nListeners) {\n if (fn._el && !fn._el.isConnected) { _i18nListeners.delete(fn); continue; }\n fn();\n }\n}\n\n// \u2500\u2500\u2500 Deep merge (recursive, returns new object) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst _FORBIDDEN_MERGE_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\nfunction _deepMerge(target, source) {\n const out = { ...target };\n for (const key of Object.keys(source)) {\n if (_FORBIDDEN_MERGE_KEYS.has(key)) continue;\n if (\n source[key] && typeof source[key] === \"object\" && !Array.isArray(source[key]) &&\n target[key] && typeof target[key] === \"object\" && !Array.isArray(target[key])\n ) {\n out[key] = _deepMerge(target[key], source[key]);\n } else {\n out[key] = source[key];\n }\n }\n return out;\n}\n\n// \u2500\u2500\u2500 Translation lookup cache: Map key = \"en:namespace.key.path\"\n// Stores the raw resolved message (before interpolation/pluralization).\n// Cleared on locale change and namespace reload to avoid stale entries.\nexport const _i18nTranslationCache = new Map();\n\n// \u2500\u2500\u2500 Locale file cache: Map key = \"en\" or \"en:dashboard\"\nconst _i18nCache = new Map();\nconst _loadedNs = new Set();\n\n// \u2500\u2500\u2500 Fetch a single JSON file and merge into _i18n.locales[locale] \u2500\u2500\nasync function _loadLocale(locale, ns) {\n const cacheKey = ns ? `${locale}:${ns}` : locale;\n if (_config.i18n.cache && _i18nCache.has(cacheKey)) return;\n\n // Percent-encode placeholder values before substituting into the loadPath,\n // mirroring _interpolate() which encodes every {placeholder}. This neutralizes\n // path traversal (e.g. \"../../../account/settings\") even when supportedLocales\n // is unset \u2014 \"/\" becomes \"%2F\", so the \"../\" cannot escape the configured path.\n let url = _config.i18n.loadPath.replace(\"{locale}\", encodeURIComponent(locale));\n if (ns) url = url.replace(\"{ns}\", encodeURIComponent(ns));\n else if (url.includes(\"{ns}\")) return; // no namespace to substitute\n\n\n try {\n const res = await fetch(url);\n if (!res.ok) { _warn(`i18n: failed to load ${url} (${res.status})`); return; }\n const data = await res.json();\n _i18n.locales[locale] = _deepMerge(_i18n.locales[locale] || {}, data);\n _i18nTranslationCache.clear();\n if (_config.i18n.cache) _i18nCache.set(cacheKey, data);\n } catch (e) {\n _warn(`i18n: error loading ${url}`, e);\n }\n}\n\n// \u2500\u2500\u2500 Load all configured data for a locale (flat or all namespaces) \u2500\u2500\nexport async function _loadI18nForLocale(locale) {\n if (!_config.i18n.loadPath) return;\n const ns = _config.i18n.ns;\n if (!ns.length || !_config.i18n.loadPath.includes(\"{ns}\")) {\n await _loadLocale(locale, null);\n } else {\n await Promise.all(ns.map((n) => _loadLocale(locale, n)));\n }\n}\n\n// \u2500\u2500\u2500 Load a single namespace for current + fallback locales \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport async function _loadI18nNamespace(ns) {\n if (!_config.i18n.loadPath) return;\n _loadedNs.add(ns);\n const locales = new Set([_i18n.locale, _config.i18n.fallbackLocale]);\n await Promise.all([...locales].map((l) => _loadLocale(l, ns)));\n}\n\nexport const _i18n = {\n _locale: \"en\",\n _locales: {},\n get locales() {\n return this._locales;\n },\n set locales(v) {\n this._locales = v;\n _i18nTranslationCache.clear();\n },\n get locale() {\n return this._locale;\n },\n set locale(v) {\n // Reject unsupported locales when supportedLocales is configured (a non-empty\n // array). Untrusted input (e.g. $route.params.lang) flowing into setLocale must\n // not load an attacker-chosen path. When supportedLocales is unset, the\n // encodeURIComponent in _loadLocale is the defense-in-depth fallback.\n const supported = _config.i18n.supportedLocales;\n if (Array.isArray(supported) && supported.length && !supported.includes(v)) {\n _warn(`i18n: locale \"${v}\" is not in supportedLocales; ignoring`);\n return;\n }\n if (this._locale !== v) {\n this._locale = v;\n _i18nTranslationCache.clear();\n if (_config.i18n.persist && typeof localStorage !== \"undefined\") {\n try { localStorage.setItem(\"nojs-locale\", v); } catch (_) {}\n }\n if (_config.i18n.loadPath) {\n // Load configured ns + any route-loaded ns for the new locale\n const allNs = new Set([..._config.i18n.ns, ..._loadedNs]);\n Promise.all([...allNs].map((n) => _loadLocale(v, n))).then(() => _notifyI18n());\n } else {\n _notifyI18n();\n }\n }\n },\n t(key, params = {}) {\n // \u2500\u2500\u2500 Flat translation cache: avoid repeated split+reduce on same key \u2500\u2500\n const cacheKey = `${_i18n.locale}:${key}`;\n let msg = _i18nTranslationCache.get(cacheKey);\n if (msg === undefined) {\n const resolve = (locale) =>\n key.split(\".\").reduce((o, k) => o?.[k], _i18n.locales[locale] || {});\n msg = resolve(_i18n.locale);\n // Per-key fallback: a present bundle missing this key still falls back\n // to the fallbackLocale bundle (not just when the whole bundle is absent).\n if (\n msg == null &&\n _config.i18n.fallbackLocale &&\n _config.i18n.fallbackLocale !== _i18n.locale\n ) {\n msg = resolve(_config.i18n.fallbackLocale);\n }\n // Cache resolved value (including null for missing keys)\n _i18nTranslationCache.set(cacheKey, msg ?? null);\n }\n if (msg == null) return key;\n\n // Pluralization: \"one item | {count} items\"\n if (\n typeof msg === \"string\" &&\n msg.includes(\"|\") &&\n params.count != null\n ) {\n const forms = msg.split(\"|\").map((s) => s.trim());\n msg = Number(params.count) === 1 ? forms[0] : forms[1] || forms[0];\n }\n\n // Interpolation: {name}\n if (typeof msg === \"string\") {\n msg = msg.replace(/\\{(\\w+)\\}/g, (_, k) =>\n params[k] != null ? params[k] : \"\",\n );\n }\n return msg;\n },\n};\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// $i18n REACTIVE PROXY\n// Exposes translation data as dot-notation properties so i18n keys can\n// be used in any expression context (state, bind, computed, watch, etc.)\n// Usage: $i18n.shell.sidebar.introduction \u2192 resolved translation\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nconst _I18N_RESERVED = new Set([\"locale\", \"locales\", \"t\", \"setLocale\"]);\n\nfunction _createI18nNestedProxy(path) {\n return new Proxy(Object.create(null), {\n get(_, key) {\n // Symbol properties \u2014 delegate normally (for JSON.stringify, console.log, etc.)\n if (typeof key !== \"string\") return undefined;\n\n const fullPath = path ? path + \".\" + key : key;\n const locale = _i18n.locale;\n const data = _i18n.locales[locale];\n const val = fullPath.split(\".\").reduce((o, k) => o?.[k], data || {});\n\n // If resolved value is an object \u2192 return a nested proxy (recursive)\n if (val != null && typeof val === \"object\" && !Array.isArray(val)) {\n return _createI18nNestedProxy(fullPath);\n }\n\n // If it's a string/number \u2192 return the leaf value\n if (val != null) return val;\n\n // Fallback locale: try fallbackLocale before returning undefined\n const fb = _config.i18n.fallbackLocale;\n if (fb && fb !== locale) {\n const fbData = _i18n.locales[fb];\n const fbVal = fullPath.split(\".\").reduce((o, k) => o?.[k], fbData || {});\n if (fbVal != null && typeof fbVal === \"object\" && !Array.isArray(fbVal)) {\n return _createI18nNestedProxy(fullPath);\n }\n if (fbVal != null) return fbVal;\n }\n\n return undefined;\n },\n });\n}\n\nexport const _i18nProxy = new Proxy(_i18n, {\n get(target, key) {\n // Symbol properties \u2014 delegate to _i18n for JSON.stringify, console.log, etc.\n if (typeof key !== \"string\") return target[key];\n\n // Reserved properties \u2014 delegate to _i18n directly\n if (key === \"locale\" || key === \"locales\" || key === \"t\") {\n return target[key];\n }\n\n // setLocale \u2014 a convenience method that sets _i18n.locale\n if (key === \"setLocale\") {\n return (value) => { target.locale = value; };\n }\n\n // Unknown string properties \u2192 resolve into translation data\n const locale = target.locale;\n const data = target.locales[locale];\n const val = data?.[key];\n\n // If the resolved value is an object \u2192 return a nested proxy\n if (val != null && typeof val === \"object\" && !Array.isArray(val)) {\n return _createI18nNestedProxy(key);\n }\n\n // If it's a string/number \u2192 return the leaf value\n if (val != null) return val;\n\n // Fallback locale\n const fb = _config.i18n.fallbackLocale;\n if (fb && fb !== locale) {\n const fbData = target.locales[fb];\n const fbVal = fbData?.[key];\n if (fbVal != null && typeof fbVal === \"object\" && !Array.isArray(fbVal)) {\n return _createI18nNestedProxy(key);\n }\n if (fbVal != null) return fbVal;\n }\n\n return undefined;\n },\n});\n", "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// No.JS \u2014 Module Entry Point\n// For npm/ESM/CJS consumers: import NoJS from 'nojs'\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\n// Core modules\nimport {\n _config,\n _filters,\n _validators,\n _interceptors,\n _eventBus,\n _stores,\n _refs,\n _routerInstance,\n setRouterInstance,\n _log,\n _warn,\n _notifyStoreWatchers,\n _plugins,\n _globals,\n _globalOwners,\n _disposing,\n _setDisposing,\n _currentPluginName,\n _setCurrentPluginName,\n _emitEvent,\n _CANCEL,\n _RESPOND,\n _REPLACE,\n _onDispose,\n _stripBase,\n} from \"./globals.js\";\nimport { _i18n, _loadI18nForLocale } from \"./i18n.js\";\nimport { createContext } from \"./context.js\";\nimport { evaluate, resolve, _execStatement } from \"./evaluate.js\";\nimport { findContext, _loadRemoteTemplates, _loadRemoteTemplatesPhase1, _loadRemoteTemplatesPhase2, _processTemplateIncludes, _cloneTemplate } from \"./dom.js\";\nimport { registerDirective, processTree, _removeCoreDirective, _disposeChildren, _disposeTree } from \"./registry.js\";\nimport { _createRouter } from \"./router.js\";\nimport { initDevtools, destroyDevtools, _devtoolsEmit } from \"./devtools.js\";\n\n// Side-effect imports: register built-in filters\nimport \"./filters.js\";\n\n// Side-effect imports: register all built-in directives\nimport \"./directives/state.js\";\nimport \"./directives/http.js\";\nimport \"./directives/binding.js\";\nimport \"./directives/conditionals.js\";\nimport \"./directives/loops.js\";\nimport \"./directives/styling.js\";\nimport \"./directives/events.js\";\nimport \"./directives/refs.js\";\nimport \"./directives/validate-stub.js\";\nimport \"./directives/error-boundary.js\";\nimport \"./directives/i18n.js\";\nimport \"./directives/dnd-stub.js\";\nimport \"./directives/head.js\";\n\n// Lock core directives \u2014 plugins can only register NEW names\nimport { _freezeDirectives } from \"./registry.js\";\n_freezeDirectives();\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// PLUGIN SYSTEM INTERNALS\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nlet _initPromise = null;\nlet _configLocked = false;\n\n// Keep in sync with context.js proxy handler $xxx variables.\n// Any new $xxx context variable requires adding xxx to this list.\nconst _RESERVED_GLOBAL_NAMES = new Set([\n \"store\", \"route\", \"router\", \"i18n\", \"refs\", \"form\", \"parent\",\n \"watch\", \"set\", \"notify\", \"raw\", \"isProxy\", \"listeners\",\n \"app\", \"config\", \"env\", \"debug\", \"version\", \"plugins\", \"globals\",\n \"el\", \"event\", \"self\", \"this\", \"super\", \"window\", \"document\",\n \"toString\", \"valueOf\", \"hasOwnProperty\",\n]);\n\nconst _DANGEROUS_REFS = typeof window !== \"undefined\"\n ? new Set([eval, Function, window.eval, window.Function].filter(Boolean))\n : new Set();\n\nfunction _isUnsafeGlobalValue(value) {\n return _DANGEROUS_REFS.has(value);\n}\n\nconst _FORBIDDEN_GLOBAL_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n// Built-in filter names \u2014 prevent user code from overwriting core filters\nconst _BUILTIN_FILTER_NAMES = new Set([\n \"uppercase\", \"lowercase\", \"capitalize\", \"truncate\", \"trim\", \"stripHtml\",\n \"slugify\", \"nl\", \"nl2br\", \"encodeUri\", \"number\", \"currency\", \"percent\",\n \"filesize\", \"ordinal\", \"count\", \"first\", \"last\", \"join\", \"reverse\",\n \"unique\", \"sortBy\", \"where\", \"pluck\", \"keys\", \"values\", \"json\", \"debug\",\n \"default\", \"date\", \"datetime\", \"relative\", \"fromNow\",\n]);\n\n// Built-in validator names \u2014 prevent user code from overwriting core validators\n// (core validators are registered by @no-js-dev/nojs-elements)\nconst _BUILTIN_VALIDATOR_NAMES = new Set([\n \"required\", \"email\", \"url\", \"min\", \"max\", \"minlength\", \"maxlength\",\n \"pattern\", \"match\", \"number\", \"integer\", \"alpha\", \"alphanumeric\",\n]);\nfunction _deepCheckUnsafe(obj, seen = new Set()) {\n if (!obj || typeof obj !== \"object\" || seen.has(obj)) return;\n seen.add(obj);\n for (const key of Object.keys(obj)) {\n if (_FORBIDDEN_GLOBAL_KEYS.has(key)) {\n _warn(\"NoJS.global(): value contains a forbidden key: \" + key);\n throw new Error(\"unsafe_global\");\n }\n }\n for (const val of Object.values(obj)) {\n if (_isUnsafeGlobalValue(val)) {\n _warn(\"NoJS.global(): value contains a forbidden reference (eval/Function).\");\n throw new Error(\"unsafe_global\");\n }\n if (val && typeof val === \"object\") _deepCheckUnsafe(val, seen);\n }\n}\n\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// PUBLIC API\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nfunction _getDefaultRoutePath() {\n if (typeof window === \"undefined\") return null;\n const routerCfg = _config.router || {};\n if (routerCfg.useHash) {\n return window.location.hash.slice(1) || \"/\";\n }\n return _stripBase(window.location.pathname);\n}\n\nconst NoJS = {\n get baseApiUrl() {\n return _config.baseApiUrl;\n },\n set baseApiUrl(v) {\n _config.baseApiUrl = v;\n },\n\n get locale() {\n return _i18n.locale;\n },\n set locale(v) {\n _i18n.locale = v;\n },\n\n config(opts = {}) {\n // Block security-critical config changes after init\n if (_configLocked) {\n const locked = [\"sanitize\", \"dangerouslyDisableSanitize\", \"sanitizeHtml\"];\n for (const key of locked) {\n if (key in opts) {\n _warn(`config.${key} cannot be changed after init()`);\n delete opts[key];\n }\n }\n }\n // Save nested objects before shallow assign overwrites them\n const prevHeaders = { ..._config.headers };\n const prevCache = { ..._config.cache };\n const prevTemplates = { ..._config.templates };\n const prevRouter = { ..._config.router };\n const prevI18n = { ..._config.i18n };\n if (\"csp\" in opts) {\n _warn(\"csp config option removed \u2014 No.JS is now CSP-safe by default\");\n delete opts.csp;\n }\n if (opts.exprCacheSize !== undefined) {\n const n = parseInt(opts.exprCacheSize);\n opts.exprCacheSize = (Number.isFinite(n) && n > 0) ? n : 500;\n }\n Object.assign(_config, opts);\n if (opts.sanitize === false) {\n _warn('sanitize:false is deprecated \u2014 use dangerouslyDisableSanitize:true to make the risk explicit.');\n }\n if (opts.headers)\n _config.headers = { ...prevHeaders, ...opts.headers };\n if (opts.csrf) _config.csrf = opts.csrf;\n if (opts.cache) _config.cache = { ...prevCache, ...opts.cache };\n if (opts.templates) _config.templates = { ...prevTemplates, ...opts.templates };\n if (opts.router) {\n if (\"mode\" in opts.router && !(\"useHash\" in opts.router)) {\n _log(\n 'router.mode is deprecated. Use router.useHash instead: ' +\n 'mode: \"hash\" \u2192 useHash: true, mode: \"history\" \u2192 useHash: false',\n \"warn\"\n );\n opts.router.useHash = opts.router.mode === \"hash\";\n delete opts.router.mode;\n }\n _config.router = { ...prevRouter, ...opts.router };\n }\n if (opts.i18n) {\n _config.i18n = { ...prevI18n, ...opts.i18n };\n _i18n.locale = opts.i18n.defaultLocale || _i18n.locale;\n }\n if (opts.stores) {\n for (const [name, data] of Object.entries(opts.stores)) {\n if (!_stores[name]) {\n _stores[name] = createContext(data || {});\n _devtoolsEmit(\"store:created\", { name, keys: Object.keys(data || {}) });\n }\n }\n delete _config.stores;\n }\n },\n\n // \u2500\u2500\u2500 Plugin registration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n use(plugin, options = {}) {\n if (_disposing) {\n _warn(\"Cannot install plugins during dispose.\");\n return;\n }\n\n // Normalize function shorthand (named functions only)\n if (typeof plugin === \"function\") {\n if (!plugin.name || plugin.name === \"anonymous\") {\n _warn('Plugin must have a unique, non-empty name. Use { name: \"my-plugin\", install: fn }.');\n return;\n }\n plugin = { name: plugin.name, install: plugin };\n }\n\n // Validate name\n if (!plugin.name || typeof plugin.name !== \"string\" || plugin.name === \"anonymous\") {\n _warn('Plugin must have a unique, non-empty name.');\n return;\n }\n\n // Duplicate detection with object identity comparison\n if (_plugins.has(plugin.name)) {\n const existing = _plugins.get(plugin.name);\n if (existing.plugin !== plugin) {\n _warn(`Plugin \"${plugin.name}\" name collision: a different plugin with this name is already installed.`);\n }\n return;\n }\n\n // Log declared capabilities in debug mode\n if (plugin.capabilities && _config.debug) {\n _log(`Plugin \"${plugin.name}\" declares capabilities:`, plugin.capabilities);\n }\n\n // Warn on trusted access\n if (options.trusted === true) {\n _warn(`WARNING: Plugin \"${plugin.name}\" installed with trusted access to sensitive HTTP headers.`);\n }\n\n // Set current plugin name for interceptor tracking\n _setCurrentPluginName(plugin.name);\n try {\n plugin.install(NoJS, options);\n } finally {\n _setCurrentPluginName(null);\n }\n\n _plugins.set(plugin.name, { plugin, options });\n\n // If already initialized and plugin has init, await then call\n if (_initPromise && plugin.init) {\n _initPromise.then(() => plugin.init(NoJS)).catch(e => _warn(`Plugin \"${plugin.name}\" init error:`, e.message));\n }\n\n _log(`Plugin \"${plugin.name}\" installed.`);\n },\n\n // \u2500\u2500\u2500 Plugin globals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n global(name, value) {\n if (typeof name !== \"string\" || !name) {\n _warn(\"NoJS.global() requires a non-empty string name.\");\n return;\n }\n\n // Block prototype pollution vectors\n if (name === \"__proto__\" || name === \"constructor\" || name === \"prototype\") {\n _warn(`NoJS.global(): \"${name}\" is a forbidden name.`);\n return;\n }\n\n // Block reserved names\n if (_RESERVED_GLOBAL_NAMES.has(name)) {\n _warn(`NoJS.global(): \"${name}\" is reserved and cannot be used.`);\n return;\n }\n\n // Validate identifier characters\n if (!/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)) {\n _warn(`NoJS.global(): \"${name}\" is not a valid identifier.`);\n return;\n }\n\n // Block dangerous function references\n if (_isUnsafeGlobalValue(value)) {\n _warn(`NoJS.global(): value for \"${name}\" is a forbidden reference (eval/Function).`);\n return;\n }\n\n // Warn on overwrite by a different plugin\n if (name in _globals && _globalOwners[name] && _globalOwners[name] !== _currentPluginName) {\n _warn(`Global \"$${name}\" owned by \"${_globalOwners[name]}\" is being overwritten.`);\n }\n\n // Sanitize object values to strip __proto__ keys\n if (value && typeof value === \"object\" && !value.__isProxy) {\n try {\n value = JSON.parse(JSON.stringify(value));\n } catch {\n // Non-serializable objects \u2014 check for dangerous function references\n try {\n _deepCheckUnsafe(value);\n } catch (safetyErr) {\n if (safetyErr.message === \"unsafe_global\") return;\n // Other errors pass through\n }\n }\n // Wrap in reactive context for deep reactivity\n value = createContext(value);\n } else if (value && typeof value === \"object\" && value.__isProxy) {\n // Already a reactive proxy \u2014 sanitization branch above is skipped, so run the\n // recursive unsafe-reference / prototype-pollution check on the raw target\n // to avoid storing nested eval/Function refs or polluted prototypes verbatim.\n try {\n _deepCheckUnsafe(value.__raw ?? value);\n } catch (safetyErr) {\n if (safetyErr.message === \"unsafe_global\") return;\n // Other errors pass through\n }\n }\n\n _globals[name] = value;\n if (_currentPluginName) _globalOwners[name] = _currentPluginName;\n\n // Notify all store watchers since globals are scope-wide\n _notifyStoreWatchers();\n\n _devtoolsEmit(\"global:set\", { name, hasValue: value != null });\n _log(`Global \"$${name}\" registered.`);\n },\n\n // \u2500\u2500\u2500 App teardown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n async dispose() {\n _setDisposing(true);\n try {\n // Wait for any in-flight init() to settle before tearing down \u2014 otherwise the\n // init IIFE keeps running against state we are about to clear and re-locks config\n // after teardown. _setDisposing(true) above prevents new plugin installs meanwhile.\n if (_initPromise) {\n try { await _initPromise; } catch { /* init failure is irrelevant during dispose */ }\n }\n\n // Dispose plugins in reverse installation order\n const entries = [..._plugins.entries()].reverse();\n for (const [name, { plugin }] of entries) {\n if (plugin.dispose) {\n try {\n let timeoutId;\n await Promise.race([\n Promise.resolve(plugin.dispose(NoJS)).finally(() => clearTimeout(timeoutId)),\n new Promise((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error(\"Dispose timeout\")), 3000);\n }),\n ]);\n } catch (e) {\n _warn(`Plugin \"${name}\" dispose error:`, e.message);\n }\n }\n }\n _plugins.clear();\n for (const k in _globals) delete _globals[k];\n for (const k in _globalOwners) delete _globalOwners[k];\n\n // Clear interceptors\n _interceptors.request.length = 0;\n _interceptors.response.length = 0;\n\n // Destroy router listeners\n if (_routerInstance && _routerInstance.destroy) {\n _routerInstance.destroy();\n }\n setRouterInstance(null);\n\n // Clean up devtools listener\n destroyDevtools();\n\n _configLocked = false;\n\n _initPromise = null;\n _log(\"Disposed.\");\n } finally {\n _setDisposing(false);\n }\n },\n\n // \u2500\u2500\u2500 Init (Promise-based lifecycle) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n async init(root) {\n if (typeof document === \"undefined\") return;\n if (_initPromise) return _initPromise;\n // Lock security-critical config synchronously, BEFORE the async init body awaits\n // anything \u2014 otherwise sanitize flags remain mutable during the async init window.\n _configLocked = true;\n _initPromise = (async () => {\n root = root || document.body;\n _log(\"Initializing...\");\n\n // Load external locale files (blocking \u2014 translations must be available for first paint)\n if (_config.i18n.loadPath) {\n const locales = new Set([_i18n.locale, _config.i18n.fallbackLocale]);\n await Promise.all([...locales].map((l) => _loadI18nForLocale(l)));\n }\n\n // Inline template includes (e.g. skeletons) \u2014 synchronous, before any fetch\n _processTemplateIncludes(root);\n\n // Determine active route path for phase 1 prioritization\n const defaultRoutePath = _getDefaultRoutePath();\n\n // Phase 1 (blocking): priority + non-route + default route templates\n await _loadRemoteTemplatesPhase1(defaultRoutePath);\n\n // Check for route-view outlets to activate router\n if (document.querySelector(\"[route-view]\")) {\n setRouterInstance(_createRouter());\n }\n\n processTree(root); // \u2190 first paint happens here\n\n // Init router after tree is processed\n if (_routerInstance) await _routerInstance.init();\n\n _log(\"Initialized.\");\n\n // Phase 2 (non-blocking): background preload remaining route templates\n _loadRemoteTemplatesPhase2();\n\n // DevTools integration\n initDevtools(NoJS);\n\n // Plugin init hooks\n for (const [, { plugin }] of _plugins) {\n if (plugin.init) await plugin.init(NoJS);\n }\n _emitEvent(\"plugins:ready\");\n })();\n return _initPromise;\n },\n\n // Register custom directive\n directive(name, handler) {\n registerDirective(name, handler);\n },\n\n // Register custom filter\n filter(name, fn) {\n if (typeof name !== \"string\" || !name) {\n throw new TypeError(\"NoJS.filter() requires a non-empty string name.\");\n }\n if (typeof fn !== \"function\") {\n throw new TypeError(`NoJS.filter(): \"${name}\" handler must be a function.`);\n }\n if (_BUILTIN_FILTER_NAMES.has(name)) {\n _warn(`NoJS.filter(): \"${name}\" is a built-in filter and cannot be overridden.`);\n return;\n }\n _filters[name] = fn;\n },\n\n // Register custom validator\n validator(name, fn) {\n if (typeof name !== \"string\" || !name) {\n throw new TypeError(\"NoJS.validator() requires a non-empty string name.\");\n }\n if (typeof fn !== \"function\") {\n throw new TypeError(`NoJS.validator(): \"${name}\" handler must be a function.`);\n }\n if (_BUILTIN_VALIDATOR_NAMES.has(name)) {\n _warn(`NoJS.validator(): \"${name}\" is a built-in validator and cannot be overridden.`);\n return;\n }\n _validators[name] = fn;\n },\n\n // i18n\n i18n(opts) {\n // Set config options BEFORE locale (setter checks loadPath)\n if (opts.loadPath != null) _config.i18n.loadPath = opts.loadPath;\n if (opts.ns) _config.i18n.ns = opts.ns;\n if (Array.isArray(opts.supportedLocales)) _config.i18n.supportedLocales = opts.supportedLocales;\n if (opts.cache != null) _config.i18n.cache = opts.cache;\n if (opts.persist != null) _config.i18n.persist = opts.persist;\n if (opts.locales) _i18n.locales = opts.locales;\n if (opts.fallbackLocale) _config.i18n.fallbackLocale = opts.fallbackLocale;\n\n // Set defaultLocale WITHOUT the setter (avoids overwriting localStorage)\n if (opts.defaultLocale) _i18n._locale = opts.defaultLocale;\n\n // Restore persisted locale (highest priority)\n if (_config.i18n.persist && typeof localStorage !== \"undefined\") {\n try {\n const saved = localStorage.getItem(\"nojs-locale\");\n if (saved) { _i18n._locale = saved; return; }\n } catch (_) {}\n }\n\n // Detect browser language (second priority)\n if (opts.detectBrowser) {\n const browserLang =\n (typeof navigator !== \"undefined\" && navigator.language) || \"en\";\n const prefix = browserLang.split(\"-\")[0];\n // A locale is a match if it exists in the in-memory bundle map (inline\n // `locales`) OR is declared in `supportedLocales`. The latter is required\n // for lazy `loadPath` setups where no bundles are loaded yet at this point.\n const list = Array.isArray(_config.i18n.supportedLocales)\n ? _config.i18n.supportedLocales\n : [];\n const has = (loc) => _i18n.locales[loc] || list.includes(loc);\n if (has(browserLang)) _i18n._locale = browserLang;\n else if (has(prefix)) _i18n._locale = prefix;\n }\n },\n\n // Event bus\n on(event, fn) {\n if (!_eventBus[event]) _eventBus[event] = [];\n if (_eventBus[event].length >= _config.maxEventListeners) {\n _warn(\n 'MaxListenersExceeded: event \"' + event + '\" has ' + _eventBus[event].length +\n ' listeners (max ' + _config.maxEventListeners + '). Possible memory leak.'\n );\n }\n _eventBus[event].push(fn);\n return () => {\n _eventBus[event] = _eventBus[event].filter((f) => f !== fn);\n };\n },\n\n // Request/response interceptors (with plugin tracking)\n interceptor(type, fn) {\n if (_disposing) {\n _warn(\"Cannot register interceptors during dispose.\");\n return;\n }\n if (!_interceptors[type]) {\n _warn(`NoJS.interceptor(): unknown type \"${type}\" (expected \"request\" or \"response\").`);\n return;\n }\n _interceptors[type].push(\n _currentPluginName ? { fn, pluginName: _currentPluginName } : fn\n );\n },\n\n // Access global stores\n get store() {\n return _stores;\n },\n\n // Notify global store watchers (for external JS mutations)\n notify() {\n _notifyStoreWatchers();\n },\n\n // Access router\n get router() {\n return _routerInstance;\n },\n\n // Utilities (for custom directives)\n createContext,\n evaluate,\n findContext,\n processTree,\n resolve,\n\n // Internal API for trusted plugins (e.g. NoJS-Elements)\n get internals() {\n return Object.freeze({\n execStatement: _execStatement,\n cloneTemplate: _cloneTemplate,\n disposeChildren: _disposeChildren,\n disposeTree: _disposeTree,\n warn: _warn,\n validators: Object.freeze({..._validators}),\n removeCoreDirective: _removeCoreDirective,\n onDispose: _onDispose,\n });\n },\n\n // Version\n version: \"1.19.0\",\n};\n\n// Expose sentinel symbols as read-only properties\nObject.defineProperty(NoJS, \"CANCEL\", { value: _CANCEL, writable: false, configurable: false });\nObject.defineProperty(NoJS, \"RESPOND\", { value: _RESPOND, writable: false, configurable: false });\nObject.defineProperty(NoJS, \"REPLACE\", { value: _REPLACE, writable: false, configurable: false });\n\n// Backward-compat: _initialized getter/setter (tests use `NoJS._initialized = false` to reset)\nObject.defineProperty(NoJS, \"_initialized\", {\n get() { return _initPromise !== null; },\n set(v) { if (!v) _initPromise = null; },\n configurable: true,\n});\n\nexport default NoJS;\n", "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// REACTIVE CONTEXT\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nimport { _config, _stores, _refs, _routerInstance, _currentEl, _globals, _SENSITIVE_KEYS, _warn } from \"./globals.js\";\nimport { _i18nProxy } from \"./i18n.js\";\nimport { _devtoolsEmit, _ctxRegistry } from \"./devtools.js\";\n\nconst _FORBIDDEN_CTX_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nlet _batchDepth = 0;\nlet _batchQueue = new Set();\nlet _ctxId = 0;\nlet _ctxGeneration = 0;\n\nexport function _resetCtxId() { _ctxId = 0; }\n\nexport function _startBatch() {\n _batchDepth++;\n _devtoolsEmit(\"batch:start\", { depth: _batchDepth });\n}\n\nexport function _endBatch() {\n _batchDepth--;\n if (_batchDepth === 0 && _batchQueue.size > 0) {\n _devtoolsEmit(\"batch:end\", { depth: 0, queueSize: _batchQueue.size });\n // Drain with the depth held above zero so notifies fired by running\n // listeners re-queue into the live Set (deduped) instead of executing\n // synchronously \u2014 each listener runs once per settled state instead of\n // once per notification source.\n let rounds = 0;\n while (_batchQueue.size > 0) {\n if (++rounds > 100) {\n _warn(\"batch drain exceeded 100 rounds \u2014 possible update cycle; aborting drain\");\n _batchQueue = new Set();\n break;\n }\n const fns = _batchQueue;\n _batchQueue = new Set();\n _batchDepth++;\n try {\n // Drain defensively: a throwing listener must not drop the rest of the\n // queued updates (Safety Rule 8 \u2014 one broken attribute must not abort the page).\n fns.forEach((fn) => {\n if (fn._el && !fn._el.isConnected) return;\n // Running now supersedes a re-queue made by an earlier listener\n // in this same round; re-queues that happen after fn ran (or\n // during it) stay for the next round.\n _batchQueue.delete(fn);\n try {\n fn();\n } catch (err) {\n _warn(\"batched listener threw; continuing with remaining listeners:\", err);\n }\n });\n } finally {\n _batchDepth--;\n }\n }\n }\n}\n\n// Per-context bookkeeping lives in one meta record behind a Symbol key on the\n// raw object (invisible to Object.keys / _collectKeys). Everything a context\n// used to close over per instance \u2014 parent link, listeners Set, $watch/$set/\n// $notify closures \u2014 is either stored here or created lazily on first access,\n// so a context that is only ever read (the common loop-row case before its\n// bindings attach) costs raw + meta + Proxy and nothing else.\nconst META = Symbol(\"no.js\");\n\n// `key` is the changed property when the notification comes from a single\n// write (set trap / $set); undefined for manual $notify() and bulk changes,\n// which fire every listener. Key-scoped listeners (fn._keys, assigned in\n// _watchExpr) are skipped when the changed key cannot affect them.\n//\n// Every notify runs through the batch queue: outside an explicit batch it\n// opens its own, so listeners always execute from _endBatch's drain. A\n// notify fired by a running listener (e.g. computed's $set cascading into\n// a watch) queues for the next drain round instead of recursing \u2014 or being\n// dropped, as the old reentrancy guard did. Still fully synchronous: the\n// drain completes before the outermost notify/set returns.\nfunction _notifyMeta(meta, key) {\n const listeners = meta.listeners;\n if (!listeners || listeners.size === 0) return;\n const ownBatch = _batchDepth === 0;\n if (ownBatch) _startBatch();\n for (const fn of listeners) {\n if (fn._el && !fn._el.isConnected) { listeners.delete(fn); continue; }\n if (key !== undefined && fn._keys && !fn._keys.has(key)) continue;\n _batchQueue.add(fn);\n }\n if (ownBatch) _endBatch();\n}\n\n// One handler object shared by every context Proxy. The old per-context\n// handler literal carried three trap closures per instance; here the traps\n// reach per-context state through target[META] instead.\nconst _sharedHandler = {\n get(target, key) {\n // Fast path: non-string keys (Symbols) go straight to target\n if (typeof key !== \"string\") return target[key];\n\n const c0 = key.charCodeAt(0);\n\n // Fast path: keys not starting with '$' (36) or '_' (95) are user properties.\n // Skip all special-key checks entirely.\n if (c0 !== 36 /* $ */ && c0 !== 95 /* _ */) {\n if (key in target) return target[key];\n const parent = target[META].parent;\n if (parent && parent.__isProxy) return parent[key];\n return undefined;\n }\n\n // Dunder keys (__isProxy, __raw, __listeners)\n if (c0 === 95) {\n if (key === \"__isProxy\") return true;\n if (key === \"__raw\") return target;\n if (key === \"__listeners\") {\n // Materialize on access: devtools counting and disposal clearing see\n // the same always-a-Set shape the eager version provided.\n const meta = target[META];\n return meta.listeners || (meta.listeners = new Set());\n }\n // Fall through to target/parent lookup for other _ keys\n if (key in target) return target[key];\n const parentU = target[META].parent;\n if (parentU && parentU.__isProxy) return parentU[key];\n return undefined;\n }\n\n // $ prefix: dispatch core context keys via switch for O(1) branching.\n // The $watch/$notify/$set closures are created on first access and cached\n // on meta \u2014 stable identity, zero cost for contexts that never use them.\n switch (key) {\n case \"$watch\": {\n const meta = target[META];\n return meta.watchFn || (meta.watchFn = (fn) => {\n if (_currentEl) fn._el = _currentEl;\n (meta.listeners || (meta.listeners = new Set())).add(fn);\n return () => { if (meta.listeners) meta.listeners.delete(fn); };\n });\n }\n case \"$notify\": {\n const meta = target[META];\n // Only a string arg narrows to key-scoped listeners. $notify()\n // historically took no argument, so userland calls passing anything\n // else ($notify($event), $notify(0)) must keep firing every\n // listener rather than silently matching nothing.\n return meta.notifyFn || (meta.notifyFn =\n (k) => _notifyMeta(meta, typeof k === \"string\" ? k : undefined));\n }\n case \"$set\": {\n const meta = target[META];\n return meta.setFn || (meta.setFn = (k, v) => {\n const parts = k.split(\".\");\n if (parts.some(p => _FORBIDDEN_CTX_KEYS.has(p))) return;\n if (parts.length === 1) {\n meta.proxy[k] = v;\n } else {\n let obj = meta.proxy;\n for (let i = 0; i < parts.length - 1; i++) {\n obj = obj[parts[i]];\n if (obj == null) return;\n }\n const lastKey = parts[parts.length - 1];\n const old = obj[lastKey];\n obj[lastKey] = v;\n if (old !== v) {\n // Bump the generation so _collectKeys' cache invalidates, mirroring the\n // set trap. Otherwise a nested $set leaves stale vals cached.\n _ctxGeneration++;\n _notifyMeta(meta, parts[0]);\n }\n }\n });\n }\n case \"$parent\": return target[META].parent;\n case \"$refs\": return _refs;\n case \"$store\": return _stores;\n case \"$route\": return _routerInstance ? _routerInstance.current : {};\n case \"$router\": return _routerInstance;\n case \"$i18n\": return _i18nProxy;\n case \"$form\": return target.$form || null;\n }\n\n // Plugin globals fallback (after all core $ checks)\n const globalKey = key.slice(1);\n if (globalKey in _globals) return _globals[globalKey];\n\n // Target / parent chain lookup\n if (key in target) return target[key];\n const parent = target[META].parent;\n if (parent && parent.__isProxy) return parent[key];\n return undefined;\n },\n set(target, key, value) {\n if (typeof key === \"string\" && _FORBIDDEN_CTX_KEYS.has(key)) return true;\n const old = target[key];\n target[key] = value;\n if (old !== value) {\n _ctxGeneration++;\n _notifyMeta(target[META], typeof key === \"string\" ? key : undefined);\n if (_config.devtools) {\n let isSensitive = false;\n if (typeof key === \"string\") {\n const lk = key.toLowerCase();\n for (const s of _SENSITIVE_KEYS) {\n if (lk.includes(s)) { isSensitive = true; break; }\n }\n }\n _devtoolsEmit(\"ctx:updated\", {\n id: target.__devtoolsId,\n key,\n oldValue: isSensitive ? \"[REDACTED]\" : old,\n newValue: isSensitive ? \"[REDACTED]\" : value,\n });\n }\n }\n return true;\n },\n has(target, key) {\n if (key in target) return true;\n if (typeof key === \"string\" && key.startsWith(\"$\") && key.slice(1) in _globals) return true;\n const parent = target[META].parent;\n if (parent && parent.__isProxy) return key in parent;\n return false;\n },\n};\n\nexport function createContext(data = {}, parent = null) {\n const raw = {};\n Object.assign(raw, data);\n if (_config.devtools) raw.__devtoolsId = ++_ctxId;\n\n const meta = {\n parent,\n proxy: null,\n listeners: null,\n watchFn: null,\n notifyFn: null,\n setFn: null,\n };\n raw[META] = meta;\n const proxy = new Proxy(raw, _sharedHandler);\n meta.proxy = proxy;\n\n if (_config.devtools && raw.__devtoolsId) {\n _ctxRegistry.set(raw.__devtoolsId, proxy);\n _devtoolsEmit(\"ctx:created\", {\n id: raw.__devtoolsId,\n parentId: parent?.__raw?.__devtoolsId ?? null,\n keys: Object.keys(data),\n elementTag: _currentEl?.tagName?.toLowerCase() ?? null,\n });\n }\n\n return proxy;\n}\n\n// Collect all keys from a context + its parent chain\n// Result is cached per context and invalidated on any reactive mutation.\nexport function _collectKeys(ctx) {\n const cache = ctx.__raw.__collectKeysCache;\n if (cache && cache.gen === _ctxGeneration) return cache.result;\n\n const allKeys = new Set();\n const allVals = {};\n let c = ctx;\n while (c && c.__isProxy) {\n const raw = c.__raw;\n for (const k of Object.keys(raw)) {\n if (!allKeys.has(k)) {\n allKeys.add(k);\n allVals[k] = raw[k];\n }\n }\n c = c.$parent;\n }\n const result = { keys: [...allKeys], vals: allVals };\n ctx.__raw.__collectKeysCache = { gen: _ctxGeneration, result };\n return result;\n}\n", "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// DEVTOOLS PROTOCOL\n// Zero-overhead runtime inspection, mutation, and monitoring.\n// All hooks are guarded by _config.devtools \u2014 no cost when disabled.\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nimport { _config, _stores, _refs, _routerInstance, _plugins, _globals } from \"./globals.js\";\nimport { _i18n } from \"./i18n.js\";\n\n// \u2500\u2500\u2500 Context registry (populated by createContext when devtools enabled) \u2500\u2500\u2500\u2500\n// Maps __devtoolsId \u2192 Proxy reference for inspect/mutate commands.\nexport const _ctxRegistry = new Map();\n\n// \u2500\u2500\u2500 Hostname guard \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Optional `hostname` param exists for unit-testing without window.location mocking.\nexport function _isLocalHostname(hostname) {\n if (hostname === undefined) {\n hostname = (typeof window !== \"undefined\" && window.location) ? window.location.hostname : \"\";\n }\n return (\n hostname === \"\" ||\n hostname === \"localhost\" ||\n hostname === \"127.0.0.1\" ||\n hostname === \"::1\" ||\n hostname === \"0.0.0.0\" ||\n hostname.endsWith(\".localhost\")\n );\n}\n\n// \u2500\u2500\u2500 Emit a devtools event \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport function _devtoolsEmit(type, data) {\n if (!_config.devtools || typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"nojs:devtools\", {\n detail: { type, data, timestamp: Date.now() },\n }),\n );\n}\n\n// \u2500\u2500\u2500 Serialization helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction _safeSnapshot(proxy, seen) {\n if (!proxy || !proxy.__isProxy) return null;\n const raw = proxy.__raw;\n // Cycle detection: a self-referential reactive object would otherwise recurse\n // forever (RangeError: Maximum call stack size exceeded).\n if (!seen) seen = new WeakSet();\n if (raw && seen.has(raw)) return \"[Circular]\";\n if (raw) seen.add(raw);\n const snapshot = {};\n for (const key of Object.keys(raw)) {\n if (key.startsWith(\"__\")) continue;\n const val = raw[key];\n if (val && typeof val === \"object\" && val.__isProxy) {\n snapshot[key] = _safeSnapshot(val, seen);\n } else {\n try {\n // Verify serializable \u2014 drop functions and circular refs\n JSON.stringify(val);\n snapshot[key] = val;\n } catch {\n snapshot[key] = String(val);\n }\n }\n }\n return snapshot;\n}\n\nfunction _cssEscape(s) {\n return (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\")\n ? CSS.escape(s)\n : s;\n}\n\nfunction _elementTag(el) {\n if (!el || !el.tagName) return null;\n const tag = el.tagName.toLowerCase();\n const id = el.id ? `#${_cssEscape(el.id)}` : \"\";\n // SVG elements expose className as an SVGAnimatedString (not a string), so the\n // typeof guard skips them. Escape each class so special chars stay valid selectors.\n const cls = el.className && typeof el.className === \"string\"\n ? el.className.trim().split(/\\s+/).filter(Boolean).map((c) => \".\" + _cssEscape(c)).join(\"\")\n : \"\";\n return tag + id + cls;\n}\n\n// \u2500\u2500\u2500 Inspect commands \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction _inspectElement(selector) {\n const el = document.querySelector(selector);\n if (!el) return { error: \"Element not found\", selector };\n const ctx = el.__ctx;\n return {\n selector,\n tag: _elementTag(el),\n hasContext: !!ctx,\n contextId: ctx?.__raw?.__devtoolsId ?? null,\n data: ctx ? _safeSnapshot(ctx) : null,\n directives: [...el.attributes]\n .filter((a) => ![\"class\", \"id\", \"style\"].includes(a.name))\n .map((a) => ({ name: a.name, value: a.value })),\n };\n}\n\nfunction _inspectStore(name) {\n const store = _stores[name];\n if (!store) return { error: \"Store not found\", name };\n return {\n name,\n contextId: store.__raw?.__devtoolsId ?? null,\n data: _safeSnapshot(store),\n };\n}\n\nfunction _inspectTree(selector) {\n const root = selector ? document.querySelector(selector) : document.body;\n if (!root) return { error: \"Root not found\", selector };\n\n function walk(el) {\n const ctx = el.__ctx;\n const node = {\n tag: _elementTag(el),\n contextId: ctx?.__raw?.__devtoolsId ?? null,\n children: [],\n };\n for (const child of el.children) {\n if (child.tagName === \"TEMPLATE\" || child.tagName === \"SCRIPT\") continue;\n if (child.__ctx || child.__declared) {\n node.children.push(walk(child));\n }\n }\n return node;\n }\n\n return walk(root);\n}\n\nfunction _mutateContext(id, key, value) {\n const proxy = _ctxRegistry.get(id);\n if (!proxy) return { error: \"Context not found\", id };\n proxy[key] = value;\n return { ok: true, id, key };\n}\n\nfunction _mutateStore(name, key, value) {\n const store = _stores[name];\n if (!store) return { error: \"Store not found\", name };\n store[key] = value;\n return { ok: true, name, key };\n}\n\nfunction _getStats() {\n let listenerCount = 0;\n for (const [, proxy] of _ctxRegistry) {\n if (proxy.__listeners) listenerCount += proxy.__listeners.size;\n }\n return {\n contexts: _ctxRegistry.size,\n stores: Object.keys(_stores).length,\n listeners: listenerCount,\n refs: Object.keys(_refs).length,\n hasRouter: !!_routerInstance,\n locale: _i18n.locale,\n };\n}\n\n// \u2500\u2500\u2500 Highlight overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet _highlightOverlay = null;\nlet _highlightTarget = null;\nlet _highlightReposition = null;\n\nfunction _positionHighlight() {\n if (!_highlightOverlay || !_highlightTarget) return;\n const rect = _highlightTarget.getBoundingClientRect();\n Object.assign(_highlightOverlay.style, {\n top: rect.top + \"px\",\n left: rect.left + \"px\",\n width: rect.width + \"px\",\n height: rect.height + \"px\",\n });\n}\n\nfunction _highlightElement(selector) {\n _unhighlight();\n const el = document.querySelector(selector);\n if (!el) return;\n _highlightTarget = el;\n _highlightOverlay = document.createElement(\"div\");\n _highlightOverlay.id = \"__nojs_devtools_highlight__\";\n Object.assign(_highlightOverlay.style, {\n position: \"fixed\",\n background: \"rgba(66, 133, 244, 0.25)\",\n border: \"2px solid rgba(66, 133, 244, 0.8)\",\n pointerEvents: \"none\",\n zIndex: \"2147483647\",\n borderRadius: \"3px\",\n });\n document.body.appendChild(_highlightOverlay);\n _positionHighlight();\n // Keep the overlay anchored to its target on scroll/resize while shown.\n _highlightReposition = () => _positionHighlight();\n window.addEventListener(\"scroll\", _highlightReposition, true);\n window.addEventListener(\"resize\", _highlightReposition);\n}\n\nfunction _unhighlight() {\n if (_highlightReposition) {\n window.removeEventListener(\"scroll\", _highlightReposition, true);\n window.removeEventListener(\"resize\", _highlightReposition);\n _highlightReposition = null;\n }\n if (_highlightOverlay) {\n _highlightOverlay.remove();\n _highlightOverlay = null;\n }\n _highlightTarget = null;\n}\n\n// \u2500\u2500\u2500 Command handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction _handleDevtoolsCommand(event) {\n const { command, args = {} } = event.detail || {};\n let result;\n\n switch (command) {\n case \"inspect:element\":\n result = _inspectElement(args.selector);\n break;\n case \"inspect:store\":\n result = _inspectStore(args.name);\n break;\n case \"inspect:tree\":\n result = _inspectTree(args.selector);\n break;\n case \"mutate:context\":\n result = _mutateContext(args.id, args.key, args.value);\n break;\n case \"mutate:store\":\n result = _mutateStore(args.name, args.key, args.value);\n break;\n case \"get:config\":\n result = { ..._config };\n if (result.csrf) result.csrf = { ...result.csrf, token: '[REDACTED]' };\n if (result.headers) result.headers = '[REDACTED]';\n break;\n case \"get:routes\":\n result = _routerInstance ? _routerInstance.routes || [] : [];\n break;\n case \"get:stats\":\n result = _getStats();\n break;\n case \"highlight:element\":\n _highlightElement(args.selector);\n result = { ok: true };\n break;\n case \"unhighlight\":\n _unhighlight();\n result = { ok: true };\n break;\n default:\n result = { error: \"Unknown command\", command };\n }\n\n // Respond with result\n window.dispatchEvent(\n new CustomEvent(\"nojs:devtools:response\", {\n detail: { command, result, timestamp: Date.now() },\n }),\n );\n}\n\n// \u2500\u2500\u2500 Cleanup reference \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nlet _devtoolsCleanup = null;\n\n// Called from NoJS.dispose() to remove the command listener and clean up.\nexport function destroyDevtools() {\n // Remove any lingering highlight overlay + its scroll/resize listeners.\n _unhighlight();\n if (_devtoolsCleanup) _devtoolsCleanup();\n}\n\n// \u2500\u2500\u2500 Initialization \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport function initDevtools(nojs) {\n if (!_config.devtools || typeof window === \"undefined\") return;\n\n if (!_isLocalHostname()) {\n console.warn(\"[No.JS] devtools: true is ignored outside local environments. Remove devtools: true before deploying to production.\");\n return;\n }\n\n // Listen for commands (store reference for cleanup)\n window.addEventListener(\"nojs:devtools:cmd\", _handleDevtoolsCommand);\n _devtoolsCleanup = () => {\n window.removeEventListener(\"nojs:devtools:cmd\", _handleDevtoolsCommand);\n delete window.__NOJS_DEVTOOLS__;\n _devtoolsCleanup = null;\n };\n\n // Expose public API on window\n window.__NOJS_DEVTOOLS__ = {\n // Data access (read-only snapshots \u2014 no live references leak)\n get stores() {\n return Object.fromEntries(\n Object.entries(_stores).map(([k, v]) => [k, _safeSnapshot(v)])\n );\n },\n get config() {\n const c = { ..._config };\n if (c.headers) c.headers = { ...c.headers };\n if (c.router) c.router = { ...c.router };\n if (c.cache) c.cache = { ...c.cache };\n if (c.csrf) c.csrf = { ...c.csrf };\n if (c.i18n) c.i18n = { ...c.i18n };\n return c;\n },\n get refs() { return { ..._refs }; },\n router: _routerInstance,\n version: nojs.version,\n get plugins() { return new Map(_plugins); },\n get globals() { return { ..._globals }; },\n\n // Inspect API\n inspect: (selector) => _inspectElement(selector),\n inspectStore: (name) => _inspectStore(name),\n inspectTree: (selector) => _inspectTree(selector),\n stats: () => _getStats(),\n\n // Mutation API\n mutate: (id, key, value) => _mutateContext(id, key, value),\n mutateStore: (name, key, value) => _mutateStore(name, key, value),\n\n // Visual\n highlight: (selector) => _highlightElement(selector),\n unhighlight: () => _unhighlight(),\n\n // Event subscription shorthand\n on: (type, fn) => {\n const handler = (e) => {\n if (!type || e.detail.type === type) fn(e.detail);\n };\n window.addEventListener(\"nojs:devtools\", handler);\n return () => window.removeEventListener(\"nojs:devtools\", handler);\n },\n };\n\n console.log(\"[No.JS DevTools] enabled \u2014 access via window.__NOJS_DEVTOOLS__\");\n}\n", "// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n// EXPRESSION EVALUATOR\n// \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n\nimport { _config, _stores, _routerInstance, _filters, _warn, _notifyStoreWatchers, _extractStoreName, _globals, _setExprRootKeysFn } from \"./globals.js\";\nimport { _i18nProxy } from \"./i18n.js\";\nimport { _collectKeys, _startBatch, _endBatch } from \"./context.js\";\n\nfunction _makeCache() {\n const map = new Map();\n return {\n get(k) {\n if (!map.has(k)) return undefined;\n // Move to end so this entry is the most-recently-used\n const v = map.get(k);\n map.delete(k);\n map.set(k, v);\n return v;\n },\n has(k) { return map.has(k); },\n set(k, v) {\n const max = _config.exprCacheSize;\n if (map.has(k)) {\n map.delete(k); // refresh position before re-inserting\n } else if (map.size >= max) {\n map.delete(map.keys().next().value); // evict LRU (insertion-order first)\n }\n map.set(k, v);\n },\n get size() { return map.size; },\n };\n}\nexport const _exprCache = _makeCache();\nexport const _stmtCache = _makeCache();\n\n// \u2500\u2500 Tokenizer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst _KEYWORDS = new Set([\"true\", \"false\", \"null\", \"undefined\", \"typeof\", \"in\", \"instanceof\"]);\nconst _FORBIDDEN = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\n// Multi-char operators/punctuation, sorted longest-first for greedy matching\nconst _MULTI = [\"===\", \"!==\", \"...\", \"??\", \"?.\", \"==\", \"!=\", \">=\", \"<=\", \"&&\", \"||\", \"+=\", \"-=\", \"*=\", \"/=\", \"%=\", \"++\", \"--\", \"=>\"];\nconst _SINGLE_OPS = new Set([\"+\", \"-\", \"*\", \"/\", \"%\", \">\", \"<\", \"!\", \"=\", \"|\"]);\nconst _SINGLE_PUNC = new Set([\"(\", \")\", \"[\", \"]\", \"{\", \"}\", \".\", \",\", \":\", \";\", \"?\"]);\n\nfunction _tokenize(expr) {\n if (typeof expr !== \"string\") return [];\n const tokens = [];\n const len = expr.length;\n let pos = 0;\n\n while (pos < len) {\n const ch = expr[pos];\n\n // Skip whitespace\n if (ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\") { pos++; continue; }\n\n // String literals (single or double quoted)\n if (ch === \"'\" || ch === '\"') {\n const start = pos;\n const quote = ch;\n pos++;\n let value = \"\";\n while (pos < len && expr[pos] !== quote) {\n if (expr[pos] === \"\\\\\") {\n pos++;\n if (pos < len) {\n const esc = expr[pos];\n if (esc === \"n\") value += \"\\n\";\n else if (esc === \"t\") value += \"\\t\";\n else if (esc === \"r\") value += \"\\r\";\n else value += esc;\n pos++;\n }\n } else {\n value += expr[pos++];\n }\n }\n if (pos < len) pos++; // skip closing quote\n tokens.push({ type: \"String\", value, pos: start });\n continue;\n }\n\n // Template literals\n if (ch === \"`\") {\n const start = pos;\n pos++;\n const parts = [];\n const exprs = [];\n let seg = \"\";\n while (pos < len && expr[pos] !== \"`\") {\n if (expr[pos] === \"\\\\\" && pos + 1 < len) {\n const esc = expr[pos + 1];\n if (esc === \"n\") seg += \"\\n\";\n else if (esc === \"t\") seg += \"\\t\";\n else if (esc === \"r\") seg += \"\\r\";\n else seg += esc;\n pos += 2;\n } else if (expr[pos] === \"$\" && pos + 1 < len && expr[pos + 1] === \"{\") {\n parts.push(seg);\n seg = \"\";\n pos += 2; // skip ${\n // Collect expression text respecting nested braces\n let depth = 1;\n let inner = \"\";\n while (pos < len && depth > 0) {\n if (expr[pos] === \"{\") depth++;\n else if (expr[pos] === \"}\") { depth--; if (depth === 0) break; }\n else if (expr[pos] === \"'\" || expr[pos] === '\"' || expr[pos] === \"`\") {\n // skip string inside interpolation\n const q = expr[pos];\n inner += q; pos++;\n while (pos < len && expr[pos] !== q) {\n if (expr[pos] === \"\\\\\") { inner += expr[pos++]; if (pos < len) inner += expr[pos++]; }\n else inner += expr[pos++];\n }\n if (pos < len) { inner += expr[pos]; pos++; }\n continue;\n }\n inner += expr[pos++];\n }\n if (pos < len) pos++; // skip closing }\n exprs.push(_tokenize(inner));\n } else {\n seg += expr[pos++];\n }\n }\n if (pos < len) pos++; // skip closing `\n parts.push(seg);\n tokens.push({ type: \"Template\", parts, exprs, pos: start });\n continue;\n }\n\n // Numbers: starts with digit, or '.' followed by digit\n if ((ch >= \"0\" && ch <= \"9\") || (ch === \".\" && pos + 1 < len && expr[pos + 1] >= \"0\" && expr[pos + 1] <= \"9\")) {\n const start = pos;\n let num = \"\";\n while (pos < len && ((expr[pos] >= \"0\" && expr[pos] <= \"9\") || expr[pos] === \".\")) {\n num += expr[pos++];\n }\n tokens.push({ type: \"Number\", value: num, pos: start });\n continue;\n }\n\n // Identifiers / Keywords\n if ((ch >= \"a\" && ch <= \"z\") || (ch >= \"A\" && ch <= \"Z\") || ch === \"_\" || ch === \"$\") {\n const start = pos;\n let id = \"\";\n while (pos < len) {\n const c = expr[pos];\n if ((c >= \"a\" && c <= \"z\") || (c >= \"A\" && c <= \"Z\") || (c >= \"0\" && c <= \"9\") || c === \"_\" || c === \"$\") {\n id += c; pos++;\n } else break;\n }\n if (_FORBIDDEN.has(id)) tokens.push({ type: \"Forbidden\", value: id, pos: start });\n else if (_KEYWORDS.has(id)) tokens.push({ type: \"Keyword\", value: id, pos: start });\n else tokens.push({ type: \"Ident\", value: id, pos: start });\n continue;\n }\n\n // Multi-char operators / punctuation (longest first)\n let matched = false;\n for (let m = 0; m < _MULTI.length; m++) {\n const op = _MULTI[m];\n if (expr.startsWith(op, pos)) {\n const isPunc = op === \"...\" || op === \"?.\";\n tokens.push({ type: isPunc ? \"Punc\" : \"Op\", value: op, pos });\n pos += op.length;\n matched = true;\n break;\n }\n }\n if (matched) continue;\n\n // Single-char operators\n if (_SINGLE_OPS.has(ch)) {\n tokens.push({ type: \"Op\", value: ch, pos });\n pos++;\n continue;\n }\n\n // Single-char punctuation\n if (_SINGLE_PUNC.has(ch)) {\n tokens.push({ type: \"Punc\", value: ch, pos });\n pos++;\n continue;\n }\n\n // Unrecognized character \u2014 skip\n pos++;\n }\n\n return tokens;\n}\n\n// \u2500\u2500 Recursive-descent expression parser \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction _parseExpr(tokens) {\n if (!tokens || tokens.length === 0) return { type: \"Literal\", value: undefined };\n\n let pos = 0;\n\n function peek() { return tokens[pos]; }\n function next() { return tokens[pos++]; }\n\n function match(type, value) {\n const t = tokens[pos];\n if (!t) return false;\n if (value !== undefined) return t.type === type && t.value === value;\n return t.type === type;\n }\n\n function expect(type, value) {\n const t = tokens[pos];\n if (t && t.type === type && (value === undefined || t.value === value)) {\n pos++;\n return t;\n }\n return null;\n }\n\n // \u2500\u2500\u2500 Grammar rules (lowest \u2192 highest precedence) \u2500\u2500\u2500\n\n function parseExpression() {\n return parseTernary();\n }\n\n function parseTernary() {\n let node = parseNullishOr();\n if (match(\"Punc\", \"?\")) {\n next(); // consume ?\n const consequent = parseTernary();\n expect(\"Punc\", \":\");\n const alternate = parseTernary();\n node = { type: \"ConditionalExpr\", test: node, consequent, alternate };\n }\n return node;\n }\n\n function parseNullishOr() {\n let node = parseLogicalOr();\n if (match(\"Op\", \"??\")) {\n next();\n const right = parseNullishOr();\n node = { type: \"BinaryExpr\", op: \"??\", left: node, right };\n }\n return node;\n }\n\n function parseLogicalOr() {\n let node = parseLogicalAnd();\n while (match(\"Op\", \"||\")) {\n next();\n const right = parseLogicalAnd();\n node = { type: \"BinaryExpr\", op: \"||\", left: node, right };\n }\n return node;\n }\n\n function parseLogicalAnd() {\n let node = parseBitwiseOr();\n while (match(\"Op\", \"&&\")) {\n next();\n const right = parseBitwiseOr();\n node = { type: \"BinaryExpr\", op: \"&&\", left: node, right };\n }\n return node;\n }\n\n function parseBitwiseOr() {\n let node = parseComparison();\n while (peek() && peek().type === \"Op\" && peek().value === \"|\" && (!tokens[pos + 1] || tokens[pos + 1].value !== \"|\")) {\n next();\n const right = parseComparison();\n node = { type: \"BinaryExpr\", op: \"|\", left: node, right };\n }\n return node;\n }\n\n function parseComparison() {\n let node = parseAddition();\n const t = peek();\n if (!t) return node;\n const compOps = [\"===\", \"!==\", \"==\", \"!=\", \">=\", \"<=\", \">\", \"<\"];\n if ((t.type === \"Op\" && compOps.indexOf(t.value) !== -1) ||\n (t.type === \"Keyword\" && (t.value === \"in\" || t.value === \"instanceof\"))) {\n const op = next().value;\n const right = parseAddition();\n node = { type: \"BinaryExpr\", op, left: node, right };\n }\n return node;\n }\n\n function parseAddition() {\n let node = parseMultiplication();\n while (peek() && peek().type === \"Op\" && (peek().value === \"+\" || peek().value === \"-\")) {\n const op = next().value;\n const right = parseMultiplication();\n node = { type: \"BinaryExpr\", op, left: node, right };\n }\n return node;\n }\n\n function parseMultiplication() {\n let node = parseUnary();\n while (peek() && peek().type === \"Op\" && (peek().value === \"*\" || peek().value === \"/\" || peek().value === \"%\")) {\n const op = next().value;\n const right = parseUnary();\n node = { type: \"BinaryExpr\", op, left: node, right };\n }\n return node;\n }\n\n function parseUnary() {\n const t = peek();\n if (!t) return { type: \"Literal\", value: undefined };\n // typeof\n if (t.type === \"Keyword\" && t.value === \"typeof\") {\n next();\n return { type: \"UnaryExpr\", op: \"typeof\", argument: parseUnary() };\n }\n // ! or unary - or unary +\n if (t.type === \"Op\" && (t.value === \"!\" || t.value === \"-\" || t.value === \"+\")) {\n next();\n return { type: \"UnaryExpr\", op: t.value, argument: parseUnary() };\n }\n // Prefix ++ / --\n if (t.type === \"Op\" && (t.value === \"++\" || t.value === \"--\")) {\n next();\n return { type: \"UnaryExpr\", op: t.value, argument: parseUnary(), prefix: true };\n }\n return parsePostfix();\n }\n\n function parsePostfix() {\n let node = parseCallMember();\n const t = peek();\n if (t && t.type === \"Op\" && (t.value === \"++\" || t.value === \"--\")) {\n next();\n node = { type: \"PostfixExpr\", op: t.value, argument: node };\n }\n return node;\n }\n\n function parseCallMember() {\n let node = parsePrimary();\n\n while (true) {\n const t = peek();\n if (!t) break;\n\n // Dot access: obj.prop\n if (t.type === \"Punc\" && t.value === \".\") {\n next();\n const prop = peek();\n if (prop && (prop.type === \"Ident\" || prop.type === \"Keyword\")) {\n next();\n node = { type: \"MemberExpr\", object: node, property: { type: \"Identifier\", name: prop.value }, computed: false };\n } else if (prop && prop.type === \"Forbidden\") {\n next();\n node = { type: \"Forbidden\" };\n } else {\n break;\n }\n continue;\n }\n\n // Optional chaining: obj?.prop or obj?.(args)\n if (t.type === \"Punc\" && t.value === \"?.\") {\n next();\n const nt = peek();\n // Optional call: obj?.(args)\n if (nt && nt.type === \"Punc\" && nt.value === \"(\") {\n next(); // consume (\n const args = parseArgsList();\n expect(\"Punc\", \")\");\n node = { type: \"OptionalCallExpr\", callee: node, args };\n }\n // Optional member: obj?.prop\n else if (nt && (nt.type === \"Ident\" || nt.type === \"Keyword\")) {\n next();\n node = { type: \"OptionalMemberExpr\", object: node, property: { type: \"Identifier\", name: nt.value }, computed: false };\n }\n // Optional bracket: obj?.[expr]\n else if (nt && nt.type === \"Punc\" && nt.value === \"[\") {\n next(); // consume [\n const prop = parseExpression();\n expect(\"Punc\", \"]\");\n node = { type: \"OptionalMemberExpr\", object: node, property: prop, computed: true };\n } else {\n break;\n }\n continue;\n }\n\n // Bracket access: obj[expr]\n if (t.type === \"Punc\" && t.value === \"[\") {\n next();\n const prop = parseExpression();\n expect(\"Punc\", \"]\");\n node = { type: \"MemberExpr\", object: node, property: prop, computed: true };\n continue;\n }\n\n // Function call: fn(args)\n if (t.type === \"Punc\" && t.value === \"(\") {\n next();\n const args = parseArgsList();\n expect(\"Punc\", \")\");\n node = { type: \"CallExpr\", callee: node, args };\n continue;\n }\n\n break;\n }\n\n return node;\n }\n\n function parseArgsList() {\n const args = [];\n if (match(\"Punc\", \")\")) return args;\n args.push(parseSpreadOrExpr());\n while (match(\"Punc\", \",\")) {\n next();\n if (match(\"Punc\", \")\")) break; // trailing comma\n args.push(parseSpreadOrExpr());\n }\n return args;\n }\n\n function parseSpreadOrExpr() {\n if (match(\"Punc\", \"...\")) {\n next();\n return { type: \"SpreadElement\", argument: parseExpression() };\n }\n return parseExpression();\n }\n\n // \u2500\u2500\u2500 Arrow function detection helpers \u2500\u2500\u2500\n\n function isArrowParams() {\n // Lookahead from current pos (after consuming \"(\") to see if this is (id, id, ...) =>\n const saved = pos;\n // Empty params: () =>\n if (match(\"Punc\", \")\")) {\n const after = tokens[pos + 1];\n if (after && after.type === \"Op\" && after.value === \"=>\") {\n pos = saved;\n return true;\n }\n pos = saved;\n return false;\n }\n // Check for ident list followed by ) =>\n while (pos < tokens.length) {\n const t = peek();\n if (!t) break;\n if (t.type === \"Ident\") {\n next();\n if (match(\"Punc\", \",\")) {\n next();\n continue;\n }\n if (match(\"Punc\", \")\")) {\n const after = tokens[pos + 1];\n if (after && after.type === \"Op\" && after.value === \"=>\") {\n pos = saved;\n return true;\n }\n pos = saved;\n return false;\n }\n pos = saved;\n return false;\n }\n // Spread param: (...rest) =>\n if (t.type === \"Punc\" && t.value === \"...\") {\n next();\n if (match(\"Ident\")) { next(); }\n if (match(\"Punc\", \")\")) {\n const after = tokens[pos + 1];\n if (after && after.type === \"Op\" && after.value === \"=>\") {\n pos = saved;\n return true;\n }\n }\n pos = saved;\n return false;\n }\n pos = saved;\n return false;\n }\n pos = saved;\n return false;\n }\n\n function parseArrowParams() {\n // Parse comma-separated identifiers until \")\"\n const params = [];\n if (match(\"Punc\", \")\")) return params;\n if (match(\"Punc\", \"...\")) {\n next();\n if (match(\"Ident\")) params.push(\"...\" + next().value);\n } else if (match(\"Ident\")) {\n params.push(next().value);\n }\n while (match(\"Punc\", \",\")) {\n next();\n if (match(\"Punc\", \")\")) break;\n if (match(\"Punc\", \"...\")) {\n next();\n if (match(\"Ident\")) params.push(\"...\" + next().value);\n } else if (match(\"Ident\")) {\n params.push(next().value);\n }\n }\n return params;\n }\n\n // \u2500\u2500\u2500 Primary \u2500\u2500\u2500\n\n function parsePrimary() {\n const t = peek();\n if (!t) return { type: \"Literal\", value: undefined };\n\n // Forbidden token\n if (t.type === \"Forbidden\") {\n next();\n return { type: \"Forbidden\" };\n }\n\n // Number literal\n if (t.type === \"Number\") {\n next();\n return { type: \"Literal\", value: Number(t.value) };\n }\n\n // String literal\n if (t.type === \"String\") {\n next();\n return { type: \"Literal\", value: t.value };\n }\n\n // Template literal\n if (t.type === \"Template\") {\n next();\n return {\n type: \"TemplateLiteral\",\n parts: t.parts,\n expressions: t.exprs.map(function(exprTokens) { return _parseExpr(exprTokens); })\n };\n }\n\n // Keywords: true, false, null, undefined\n if (t.type === \"Keyword\") {\n if (t.value === \"true\") { next(); return { type: \"Literal\", value: true }; }\n if (t.value === \"false\") { next(); return { type: \"Literal\", value: false }; }\n if (t.value === \"null\") { next(); return { type: \"Literal\", value: null }; }\n if (t.value === \"undefined\") { next(); return { type: \"Literal\", value: undefined }; }\n }\n\n // Array literal: [...]\n if (t.type === \"Punc\" && t.value === \"[\") {\n next();\n const elements = [];\n while (!match(\"Punc\", \"]\") && pos < tokens.length) {\n elements.push(parseSpreadOrExpr());\n if (match(\"Punc\", \",\")) next();\n }\n expect(\"Punc\", \"]\");\n return { type: \"ArrayExpr\", elements };\n }\n\n // Object literal: { ... }\n if (t.type === \"Punc\" && t.value === \"{\") {\n return parseObjectLiteral();\n }\n\n // Parenthesized expression or arrow function with parens\n if (t.type === \"Punc\" && t.value === \"(\") {\n next(); // consume (\n\n // Check for arrow function: (params) =>\n if (isArrowParams()) {\n const params = parseArrowParams();\n expect(\"Punc\", \")\");\n expect(\"Op\", \"=>\");\n const body = parseExpression();\n return { type: \"ArrowFunction\", params, body };\n }\n\n // Regular grouping\n const expr = parseExpression();\n expect(\"Punc\", \")\");\n return expr;\n }\n\n // Identifier (possibly arrow: x => ...)\n if (t.type === \"Ident\") {\n next();\n // Single-param arrow function: x => expr\n if (match(\"Op\", \"=>\")) {\n next(); // consume =>\n const body = parseExpression();\n return { type: \"ArrowFunction\", params: [t.value], body };\n }\n return { type: \"Identifier\", name: t.value };\n }\n\n // Assignment operators\n if (t.type === \"Op\" && (t.value === \"=\" || t.value === \"+=\" || t.value === \"-=\" || t.value === \"*=\" || t.value === \"/=\" || t.value === \"%=\")) {\n // Should not appear as primary; skip\n next();\n return { type: \"Literal\", value: undefined };\n }\n\n // Spread in unexpected position (e.g. top level)\n if (t.type === \"Punc\" && t.value === \"...\") {\n next();\n return { type: \"SpreadElement\", argument: parseExpression() };\n }\n\n // Fallback: skip unrecognized token\n next();\n return { type: \"Literal\", value: undefined };\n }\n\n function parseObjectLiteral() {\n next(); // consume {\n const properties = [];\n while (!match(\"Punc\", \"}\") && pos < tokens.length) {\n // Spread property: ...expr\n if (match(\"Punc\", \"...\")) {\n next();\n properties.push({ key: null, value: parseExpression(), computed: false, spread: true });\n if (match(\"Punc\", \",\")) next();\n continue;\n }\n\n // Computed property: [expr]: value\n if (match(\"Punc\", \"[\")) {\n next();\n const keyExpr = parseExpression();\n expect(\"Punc\", \"]\");\n expect(\"Punc\", \":\");\n const val = parseExpression();\n properties.push({ key: keyExpr, value: val, computed: true, spread: false });\n if (match(\"Punc\", \",\")) next();\n continue;\n }\n\n // String key: 'key': value\n if (match(\"String\")) {\n const keyToken = next();\n if (match(\"Punc\", \":\")) {\n next();\n const val = parseExpression();\n properties.push({ key: keyToken.value, value: val, computed: false, spread: false });\n }\n if (match(\"Punc\", \",\")) next();\n continue;\n }\n\n // Identifier key (shorthand or key: value)\n if (match(\"Ident\") || match(\"Keyword\")) {\n const keyToken = next();\n if (match(\"Punc\", \":\")) {\n next();\n const val = parseExpression();\n properties.push({ key: keyToken.value, value: val, computed: false, spread: false });\n } else {\n // Shorthand: { key } \u2192 { key: key }\n properties.push({\n key: keyToken.value,\n value: { type: \"Identifier\", name: keyToken.value },\n computed: false,\n spread: false\n });\n }\n if (match(\"Punc\", \",\")) next();\n continue;\n }\n\n // Number key\n if (match(\"Number\")) {\n const keyToken = next();\n if (match(\"Punc\", \":\")) {\n next();\n const val = parseExpression();\n properties.push({ key: keyToken.value, value: val, computed: false, spread: false });\n }\n if (match(\"Punc\", \",\")) next();\n continue;\n }\n\n // Unrecognized \u2014 skip\n next();\n }\n expect(\"Punc\", \"}\");\n return { type: \"ObjectExpr\", properties };\n }\n\n // \u2500\u2500\u2500 Handle top-level assignment \u2500\u2500\u2500\n\n function parseTopLevel() {\n const expr = parseExpression();\n // Check for assignment at top level: ident = expr, ident += expr, etc.\n const t = peek();\n if (t && t.type === \"Op\" && (t.value === \"=\" || t.value === \"+=\" || t.value === \"-=\" || t.value === \"*=\" || t.value === \"/=\" || t.value === \"%=\")) {\n const op = next().value;\n const right = parseExpression();\n return { type: \"AssignExpr\", op, left: expr, right };\n }\n return expr;\n }\n\n const ast = parseTopLevel();\n return ast;\n}\n\n// ---------------------------------------------------------------------------\n// AST tree-walking evaluator\n// ---------------------------------------------------------------------------\nexport const _FORBIDDEN_PROPS = { __proto__: 1, constructor: 1, prototype: 1, alert: 1, confirm: 1, prompt: 1 };\n\n// Foreign-realm accessor names (VULNERABILITY F4 / NOJS-239). Reading any of\n// these off a raw DOM element (e.g. an