@jasonshimmy/custom-elements-runtime 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,31 +1,31 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("./custom-elements-runtime.cjs.js"),b=require("./namespace-helpers-BsKQl3aH.cjs"),P=require("./custom-elements-runtime.store.cjs.js"),g=require("./logger-DiXdWaF-.cjs"),T=require("./custom-elements-runtime.directives.cjs.js"),A=n=>n?typeof URLSearchParams>"u"?{}:Object.fromEntries(new URLSearchParams(n)):{},L=new WeakMap;function B(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function O(n){if(!n)return"/";let r=n.replace(/\/+/g,"/");return r.startsWith("/")||(r="/"+r),r.length>1&&r.endsWith("/")&&(r=r.slice(0,-1)),r}function D(n){const r=n.path||"/",e=O(r),f=e==="/"?[]:e.split("/").filter(Boolean),s=[],c=[];for(let i=0;i<f.length;i++){const d=f[i];if(d==="*"){if(i!==f.length-1)return g.devWarn(`Route '${n.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};const p=`splat${s.length}`;s.push(p),c.push("__SPLAT__");continue}const $=d.match(/^:([A-Za-z0-9_-]+)(\*)?$/);if($){const p=$[1],R=!!$[2];if(R&&i!==f.length-1)return g.devWarn(`Route '${n.path}' contains a splat param ':${p}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};s.push(p),c.push(R?"__SPLAT__":"([^/]+)");continue}c.push(B(d))}let o;if(c.length===0)o="^/$";else if(c[c.length-1]==="__SPLAT__"){const d=c.slice(0,-1).join("/");d?o=`^/${d}(?:/(.*))?(?:/)?$`:o="^(?:/(.*))?(?:/)?$"}else o=`^/${c.join("/")}(?:/)?$`;try{return{regex:new RegExp(o),paramNames:s}}catch(i){return g.devWarn(`Failed to compile route regex for '${n.path}': ${String(i)}`),{invalid:!0}}}const S=(n,r)=>{const e=O(r);for(const f of n){let s=L.get(f);if(s||(s=D(f),L.set(f,s)),s.invalid)continue;const{regex:c,paramNames:o}=s,i=c.exec(e);if(i){const d={},$=p=>{try{return decodeURIComponent(p)}catch{return p}};for(let p=0;p<o.length;p++){const R=i[p+1]||"";d[o[p]]=R?$(R):""}return{route:f,params:d}}}return{route:null,params:{}}};function q(n,r){for(const e of n)if(S([e],r).route!==null)return e;return null}const _={};async function j(n){if(n.component)return n.component;if(n.load){if(_[n.path])return _[n.path];try{const r=await n.load();return _[n.path]=r.default,r.default}catch{throw new Error(`Failed to load component for route: ${n.path}`)}}throw new Error(`No component or loader defined for route: ${n.path}`)}function N(n){const{routes:r,base:e="",initialUrl:f}=n;let s,c,o,i,d,$,p;const R=async(l,u)=>{const t=q(r,l.path);if(!t||!t.beforeEnter)return!0;try{const a=await t.beforeEnter(l,u);return typeof a=="string"?(await E(a,!0),!1):a!==!1}catch(a){return g.devError("beforeEnter error",a),!1}},C=async(l,u)=>{const t=q(r,l.path);if(!t||!t.onEnter)return!0;try{const a=await t.onEnter(l,u);return typeof a=="string"?(await E(a,!0),!1):a!==!1}catch(a){return g.devError("onEnter error",a),!1}},k=(l,u)=>{const t=q(r,l.path);if(!(!t||!t.afterEnter))try{t.afterEnter(l,u)}catch(a){g.devError("afterEnter error",a)}},E=async(l,u=!1)=>{try{const t={path:l.replace(e,"")||"/",query:{}},a=S(r,t.path);if(!a.route)throw new Error(`No route found for ${t.path}`);const m=o.getState(),h={path:t.path,params:a.params,query:t.query};if(!await R(h,m)||!await C(h,m))return;typeof window<"u"&&typeof document<"u"&&(u?window.history.replaceState({},"",e+l):window.history.pushState({},"",e+l)),o.setState(h),k(h,m)}catch(t){g.devError("Navigation error:",t)}};if(typeof window<"u"&&typeof document<"u"&&typeof f>"u"){s=()=>{const u=new URL(window.location.href),t=u.pathname.replace(e,"")||"/",a=A(u.search);return{path:t,query:a}},c=s();const l=S(r,c.path);o=P.createStore({path:c.path,params:l.params,query:c.query}),i=async(u=!1)=>{const t=s();await E(t.path,u)},window.addEventListener("popstate",()=>i(!0)),d=u=>E(u,!1),$=u=>E(u,!0),p=()=>window.history.back()}else{s=()=>{const t=new URL(f||"/","http://localhost"),a=t.pathname.replace(e,"")||"/",m=A(t.search);return{path:a,query:m}},c=s();const l=S(r,c.path);o=P.createStore({path:c.path,params:l.params,query:c.query}),i=async()=>{const t=s();await u(t.path)};const u=async t=>{try{const a={path:t.replace(e,"")||"/",query:{}},m=S(r,a.path);if(!m.route)throw new Error(`No route found for ${a.path}`);const h=o.getState(),v={path:a.path,params:m.params,query:a.query},w=q(r,v.path);if(w?.beforeEnter){const x=await w.beforeEnter(v,h);if(typeof x=="string"){await u(x);return}if(x===!1)return}if(w?.onEnter){const x=await w.onEnter(v,h);if(typeof x=="string"){await u(x);return}if(x===!1)return}o.setState(v),w?.afterEnter&&w.afterEnter(v,h)}catch(a){throw g.devError("SSR navigation error:",a),a}};d=async t=>u(t),$=async t=>u(t),p=()=>{}}return{store:o,push:d,replace:$,back:p,subscribe:o.subscribe,matchRoute:l=>S(r,l),getCurrent:()=>o.getState(),resolveRouteComponent:j}}function U(n,r){return S(n,r)}let W=null;function M(n){const r=N(n);return W=r,y.component("router-view",async()=>{const e=W||r;if(!e)return y.html`<div>Router not initialized.</div>`;const f=b.ref(e.getCurrent());let s;y.useOnConnected(()=>{try{e&&typeof e.subscribe=="function"&&(s=e.subscribe(o=>{try{f.value=o}catch(i){g.devWarn("router-view subscription update failed",i)}}))}catch(o){g.devWarn("router-view subscribe failed",o)}}),y.useOnDisconnected(()=>{if(typeof s=="function")try{s()}catch(o){g.devWarn("router-view unsubscribe failed",o)}});const c=e.matchRoute(f.value.path);if(!c||!c.route)return y.html`<div>Not found</div>`;try{const i=await e.resolveRouteComponent(c.route);if(typeof i=="string")return{tag:i,props:{},children:[]};if(typeof i=="function"){const d=i();return(d instanceof Promise?d:Promise.resolve(d)).then(p=>typeof p=="string"?{tag:p,props:{},children:[]}:p)}return y.html`<div>Invalid route component</div>`}catch{return y.html`<div>Invalid route component</div>`}}),y.component("router-link",()=>{const e=y.useProps({to:"",tag:"a",replace:!1,exact:!1,activeClass:"active",exactActiveClass:"exact-active",ariaCurrentValue:"page",disabled:!1,external:!1,class:"",style:""}),f=W||r,s=b.ref(f.getCurrent());let c;y.useStyle(()=>"a,button{display:inline-block;}");const o=b.ref(e.class||""),i=b.ref(e.style||"");y.useOnConnected(m=>{try{f&&typeof f.subscribe=="function"&&(c=f.subscribe(h=>{try{s.value=h}catch(v){g.devWarn("router-link subscription update failed",v)}}))}catch(h){g.devWarn("router-link subscribe failed",h)}try{const h=m?._host;if(h instanceof HTMLElement){const v=h.getAttribute("class"),w=h.getAttribute("style");v&&(o.value=v),w&&(i.value=w),v!==null&&h.removeAttribute("class"),w!==null&&h.removeAttribute("style")}}catch(h){g.devWarn("router-link host migration failed",h)}}),y.useOnDisconnected(()=>{if(typeof c=="function")try{c()}catch(m){g.devWarn("router-link unsubscribe failed",m)}});const d=b.computed(()=>s.value.path===e.to),$=b.computed(()=>e.exact?d.value:s.value&&typeof s.value.path=="string"?s.value.path.startsWith(e.to):!1),p=b.computed(()=>{const h=(o&&o.value||e.class||"").split(/\s+/).filter(Boolean),v={};for(const w of h)v[w]=!0;return v}),R=b.computed(()=>({...p.value,[e.activeClass||"active"]:$.value,[e.exactActiveClass||"exact-active"]:d.value})),C=b.computed(()=>Object.keys(R.value).filter(m=>R.value[m]).join(" ")),k=b.computed(()=>e.tag==="button"),E=b.computed(()=>d.value?e.ariaCurrentValue:""),l=b.computed(()=>!!e.disabled),u=b.computed(()=>!!e.external&&(e.tag==="a"||!e.tag)),t=b.computed(()=>i&&i.value||e.style||""),a=m=>{if(e.disabled){m.preventDefault();return}e.external&&(e.tag==="a"||!e.tag)||(m.preventDefault(),e.replace?f.replace(e.to):f.push(e.to))};return y.html`
2
- ${T.match().when(k.value,y.html`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("./custom-elements-runtime.cjs.js"),b=require("./namespace-helpers-BsKQl3aH.cjs"),N=require("./custom-elements-runtime.store.cjs.js"),y=require("./logger-DiXdWaF-.cjs"),U=require("./custom-elements-runtime.directives.cjs.js"),j=n=>n?typeof URLSearchParams>"u"?{}:Object.fromEntries(new URLSearchParams(n)):{},T=new WeakMap;function F(n){return n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function q(n){if(!n)return"/";let r=n.replace(/\/+/g,"/");return r.startsWith("/")||(r="/"+r),r.length>1&&r.endsWith("/")&&(r=r.slice(0,-1)),r}function I(n){const r=n.path||"/",t=q(r),h=t==="/"?[]:t.split("/").filter(Boolean),o=[],s=[];for(let l=0;l<h.length;l++){const d=h[l];if(d==="*"){if(l!==h.length-1)return y.devWarn(`Route '${n.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};const p=`splat${o.length}`;o.push(p),s.push("__SPLAT__");continue}const R=d.match(/^:([A-Za-z0-9_-]+)(\*)?$/);if(R){const p=R[1],$=!!R[2];if($&&l!==h.length-1)return y.devWarn(`Route '${n.path}' contains a splat param ':${p}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`),{invalid:!0};o.push(p),s.push($?"__SPLAT__":"([^/]+)");continue}s.push(F(d))}let c;if(s.length===0)c="^/$";else if(s[s.length-1]==="__SPLAT__"){const d=s.slice(0,-1).join("/");d?c=`^/${d}(?:/(.*))?(?:/)?$`:c="^(?:/(.*))?(?:/)?$"}else c=`^/${s.join("/")}(?:/)?$`;try{return{regex:new RegExp(c),paramNames:o}}catch(l){return y.devWarn(`Failed to compile route regex for '${n.path}': ${String(l)}`),{invalid:!0}}}const x=(n,r)=>{const t=q(r);for(const h of n){let o=T.get(h);if(o||(o=I(h),T.set(h,o)),o.invalid)continue;const{regex:s,paramNames:c}=o,l=s.exec(t);if(l){const d={},R=p=>{try{return decodeURIComponent(p)}catch{return p}};for(let p=0;p<c.length;p++){const $=l[p+1]||"";d[c[p]]=$?R($):""}return{route:h,params:d}}}return{route:null,params:{}}};function W(n,r){for(const t of n)if(x([t],r).route!==null)return t;return null}const A={};async function B(n){if(n.component)return n.component;if(n.load){if(A[n.path])return A[n.path];try{const r=await n.load();return A[n.path]=r.default,r.default}catch{throw new Error(`Failed to load component for route: ${n.path}`)}}throw new Error(`No component or loader defined for route: ${n.path}`)}function D(n){const{routes:r,base:t="",initialUrl:h}=n;let o,s,c,l,d,R,p;const $=async(f,i)=>{const e=W(r,f.path);if(!e||!e.beforeEnter)return!0;try{const a=await e.beforeEnter(f,i);return typeof a=="string"?(await E(a,!0),!1):a!==!1}catch(a){return y.devError("beforeEnter error",a),!1}},O=async(f,i)=>{const e=W(r,f.path);if(!e||!e.onEnter)return!0;try{const a=await e.onEnter(f,i);return typeof a=="string"?(await E(a,!0),!1):a!==!1}catch(a){return y.devError("onEnter error",a),!1}},_=(f,i)=>{const e=W(r,f.path);if(!(!e||!e.afterEnter))try{e.afterEnter(f,i)}catch(a){y.devError("afterEnter error",a)}},E=async(f,i=!1)=>{try{const e=f.indexOf("#"),a=e>=0?f.slice(e+1):"",u={path:(e>=0?f.slice(0,e):f).replace(t,"")||"/",query:{},fragment:a},m=x(r,u.path);if(!m.route)throw new Error(`No route found for ${u.path}`);const w=c.getState(),S={path:u.path,params:m.params,query:u.query,fragment:u.fragment};if(!await $(S,w)||!await O(S,w))return;typeof window<"u"&&typeof document<"u"&&(i?window.history.replaceState({},"",t+f):window.history.pushState({},"",t+f)),c.setState(S),_(S,w)}catch(e){y.devError("Navigation error:",e)}};if(typeof window<"u"&&typeof document<"u"&&typeof h>"u"){o=()=>{const i=new URL(window.location.href),e=i.pathname.replace(t,"")||"/",a=j(i.search),v=i.hash&&i.hash.length?i.hash.slice(1):"";return{path:e,query:a,fragment:v}},s=o();const f=x(r,s.path);c=N.createStore({path:s.path,params:f.params,query:s.query,fragment:s.fragment}),l=async(i=!1)=>{const e=o();await E(e.path,i)},window.addEventListener("popstate",()=>l(!0)),d=i=>E(i,!1),R=i=>E(i,!0),p=()=>window.history.back()}else{o=()=>{const e=new URL(h||"/","http://localhost"),a=e.pathname.replace(t,"")||"/",v=j(e.search),u=e.hash&&e.hash.length?e.hash.slice(1):"";return{path:a,query:v,fragment:u}},s=o();const f=x(r,s.path);c=N.createStore({path:s.path,params:f.params,query:s.query,fragment:s.fragment}),l=async()=>{const e=o();await i(e.path)};const i=async e=>{try{const a=e.indexOf("#"),v=a>=0?e.slice(a+1):"",m={path:(a>=0?e.slice(0,a):e).replace(t,"")||"/",query:{},fragment:v},w=x(r,m.path);if(!w.route)throw new Error(`No route found for ${m.path}`);const S=c.getState(),k={path:m.path,params:w.params,query:m.query,fragment:m.fragment},P=W(r,k.path);if(P?.beforeEnter){const C=await P.beforeEnter(k,S);if(typeof C=="string"){await i(C);return}if(C===!1)return}if(P?.onEnter){const C=await P.onEnter(k,S);if(typeof C=="string"){await i(C);return}if(C===!1)return}c.setState(k),P?.afterEnter&&P.afterEnter(k,S)}catch(a){throw y.devError("SSR navigation error:",a),a}};d=async e=>i(e),R=async e=>i(e),p=()=>{}}return{store:c,push:d,replace:R,back:p,subscribe:c.subscribe,matchRoute:f=>x(r,f),getCurrent:()=>c.getState(),resolveRouteComponent:B}}function M(n,r){return x(n,r)}let L=null;function z(n){const r=D(n);return L=r,g.component("router-view",async()=>{const t=L||r;if(!t)return g.html`<div>Router not initialized.</div>`;const h=b.ref(t.getCurrent());let o;g.useOnConnected(()=>{try{t&&typeof t.subscribe=="function"&&(o=t.subscribe(c=>{try{h.value=c}catch(l){y.devWarn("router-view subscription update failed",l)}}))}catch(c){y.devWarn("router-view subscribe failed",c)}}),g.useOnDisconnected(()=>{if(typeof o=="function")try{o()}catch(c){y.devWarn("router-view unsubscribe failed",c)}});const s=t.matchRoute(h.value.path);if(!s||!s.route)return g.html`<div>Not found</div>`;try{const l=await t.resolveRouteComponent(s.route);if(typeof l=="string")return{tag:l,props:{},children:[]};if(typeof l=="function"){const d=l();return(d instanceof Promise?d:Promise.resolve(d)).then(p=>typeof p=="string"?{tag:p,props:{},children:[]}:p)}return g.html`<div>Invalid route component</div>`}catch{return g.html`<div>Invalid route component</div>`}}),g.component("router-link",()=>{const t=g.useProps({to:"",tag:"a",replace:!1,exact:!1,activeClass:"active",exactActiveClass:"exact-active",ariaCurrentValue:"page",disabled:!1,external:!1,class:"",style:""}),h=L||r,o=b.ref(h.getCurrent());let s;g.useStyle(()=>"a,button{display:inline-block;}");const c=b.ref(t.class||""),l=b.ref(t.style||"");g.useOnConnected(v=>{try{h&&typeof h.subscribe=="function"&&(s=h.subscribe(u=>{try{o.value=u}catch(m){y.devWarn("router-link subscription update failed",m)}}))}catch(u){y.devWarn("router-link subscribe failed",u)}try{const u=v?._host;if(u instanceof HTMLElement){const m=u.getAttribute("class"),w=u.getAttribute("style");m&&(c.value=m),w&&(l.value=w),m!==null&&u.removeAttribute("class"),w!==null&&u.removeAttribute("style")}}catch(u){y.devWarn("router-link host migration failed",u)}}),g.useOnDisconnected(()=>{if(typeof s=="function")try{s()}catch(v){y.devWarn("router-link unsubscribe failed",v)}});const d=b.computed(()=>{const u=(t.to||"").split("#")[0];try{return q(o.value.path)===q(u)}catch{return o.value.path===u}}),R=b.computed(()=>{const u=(t.to||"").split("#")[0];if(t.exact)return d.value;try{const m=q(o.value.path),w=q(u);return m.startsWith(w)}catch{return o.value&&typeof o.value.path=="string"&&o.value.path.startsWith(u)}}),p=b.computed(()=>{const u=(c&&c.value||t.class||"").split(/\s+/).filter(Boolean),m={};for(const w of u)m[w]=!0;return m}),$=b.computed(()=>({...p.value,[t.activeClass||"active"]:R.value,[t.exactActiveClass||"exact-active"]:d.value})),O=b.computed(()=>Object.keys($.value).filter(v=>$.value[v]).join(" ")),_=b.computed(()=>t.tag==="button"),E=b.computed(()=>d.value?t.ariaCurrentValue:""),f=b.computed(()=>!!t.disabled),i=b.computed(()=>!!t.external&&(t.tag==="a"||!t.tag)),e=b.computed(()=>l&&l.value||t.style||""),a=v=>{if(t.disabled){v.preventDefault();return}t.external&&(t.tag==="a"||!t.tag)||(v.preventDefault(),t.replace?h.replace(t.to):h.push(t.to))};return g.html`
2
+ ${U.match().when(_.value,g.html`
3
3
  <button
4
4
  part="button"
5
- class="${C.value}"
6
- style="${t.value||null}"
5
+ class="${O.value}"
6
+ style="${e.value||null}"
7
7
  aria-current="${E.value}"
8
- disabled="${l.value?"":null}"
9
- aria-disabled="${l.value?"true":null}"
10
- tabindex="${l.value?"-1":null}"
8
+ disabled="${f.value?"":null}"
9
+ aria-disabled="${f.value?"true":null}"
10
+ tabindex="${f.value?"-1":null}"
11
11
  @click="${a}"
12
12
  >
13
13
  <slot></slot>
14
14
  </button>
15
- `).otherwise(y.html`
15
+ `).otherwise(g.html`
16
16
  <a
17
17
  part="link"
18
- href="${e.to}"
19
- class="${C.value}"
20
- style="${t.value||null}"
18
+ href="${t.to}"
19
+ class="${O.value}"
20
+ style="${e.value||null}"
21
21
  aria-current="${E.value}"
22
- aria-disabled="${l.value?"true":null}"
23
- tabindex="${l.value?"-1":null}"
24
- target="${u.value?"_blank":null}"
25
- rel="${u.value?"noopener noreferrer":null}"
22
+ aria-disabled="${f.value?"true":null}"
23
+ tabindex="${f.value?"-1":null}"
24
+ target="${i.value?"_blank":null}"
25
+ rel="${i.value?"noopener noreferrer":null}"
26
26
  @click="${a}"
27
27
  ><slot></slot
28
28
  ></a>
29
29
  `).done()}
30
- `}),r}exports.initRouter=M;exports.matchRoute=S;exports.matchRouteSSR=U;exports.parseQuery=A;exports.resolveRouteComponent=j;exports.useRouter=N;
30
+ `}),r}exports.initRouter=z;exports.matchRoute=x;exports.matchRouteSSR=M;exports.normalizePathForRoute=q;exports.parseQuery=j;exports.resolveRouteComponent=B;exports.useRouter=D;
31
31
  //# sourceMappingURL=custom-elements-runtime.router.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-elements-runtime.router.cjs.js","sources":["../src/lib/router.ts"],"sourcesContent":["import { html } from './runtime/template-compiler';\nimport { component } from './runtime/component';\nimport {\n useProps,\n useOnConnected,\n useOnDisconnected,\n useStyle,\n} from './runtime/hooks';\nimport { ref, computed } from './runtime/reactive';\nimport { createStore, type Store } from './store';\nimport { devError, devWarn } from './runtime/logger';\nimport { match } from './directives';\n\nexport type RouteComponent =\n | { new (...args: unknown[]): unknown } // class components\n | ((...args: unknown[]) => unknown); // functional components\n\nexport interface RouteState {\n path: string;\n params: Record<string, string>;\n query: Record<string, string>;\n}\n\nexport type GuardResult = boolean | string | Promise<boolean | string>;\n\nexport interface Route {\n path: string;\n\n /**\n * Statically available component (already imported)\n */\n component?: string | (() => unknown);\n\n /**\n * Lazy loader that resolves to something renderable\n */\n load?: () => Promise<{\n default: string | HTMLElement | ((...args: unknown[]) => unknown);\n }>;\n\n /**\n * Runs before matching — return false to cancel,\n * or a string to redirect\n */\n beforeEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs right before navigation commits — can cancel or redirect\n */\n onEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs after navigation completes — cannot cancel\n */\n afterEnter?: (to: RouteState, from: RouteState) => void;\n}\n\nexport interface RouterLinkProps {\n to: string;\n tag: string;\n replace: boolean;\n exact: boolean;\n activeClass: string;\n exactActiveClass: string;\n ariaCurrentValue: string;\n disabled: boolean;\n external: boolean;\n class?: string;\n style?: string;\n}\n\nexport interface RouterLinkComputed {\n current: RouteState;\n isExactActive: boolean;\n isActive: boolean;\n className: string;\n ariaCurrent: string;\n isButton: boolean;\n disabledAttr: string;\n externalAttr: string;\n}\n\nexport interface RouterConfig {\n routes: Route[];\n base?: string;\n initialUrl?: string; // For SSR: explicitly pass the URL\n}\n\nexport const parseQuery = (search: string): Record<string, string> => {\n if (!search) return {};\n if (typeof URLSearchParams === 'undefined') return {};\n return Object.fromEntries(new URLSearchParams(search));\n};\n\n// Cache compiled route regexes to avoid rebuilding on every navigation.\ntype CompiledRoute =\n | { regex: RegExp; paramNames: string[] }\n | { invalid: true };\nconst compileCache: WeakMap<Route, CompiledRoute> = new WeakMap();\n\nfunction escapeSeg(seg: string) {\n return seg.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction normalizePathForRoute(p: string) {\n if (!p) return '/';\n // Collapse duplicate slashes, ensure leading slash, remove trailing slash\n let out = p.replace(/\\/+/g, '/');\n if (!out.startsWith('/')) out = '/' + out;\n if (out.length > 1 && out.endsWith('/')) out = out.slice(0, -1);\n return out;\n}\n\nfunction compileRoute(route: Route): CompiledRoute {\n const raw = route.path || '/';\n const routePath = normalizePathForRoute(raw);\n\n const segments =\n routePath === '/' ? [] : routePath.split('/').filter(Boolean);\n\n const paramNames: string[] = [];\n const regexParts: string[] = [];\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n\n // Anonymous wildcard\n if (seg === '*') {\n // splat must be terminal\n if (i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n const name = `splat${paramNames.length}`;\n paramNames.push(name);\n // mark splat token; pattern will be built specially so the\n // preceding slash can be optional (allow empty splat)\n regexParts.push('__SPLAT__');\n continue;\n }\n\n const paramMatch = seg.match(/^:([A-Za-z0-9_-]+)(\\*)?$/);\n if (paramMatch) {\n const name = paramMatch[1];\n const isSplat = !!paramMatch[2];\n // If splat, ensure terminal\n if (isSplat && i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a splat param ':${name}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n paramNames.push(name);\n regexParts.push(isSplat ? '__SPLAT__' : '([^/]+)');\n continue;\n }\n\n // Static\n regexParts.push(escapeSeg(seg));\n }\n\n let pattern: string;\n if (regexParts.length === 0) {\n pattern = '^/$';\n } else {\n const last = regexParts[regexParts.length - 1];\n if (last === '__SPLAT__') {\n const prefix = regexParts.slice(0, -1).join('/');\n if (!prefix) {\n // route is like '/:rest*' or '/*' -> allow '/' or '/x' etc.\n pattern = '^(?:/(.*))?(?:/)?$';\n } else {\n pattern = `^/${prefix}(?:/(.*))?(?:/)?$`;\n }\n } else {\n pattern = `^/${regexParts.join('/')}(?:/)?$`;\n }\n }\n try {\n const regex = new RegExp(pattern);\n return { regex, paramNames };\n } catch (e) {\n devWarn(`Failed to compile route regex for '${route.path}': ${String(e)}`);\n return { invalid: true };\n }\n}\n\nexport const matchRoute = (\n routes: Route[],\n path: string,\n): { route: Route | null; params: Record<string, string> } => {\n const incoming = normalizePathForRoute(path);\n\n for (const route of routes) {\n let compiled = compileCache.get(route);\n if (!compiled) {\n compiled = compileRoute(route);\n compileCache.set(route, compiled);\n }\n\n if ((compiled as { invalid?: true }).invalid) continue;\n\n const { regex, paramNames } = compiled as {\n regex: RegExp;\n paramNames: string[];\n };\n const m = regex.exec(incoming);\n if (m) {\n const params: Record<string, string> = {};\n const safeDecode = (v: string) => {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n };\n\n for (let i = 0; i < paramNames.length; i++) {\n const raw = m[i + 1] || '';\n params[paramNames[i]] = raw ? safeDecode(raw) : '';\n }\n\n return { route, params };\n }\n }\n\n return { route: null, params: {} };\n};\n\n/**\n * Find the first route that matches the given path.\n * Consolidates repeated inline checks like `routes.find(r => matchRoute([r], path).route !== null)`\n */\nfunction findMatchedRoute(routes: Route[], path: string): Route | null {\n for (const r of routes) {\n if (matchRoute([r], path).route !== null) return r;\n }\n return null;\n}\n\n// Async component loader cache\nconst componentCache: Record<\n string,\n string | HTMLElement | ((...args: unknown[]) => unknown)\n> = {};\n\n/**\n * Loads a route's component, supporting both static and async.\n * @param route Route object\n * @returns Promise resolving to the component\n */\nexport async function resolveRouteComponent(\n route: Route,\n): Promise<string | HTMLElement | ((...args: unknown[]) => unknown)> {\n if (route.component) return route.component;\n if (route.load) {\n if (componentCache[route.path]) return componentCache[route.path];\n try {\n const mod = await route.load();\n componentCache[route.path] = mod.default;\n return mod.default;\n } catch {\n throw new Error(`Failed to load component for route: ${route.path}`);\n }\n }\n throw new Error(`No component or loader defined for route: ${route.path}`);\n}\n\nexport function useRouter(config: RouterConfig) {\n const { routes, base = '', initialUrl } = config;\n\n let getLocation: () => { path: string; query: Record<string, string> };\n let initial: { path: string; query: Record<string, string> };\n let store: Store<RouteState>;\n let update: (replace?: boolean) => Promise<void>;\n let push: (path: string) => Promise<void>;\n let replaceFn: (path: string) => Promise<void>;\n let back: () => void;\n\n // Run matching route guards/hooks\n const runBeforeEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.beforeEnter) return true;\n try {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('beforeEnter error', err);\n return false;\n }\n };\n\n const runOnEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.onEnter) return true;\n try {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('onEnter error', err);\n return false;\n }\n };\n\n const runAfterEnter = (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.afterEnter) return;\n try {\n matched.afterEnter(to, from);\n } catch (err) {\n devError('afterEnter error', err);\n }\n };\n\n const navigate = async (path: string, replace = false) => {\n try {\n const loc = {\n path: path.replace(base, '') || '/',\n query: {},\n };\n const match = matchRoute(routes, loc.path);\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n };\n\n // beforeEnter guard\n const allowedBefore = await runBeforeEnter(to, from);\n if (!allowedBefore) return;\n\n // onEnter guard (right before commit)\n const allowedOn = await runOnEnter(to, from);\n if (!allowedOn) return;\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (replace) {\n window.history.replaceState({}, '', base + path);\n } else {\n window.history.pushState({}, '', base + path);\n }\n }\n\n store.setState(to);\n\n // afterEnter hook (post commit)\n runAfterEnter(to, from);\n } catch (err) {\n devError('Navigation error:', err);\n }\n };\n\n // If an explicit `initialUrl` is provided we treat this as SSR/static rendering\n // even if a `window` exists (useful for hydration tests). Browser mode only\n // applies when `initialUrl` is undefined.\n if (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof initialUrl === 'undefined'\n ) {\n // Browser mode\n getLocation = () => {\n const url = new URL(window.location.href);\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n return { path, query };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n });\n\n update = async (replace = false) => {\n const loc = getLocation();\n await navigate(loc.path, replace);\n };\n\n window.addEventListener('popstate', () => update(true));\n\n push = (path: string) => navigate(path, false);\n replaceFn = (path: string) => navigate(path, true);\n back = () => window.history.back();\n } else {\n // SSR mode\n getLocation = () => {\n const url = new URL(initialUrl || '/', 'http://localhost');\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n return { path, query };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n });\n\n update = async () => {\n const loc = getLocation();\n await navigateSSR(loc.path);\n };\n\n // SSR navigation contract:\n // - `push` / `replace` call into `navigateSSR` and return a Promise.\n // - On the server we intentionally surface navigation failures so\n // server-side logic (or tests) can react: missing routes or thrown\n // errors from `beforeEnter`/`onEnter` will cause the Promise to\n // reject. This lets the server render 404s or abort builds.\n // - For valid routes the server-side navigation resolves and updates\n // the internal store state so rendered output matches the target\n // path. The `back()` operation is client-only and is a synchronous\n // no-op in SSR mode.\n const navigateSSR = async (path: string) => {\n try {\n const loc = {\n path: path.replace(base, '') || '/',\n query: {},\n };\n const match = matchRoute(routes, loc.path);\n // In SSR mode we intentionally surface navigation errors (missing\n // route) to the caller so server-side logic may handle them. If no\n // route matches, throw and let the caller observe the rejection.\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n };\n\n // beforeEnter guard\n const matched = findMatchedRoute(routes, to.path);\n if (matched?.beforeEnter) {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n // onEnter guard\n if (matched?.onEnter) {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n store.setState(to);\n\n // afterEnter hook\n if (matched?.afterEnter) {\n matched.afterEnter(to, from);\n }\n } catch (err) {\n // Surface SSR navigation errors so callers (and tests) can observe\n // failures during server-side resolution.\n devError('SSR navigation error:', err);\n throw err;\n }\n };\n\n push = async (path: string) => navigateSSR(path);\n replaceFn = async (path: string) => navigateSSR(path);\n back = () => {};\n }\n\n return {\n store,\n push,\n replace: replaceFn,\n back,\n subscribe: store.subscribe,\n matchRoute: (path: string) => matchRoute(routes, path),\n getCurrent: (): RouteState => store.getState(),\n resolveRouteComponent,\n };\n}\n\n// SSR/static site support: match route for a given path\nexport function matchRouteSSR(routes: Route[], path: string) {\n return matchRoute(routes, path);\n}\n\n// Module-level reference to the latest initialized router. Tests and\n// components may rely on re-initializing the router during their setup,\n// so exposing this lets components pick up the most recent instance.\nlet activeRouter: ReturnType<typeof useRouter> | null = null;\n\n/**\n * Singleton router instance for global access.\n *\n * Define here to prevent circular dependency\n * issue with component.\n */\n\nexport function initRouter(config: RouterConfig) {\n const router = useRouter(config);\n // Expose the most recently initialized router to components defined\n // earlier in the process (tests may call initRouter multiple times).\n // Components reference `activeRouter` so re-calling initRouter updates\n // the router instance they use.\n activeRouter = router;\n\n component('router-view', async () => {\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current route so the component re-renders when router updates\n if (!r) return html`<div>Router not initialized.</div>`;\n\n const current = ref(r.getCurrent());\n\n // We'll capture the unsubscribe function when the component connects\n // and register a disconnect cleanup during render-time (useOnDisconnected\n // must be called during the component render/execution).\n let unsubRouterView: (() => void) | undefined;\n\n useOnConnected(() => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterView = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-view subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-view subscribe failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterView === 'function') {\n try {\n unsubRouterView();\n } catch (e) {\n devWarn('router-view unsubscribe failed', e);\n }\n }\n });\n\n const match = r.matchRoute(current.value.path);\n if (!match || !match.route) return html`<div>Not found</div>`;\n\n // Resolve the component (supports cached async loaders)\n try {\n const compRaw = await r.resolveRouteComponent(match.route);\n const comp = compRaw as\n | string\n | HTMLElement\n | ((...args: unknown[]) => unknown)\n | undefined;\n // String tag (custom element) -> render as VNode\n if (typeof comp === 'string') {\n return { tag: comp, props: {}, children: [] };\n }\n\n // Function component (sync or async) -> call and return its VNode(s)\n if (typeof comp === 'function') {\n const out = comp();\n const resolved = out instanceof Promise ? out : Promise.resolve(out);\n return resolved.then((resolvedComp) => {\n if (typeof resolvedComp === 'string')\n return { tag: resolvedComp, props: {}, children: [] };\n return resolvedComp;\n });\n }\n\n return html`<div>Invalid route component</div>`;\n } catch {\n return html`<div>Invalid route component</div>`;\n }\n });\n\n component('router-link', () => {\n // Declare props via useProps so observedAttributes are correct\n const props = useProps<Partial<RouterLinkProps>>({\n to: '',\n tag: 'a',\n replace: false,\n exact: false,\n activeClass: 'active',\n exactActiveClass: 'exact-active',\n ariaCurrentValue: 'page',\n disabled: false,\n external: false,\n // allow host `class` and `style` attributes to be read via useProps\n class: '',\n style: '',\n });\n\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current state so link updates when route changes\n const current = ref(r.getCurrent());\n // Capture unsubscribe for link subscriptions and register disconnect\n // cleanup during render time.\n let unsubRouterLink: (() => void) | undefined;\n\n // Keep a minimal internal host-scoped style for element display.\n // Host `style` will be applied to the inner anchor/button element.\n useStyle(() => `a,button{display:inline-block;}`);\n\n // We capture host attributes at connection time and migrate them to\n // internal refs so we can remove them from the host. This prevents\n // global/author CSS targeting the host from styling the host element\n // itself while still allowing authors to use `class`/`style` on the\n // router-link to style the inner anchor/button.\n const hostClassRef = ref((props.class as string) || '');\n const hostStyleRef = ref((props.style as string) || '');\n\n useOnConnected((ctx?: unknown) => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterLink = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-link subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-link subscribe failed', e);\n }\n\n // Migrate host `class`/`style` into internal refs and remove them\n // from the host so only the inner element is styled.\n try {\n const host = (ctx as { _host?: HTMLElement } | undefined)?._host;\n if (host instanceof HTMLElement) {\n const hc = host.getAttribute('class');\n const hs = host.getAttribute('style');\n if (hc) hostClassRef.value = hc;\n if (hs) hostStyleRef.value = hs;\n // Remove attributes from host to avoid styling the host\n if (hc !== null) host.removeAttribute('class');\n if (hs !== null) host.removeAttribute('style');\n }\n } catch (e) {\n devWarn('router-link host migration failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterLink === 'function') {\n try {\n unsubRouterLink();\n } catch (e) {\n devWarn('router-link unsubscribe failed', e);\n }\n }\n });\n\n const isExactActive = computed(\n () => current.value.path === (props.to as string),\n );\n const isActive = computed(() =>\n props.exact\n ? isExactActive.value\n : current.value && typeof current.value.path === 'string'\n ? current.value.path.startsWith(props.to as string)\n : false,\n );\n\n // Build user classes reactively from the host `class` attribute prop.\n // We intentionally apply classes to the inner element so the consumer\n // can style the link via `class=\"...\"`.\n const userClasses = computed(() => {\n const rawHost =\n (hostClassRef && hostClassRef.value) || (props.class as string) || '';\n const list = rawHost.split(/\\s+/).filter(Boolean);\n const map: Record<string, boolean> = {};\n for (const c of list) map[c] = true;\n return map;\n });\n\n const classObject = computed(() => ({\n ...userClasses.value,\n [(props.activeClass as string) || 'active']: isActive.value,\n [(props.exactActiveClass as string) || 'exact-active']:\n isExactActive.value,\n }));\n\n // Compute a final class string (template accepts object or string; we\n // convert to string to safely include host classes and conditionals).\n const classString = computed(() =>\n Object.keys(classObject.value)\n .filter((k) => classObject.value[k])\n .join(' '),\n );\n\n const isButton = computed(() => (props.tag as string) === 'button');\n // Instead of pre-building attribute fragments as strings (which can\n // accidentally inject invalid attribute names into the template and\n // cause DOMExceptions), compute simple booleans/values and apply\n // attributes explicitly in the template below.\n const ariaCurrentValue = computed(() =>\n isExactActive.value ? (props.ariaCurrentValue as string) : '',\n );\n const isDisabled = computed(() => !!props.disabled);\n const isExternal = computed(\n () =>\n !!props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string)),\n );\n\n // Inline style from host `style` attribute.\n const inlineStyle = computed(\n () =>\n (hostStyleRef && hostStyleRef.value) || (props.style as string) || '',\n );\n\n const navigate = (e: MouseEvent) => {\n if (props.disabled) {\n e.preventDefault();\n return;\n }\n if (\n props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string))\n ) {\n return;\n }\n e.preventDefault();\n if (props.replace) {\n r.replace(props.to as string);\n } else {\n r.push(props.to as string);\n }\n };\n\n return html`\n ${match()\n .when(\n isButton.value,\n html`\n <button\n part=\"button\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n disabled=\"${isDisabled.value ? '' : null}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n @click=\"${navigate}\"\n >\n <slot></slot>\n </button>\n `,\n )\n .otherwise(html`\n <a\n part=\"link\"\n href=\"${props.to}\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n target=\"${isExternal.value ? '_blank' : null}\"\n rel=\"${isExternal.value ? 'noopener noreferrer' : null}\"\n @click=\"${navigate}\"\n ><slot></slot\n ></a>\n `)\n .done()}\n `;\n });\n\n return router;\n}\n"],"names":["parseQuery","search","compileCache","escapeSeg","seg","normalizePathForRoute","p","out","compileRoute","route","raw","routePath","segments","paramNames","regexParts","devWarn","name","paramMatch","isSplat","pattern","prefix","e","matchRoute","routes","path","incoming","compiled","regex","m","params","safeDecode","v","i","findMatchedRoute","r","componentCache","resolveRouteComponent","mod","useRouter","config","base","initialUrl","getLocation","initial","store","update","push","replaceFn","back","runBeforeEnter","to","from","matched","result","navigate","err","devError","runOnEnter","runAfterEnter","replace","loc","match","url","query","createStore","navigateSSR","matchRouteSSR","activeRouter","initRouter","router","component","html","current","ref","unsubRouterView","useOnConnected","s","useOnDisconnected","comp","resolvedComp","props","useProps","unsubRouterLink","useStyle","hostClassRef","hostStyleRef","ctx","host","hc","hs","isExactActive","computed","isActive","userClasses","list","map","c","classObject","classString","k","isButton","ariaCurrentValue","isDisabled","isExternal","inlineStyle"],"mappings":"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"}
1
+ {"version":3,"file":"custom-elements-runtime.router.cjs.js","sources":["../src/lib/router.ts"],"sourcesContent":["import { html } from './runtime/template-compiler';\nimport { component } from './runtime/component';\nimport {\n useProps,\n useOnConnected,\n useOnDisconnected,\n useStyle,\n} from './runtime/hooks';\nimport { ref, computed } from './runtime/reactive';\nimport { createStore, type Store } from './store';\nimport { devError, devWarn } from './runtime/logger';\nimport { match } from './directives';\n\nexport type RouteComponent =\n | { new (...args: unknown[]): unknown } // class components\n | ((...args: unknown[]) => unknown); // functional components\n\nexport interface RouteState {\n path: string;\n params: Record<string, string>;\n query: Record<string, string>;\n // Optional fragment (hash) portion of the URL, without the leading '#'\n fragment?: string;\n}\n\nexport type GuardResult = boolean | string | Promise<boolean | string>;\n\nexport interface Route {\n path: string;\n\n /**\n * Statically available component (already imported)\n */\n component?: string | (() => unknown);\n\n /**\n * Lazy loader that resolves to something renderable\n */\n load?: () => Promise<{\n default: string | HTMLElement | ((...args: unknown[]) => unknown);\n }>;\n\n /**\n * Runs before matching — return false to cancel,\n * or a string to redirect\n */\n beforeEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs right before navigation commits — can cancel or redirect\n */\n onEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs after navigation completes — cannot cancel\n */\n afterEnter?: (to: RouteState, from: RouteState) => void;\n}\n\nexport interface RouterLinkProps {\n to: string;\n tag: string;\n replace: boolean;\n exact: boolean;\n activeClass: string;\n exactActiveClass: string;\n ariaCurrentValue: string;\n disabled: boolean;\n external: boolean;\n class?: string;\n style?: string;\n}\n\nexport interface RouterLinkComputed {\n current: RouteState;\n isExactActive: boolean;\n isActive: boolean;\n className: string;\n ariaCurrent: string;\n isButton: boolean;\n disabledAttr: string;\n externalAttr: string;\n}\n\nexport interface RouterConfig {\n routes: Route[];\n base?: string;\n initialUrl?: string; // For SSR: explicitly pass the URL\n}\n\nexport const parseQuery = (search: string): Record<string, string> => {\n if (!search) return {};\n if (typeof URLSearchParams === 'undefined') return {};\n return Object.fromEntries(new URLSearchParams(search));\n};\n\n// Cache compiled route regexes to avoid rebuilding on every navigation.\ntype CompiledRoute =\n | { regex: RegExp; paramNames: string[] }\n | { invalid: true };\nconst compileCache: WeakMap<Route, CompiledRoute> = new WeakMap();\n\nfunction escapeSeg(seg: string) {\n return seg.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function normalizePathForRoute(p: string) {\n if (!p) return '/';\n // Collapse duplicate slashes, ensure leading slash, remove trailing slash\n let out = p.replace(/\\/+/g, '/');\n if (!out.startsWith('/')) out = '/' + out;\n if (out.length > 1 && out.endsWith('/')) out = out.slice(0, -1);\n return out;\n}\n\nfunction compileRoute(route: Route): CompiledRoute {\n const raw = route.path || '/';\n const routePath = normalizePathForRoute(raw);\n\n const segments =\n routePath === '/' ? [] : routePath.split('/').filter(Boolean);\n\n const paramNames: string[] = [];\n const regexParts: string[] = [];\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n\n // Anonymous wildcard\n if (seg === '*') {\n // splat must be terminal\n if (i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n const name = `splat${paramNames.length}`;\n paramNames.push(name);\n // mark splat token; pattern will be built specially so the\n // preceding slash can be optional (allow empty splat)\n regexParts.push('__SPLAT__');\n continue;\n }\n\n const paramMatch = seg.match(/^:([A-Za-z0-9_-]+)(\\*)?$/);\n if (paramMatch) {\n const name = paramMatch[1];\n const isSplat = !!paramMatch[2];\n // If splat, ensure terminal\n if (isSplat && i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a splat param ':${name}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n paramNames.push(name);\n regexParts.push(isSplat ? '__SPLAT__' : '([^/]+)');\n continue;\n }\n\n // Static\n regexParts.push(escapeSeg(seg));\n }\n\n let pattern: string;\n if (regexParts.length === 0) {\n pattern = '^/$';\n } else {\n const last = regexParts[regexParts.length - 1];\n if (last === '__SPLAT__') {\n const prefix = regexParts.slice(0, -1).join('/');\n if (!prefix) {\n // route is like '/:rest*' or '/*' -> allow '/' or '/x' etc.\n pattern = '^(?:/(.*))?(?:/)?$';\n } else {\n pattern = `^/${prefix}(?:/(.*))?(?:/)?$`;\n }\n } else {\n pattern = `^/${regexParts.join('/')}(?:/)?$`;\n }\n }\n try {\n const regex = new RegExp(pattern);\n return { regex, paramNames };\n } catch (e) {\n devWarn(`Failed to compile route regex for '${route.path}': ${String(e)}`);\n return { invalid: true };\n }\n}\n\nexport const matchRoute = (\n routes: Route[],\n path: string,\n): { route: Route | null; params: Record<string, string> } => {\n const incoming = normalizePathForRoute(path);\n\n for (const route of routes) {\n let compiled = compileCache.get(route);\n if (!compiled) {\n compiled = compileRoute(route);\n compileCache.set(route, compiled);\n }\n\n if ((compiled as { invalid?: true }).invalid) continue;\n\n const { regex, paramNames } = compiled as {\n regex: RegExp;\n paramNames: string[];\n };\n const m = regex.exec(incoming);\n if (m) {\n const params: Record<string, string> = {};\n const safeDecode = (v: string) => {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n };\n\n for (let i = 0; i < paramNames.length; i++) {\n const raw = m[i + 1] || '';\n params[paramNames[i]] = raw ? safeDecode(raw) : '';\n }\n\n return { route, params };\n }\n }\n\n return { route: null, params: {} };\n};\n\n/**\n * Find the first route that matches the given path.\n * Consolidates repeated inline checks like `routes.find(r => matchRoute([r], path).route !== null)`\n */\nfunction findMatchedRoute(routes: Route[], path: string): Route | null {\n for (const r of routes) {\n if (matchRoute([r], path).route !== null) return r;\n }\n return null;\n}\n\n// Async component loader cache\nconst componentCache: Record<\n string,\n string | HTMLElement | ((...args: unknown[]) => unknown)\n> = {};\n\n/**\n * Loads a route's component, supporting both static and async.\n * @param route Route object\n * @returns Promise resolving to the component\n */\nexport async function resolveRouteComponent(\n route: Route,\n): Promise<string | HTMLElement | ((...args: unknown[]) => unknown)> {\n if (route.component) return route.component;\n if (route.load) {\n if (componentCache[route.path]) return componentCache[route.path];\n try {\n const mod = await route.load();\n componentCache[route.path] = mod.default;\n return mod.default;\n } catch {\n throw new Error(`Failed to load component for route: ${route.path}`);\n }\n }\n throw new Error(`No component or loader defined for route: ${route.path}`);\n}\n\nexport function useRouter(config: RouterConfig) {\n const { routes, base = '', initialUrl } = config;\n\n let getLocation: () => { path: string; query: Record<string, string> };\n let initial: { path: string; query: Record<string, string> };\n let store: Store<RouteState>;\n let update: (replace?: boolean) => Promise<void>;\n let push: (path: string) => Promise<void>;\n let replaceFn: (path: string) => Promise<void>;\n let back: () => void;\n\n // Run matching route guards/hooks\n const runBeforeEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.beforeEnter) return true;\n try {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('beforeEnter error', err);\n return false;\n }\n };\n\n const runOnEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.onEnter) return true;\n try {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('onEnter error', err);\n return false;\n }\n };\n\n const runAfterEnter = (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.afterEnter) return;\n try {\n matched.afterEnter(to, from);\n } catch (err) {\n devError('afterEnter error', err);\n }\n };\n\n const navigate = async (path: string, replace = false) => {\n try {\n // Separate fragment (hash) from path so matching ignores it while\n // the fragment is preserved on the RouteState.\n const hashIndex = path.indexOf('#');\n const fragment = hashIndex >= 0 ? path.slice(hashIndex + 1) : '';\n const rawPath = hashIndex >= 0 ? path.slice(0, hashIndex) : path;\n const loc = {\n path: rawPath.replace(base, '') || '/',\n query: {},\n fragment,\n };\n const match = matchRoute(routes, loc.path);\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n fragment: (loc as { fragment?: string }).fragment,\n };\n\n // beforeEnter guard\n const allowedBefore = await runBeforeEnter(to, from);\n if (!allowedBefore) return;\n\n // onEnter guard (right before commit)\n const allowedOn = await runOnEnter(to, from);\n if (!allowedOn) return;\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (replace) {\n window.history.replaceState({}, '', base + path);\n } else {\n window.history.pushState({}, '', base + path);\n }\n }\n\n store.setState(to);\n\n // afterEnter hook (post commit)\n runAfterEnter(to, from);\n } catch (err) {\n devError('Navigation error:', err);\n }\n };\n\n // If an explicit `initialUrl` is provided we treat this as SSR/static rendering\n // even if a `window` exists (useful for hydration tests). Browser mode only\n // applies when `initialUrl` is undefined.\n if (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof initialUrl === 'undefined'\n ) {\n // Browser mode\n getLocation = () => {\n const url = new URL(window.location.href);\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n const fragment = url.hash && url.hash.length ? url.hash.slice(1) : '';\n return { path, query, fragment };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n fragment: (initial as { fragment?: string }).fragment,\n });\n\n update = async (replace = false) => {\n const loc = getLocation();\n await navigate(loc.path, replace);\n };\n\n window.addEventListener('popstate', () => update(true));\n\n push = (path: string) => navigate(path, false);\n replaceFn = (path: string) => navigate(path, true);\n back = () => window.history.back();\n } else {\n // SSR mode\n getLocation = () => {\n const url = new URL(initialUrl || '/', 'http://localhost');\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n const fragment = url.hash && url.hash.length ? url.hash.slice(1) : '';\n return { path, query, fragment };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n fragment: (initial as { fragment?: string }).fragment,\n });\n\n update = async () => {\n const loc = getLocation();\n await navigateSSR(loc.path);\n };\n\n // SSR navigation contract:\n // - `push` / `replace` call into `navigateSSR` and return a Promise.\n // - On the server we intentionally surface navigation failures so\n // server-side logic (or tests) can react: missing routes or thrown\n // errors from `beforeEnter`/`onEnter` will cause the Promise to\n // reject. This lets the server render 404s or abort builds.\n // - For valid routes the server-side navigation resolves and updates\n // the internal store state so rendered output matches the target\n // path. The `back()` operation is client-only and is a synchronous\n // no-op in SSR mode.\n const navigateSSR = async (path: string) => {\n try {\n const hashIndex = path.indexOf('#');\n const fragment = hashIndex >= 0 ? path.slice(hashIndex + 1) : '';\n const rawPath = hashIndex >= 0 ? path.slice(0, hashIndex) : path;\n const loc = {\n path: rawPath.replace(base, '') || '/',\n query: {},\n fragment,\n };\n const match = matchRoute(routes, loc.path);\n // In SSR mode we intentionally surface navigation errors (missing\n // route) to the caller so server-side logic may handle them. If no\n // route matches, throw and let the caller observe the rejection.\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n fragment: (loc as { fragment?: string }).fragment,\n };\n\n // beforeEnter guard\n const matched = findMatchedRoute(routes, to.path);\n if (matched?.beforeEnter) {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n // onEnter guard\n if (matched?.onEnter) {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n store.setState(to);\n\n // afterEnter hook\n if (matched?.afterEnter) {\n matched.afterEnter(to, from);\n }\n } catch (err) {\n // Surface SSR navigation errors so callers (and tests) can observe\n // failures during server-side resolution.\n devError('SSR navigation error:', err);\n throw err;\n }\n };\n\n push = async (path: string) => navigateSSR(path);\n replaceFn = async (path: string) => navigateSSR(path);\n back = () => {};\n }\n\n return {\n store,\n push,\n replace: replaceFn,\n back,\n subscribe: store.subscribe,\n matchRoute: (path: string) => matchRoute(routes, path),\n getCurrent: (): RouteState => store.getState(),\n resolveRouteComponent,\n };\n}\n\n// SSR/static site support: match route for a given path\nexport function matchRouteSSR(routes: Route[], path: string) {\n return matchRoute(routes, path);\n}\n\n// Module-level reference to the latest initialized router. Tests and\n// components may rely on re-initializing the router during their setup,\n// so exposing this lets components pick up the most recent instance.\nlet activeRouter: ReturnType<typeof useRouter> | null = null;\n\n/**\n * Singleton router instance for global access.\n *\n * Define here to prevent circular dependency\n * issue with component.\n */\n\nexport function initRouter(config: RouterConfig) {\n const router = useRouter(config);\n // Expose the most recently initialized router to components defined\n // earlier in the process (tests may call initRouter multiple times).\n // Components reference `activeRouter` so re-calling initRouter updates\n // the router instance they use.\n activeRouter = router;\n\n component('router-view', async () => {\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current route so the component re-renders when router updates\n if (!r) return html`<div>Router not initialized.</div>`;\n\n const current = ref(r.getCurrent());\n\n // We'll capture the unsubscribe function when the component connects\n // and register a disconnect cleanup during render-time (useOnDisconnected\n // must be called during the component render/execution).\n let unsubRouterView: (() => void) | undefined;\n\n useOnConnected(() => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterView = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-view subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-view subscribe failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterView === 'function') {\n try {\n unsubRouterView();\n } catch (e) {\n devWarn('router-view unsubscribe failed', e);\n }\n }\n });\n\n const match = r.matchRoute(current.value.path);\n if (!match || !match.route) return html`<div>Not found</div>`;\n\n // Resolve the component (supports cached async loaders)\n try {\n const compRaw = await r.resolveRouteComponent(match.route);\n const comp = compRaw as\n | string\n | HTMLElement\n | ((...args: unknown[]) => unknown)\n | undefined;\n // String tag (custom element) -> render as VNode\n if (typeof comp === 'string') {\n return { tag: comp, props: {}, children: [] };\n }\n\n // Function component (sync or async) -> call and return its VNode(s)\n if (typeof comp === 'function') {\n const out = comp();\n const resolved = out instanceof Promise ? out : Promise.resolve(out);\n return resolved.then((resolvedComp) => {\n if (typeof resolvedComp === 'string')\n return { tag: resolvedComp, props: {}, children: [] };\n return resolvedComp;\n });\n }\n\n return html`<div>Invalid route component</div>`;\n } catch {\n return html`<div>Invalid route component</div>`;\n }\n });\n\n component('router-link', () => {\n // Declare props via useProps so observedAttributes are correct\n const props = useProps<Partial<RouterLinkProps>>({\n to: '',\n tag: 'a',\n replace: false,\n exact: false,\n activeClass: 'active',\n exactActiveClass: 'exact-active',\n ariaCurrentValue: 'page',\n disabled: false,\n external: false,\n // allow host `class` and `style` attributes to be read via useProps\n class: '',\n style: '',\n });\n\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current state so link updates when route changes\n const current = ref(r.getCurrent());\n // Capture unsubscribe for link subscriptions and register disconnect\n // cleanup during render time.\n let unsubRouterLink: (() => void) | undefined;\n\n // Keep a minimal internal host-scoped style for element display.\n // Host `style` will be applied to the inner anchor/button element.\n useStyle(() => `a,button{display:inline-block;}`);\n\n // We capture host attributes at connection time and migrate them to\n // internal refs so we can remove them from the host. This prevents\n // global/author CSS targeting the host from styling the host element\n // itself while still allowing authors to use `class`/`style` on the\n // router-link to style the inner anchor/button.\n const hostClassRef = ref((props.class as string) || '');\n const hostStyleRef = ref((props.style as string) || '');\n\n useOnConnected((ctx?: unknown) => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterLink = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-link subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-link subscribe failed', e);\n }\n\n // Migrate host `class`/`style` into internal refs and remove them\n // from the host so only the inner element is styled.\n try {\n const host = (ctx as { _host?: HTMLElement } | undefined)?._host;\n if (host instanceof HTMLElement) {\n const hc = host.getAttribute('class');\n const hs = host.getAttribute('style');\n if (hc) hostClassRef.value = hc;\n if (hs) hostStyleRef.value = hs;\n // Remove attributes from host to avoid styling the host\n if (hc !== null) host.removeAttribute('class');\n if (hs !== null) host.removeAttribute('style');\n }\n } catch (e) {\n devWarn('router-link host migration failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterLink === 'function') {\n try {\n unsubRouterLink();\n } catch (e) {\n devWarn('router-link unsubscribe failed', e);\n }\n }\n });\n\n const isExactActive = computed(() => {\n const targetRaw = (props.to as string) || '';\n // strip fragment from target when comparing\n const targetPathOnly = targetRaw.split('#')[0];\n try {\n return (\n normalizePathForRoute(current.value.path) ===\n normalizePathForRoute(targetPathOnly)\n );\n } catch {\n return current.value.path === targetPathOnly;\n }\n });\n\n const isActive = computed(() => {\n const targetRaw = (props.to as string) || '';\n const targetPathOnly = targetRaw.split('#')[0];\n if (props.exact) return isExactActive.value;\n try {\n const cur = normalizePathForRoute(current.value.path);\n const tgt = normalizePathForRoute(targetPathOnly);\n return cur.startsWith(tgt);\n } catch {\n return (\n current.value &&\n typeof current.value.path === 'string' &&\n current.value.path.startsWith(targetPathOnly)\n );\n }\n });\n\n // Build user classes reactively from the host `class` attribute prop.\n // We intentionally apply classes to the inner element so the consumer\n // can style the link via `class=\"...\"`.\n const userClasses = computed(() => {\n const rawHost =\n (hostClassRef && hostClassRef.value) || (props.class as string) || '';\n const list = rawHost.split(/\\s+/).filter(Boolean);\n const map: Record<string, boolean> = {};\n for (const c of list) map[c] = true;\n return map;\n });\n\n const classObject = computed(() => ({\n ...userClasses.value,\n [(props.activeClass as string) || 'active']: isActive.value,\n [(props.exactActiveClass as string) || 'exact-active']:\n isExactActive.value,\n }));\n\n // Compute a final class string (template accepts object or string; we\n // convert to string to safely include host classes and conditionals).\n const classString = computed(() =>\n Object.keys(classObject.value)\n .filter((k) => classObject.value[k])\n .join(' '),\n );\n\n const isButton = computed(() => (props.tag as string) === 'button');\n // Instead of pre-building attribute fragments as strings (which can\n // accidentally inject invalid attribute names into the template and\n // cause DOMExceptions), compute simple booleans/values and apply\n // attributes explicitly in the template below.\n const ariaCurrentValue = computed(() =>\n isExactActive.value ? (props.ariaCurrentValue as string) : '',\n );\n const isDisabled = computed(() => !!props.disabled);\n const isExternal = computed(\n () =>\n !!props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string)),\n );\n\n // Inline style from host `style` attribute.\n const inlineStyle = computed(\n () =>\n (hostStyleRef && hostStyleRef.value) || (props.style as string) || '',\n );\n\n const navigate = (e: MouseEvent) => {\n if (props.disabled) {\n e.preventDefault();\n return;\n }\n if (\n props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string))\n ) {\n return;\n }\n e.preventDefault();\n if (props.replace) {\n r.replace(props.to as string);\n } else {\n r.push(props.to as string);\n }\n };\n\n return html`\n ${match()\n .when(\n isButton.value,\n html`\n <button\n part=\"button\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n disabled=\"${isDisabled.value ? '' : null}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n @click=\"${navigate}\"\n >\n <slot></slot>\n </button>\n `,\n )\n .otherwise(html`\n <a\n part=\"link\"\n href=\"${props.to}\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n target=\"${isExternal.value ? '_blank' : null}\"\n rel=\"${isExternal.value ? 'noopener noreferrer' : null}\"\n @click=\"${navigate}\"\n ><slot></slot\n ></a>\n `)\n .done()}\n `;\n });\n\n return router;\n}\n"],"names":["parseQuery","search","compileCache","escapeSeg","seg","normalizePathForRoute","p","out","compileRoute","route","raw","routePath","segments","paramNames","regexParts","i","devWarn","name","paramMatch","isSplat","pattern","prefix","e","matchRoute","routes","path","incoming","compiled","regex","m","params","safeDecode","v","findMatchedRoute","r","componentCache","resolveRouteComponent","mod","useRouter","config","base","initialUrl","getLocation","initial","store","update","push","replaceFn","back","runBeforeEnter","to","from","matched","result","navigate","err","devError","runOnEnter","runAfterEnter","replace","hashIndex","fragment","loc","match","url","query","createStore","navigateSSR","matchRouteSSR","activeRouter","initRouter","router","component","html","current","ref","unsubRouterView","useOnConnected","s","useOnDisconnected","comp","resolvedComp","props","useProps","unsubRouterLink","useStyle","hostClassRef","hostStyleRef","ctx","host","hc","hs","isExactActive","computed","targetPathOnly","isActive","cur","tgt","userClasses","list","map","c","classObject","classString","k","isButton","ariaCurrentValue","isDisabled","isExternal","inlineStyle"],"mappings":"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"}
@@ -1,267 +1,273 @@
1
- import { component as O, html as S, useOnConnected as N, useOnDisconnected as j, useProps as W, useStyle as F } from "./custom-elements-runtime.es.js";
2
- import { r as _, c as g } from "./namespace-helpers-Dw1mgQab.js";
3
- import { createStore as B } from "./custom-elements-runtime.store.es.js";
4
- import { d as C, a as $ } from "./logger-BuUYv7C_.js";
5
- import { match as M } from "./custom-elements-runtime.directives.es.js";
6
- const T = (n) => n ? typeof URLSearchParams > "u" ? {} : Object.fromEntries(new URLSearchParams(n)) : {}, U = /* @__PURE__ */ new WeakMap();
7
- function V(n) {
1
+ import { component as T, html as P, useOnConnected as U, useOnDisconnected as W, useProps as M, useStyle as V } from "./custom-elements-runtime.es.js";
2
+ import { r as O, c as b } from "./namespace-helpers-Dw1mgQab.js";
3
+ import { createStore as D } from "./custom-elements-runtime.store.es.js";
4
+ import { d as A, a as $ } from "./logger-BuUYv7C_.js";
5
+ import { match as z } from "./custom-elements-runtime.directives.es.js";
6
+ const I = (n) => n ? typeof URLSearchParams > "u" ? {} : Object.fromEntries(new URLSearchParams(n)) : {}, F = /* @__PURE__ */ new WeakMap();
7
+ function H(n) {
8
8
  return n.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9
9
  }
10
- function D(n) {
10
+ function _(n) {
11
11
  if (!n) return "/";
12
12
  let r = n.replace(/\/+/g, "/");
13
13
  return r.startsWith("/") || (r = "/" + r), r.length > 1 && r.endsWith("/") && (r = r.slice(0, -1)), r;
14
14
  }
15
- function z(n) {
16
- const r = n.path || "/", t = D(r), f = t === "/" ? [] : t.split("/").filter(Boolean), s = [], i = [];
17
- for (let c = 0; c < f.length; c++) {
18
- const d = f[c];
15
+ function Q(n) {
16
+ const r = n.path || "/", t = _(r), h = t === "/" ? [] : t.split("/").filter(Boolean), o = [], s = [];
17
+ for (let u = 0; u < h.length; u++) {
18
+ const d = h[u];
19
19
  if (d === "*") {
20
- if (c !== f.length - 1)
20
+ if (u !== h.length - 1)
21
21
  return $(
22
22
  `Route '${n.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`
23
23
  ), { invalid: !0 };
24
- const p = `splat${s.length}`;
25
- s.push(p), i.push("__SPLAT__");
24
+ const p = `splat${o.length}`;
25
+ o.push(p), s.push("__SPLAT__");
26
26
  continue;
27
27
  }
28
- const w = d.match(/^:([A-Za-z0-9_-]+)(\*)?$/);
29
- if (w) {
30
- const p = w[1], b = !!w[2];
31
- if (b && c !== f.length - 1)
28
+ const y = d.match(/^:([A-Za-z0-9_-]+)(\*)?$/);
29
+ if (y) {
30
+ const p = y[1], w = !!y[2];
31
+ if (w && u !== h.length - 1)
32
32
  return $(
33
33
  `Route '${n.path}' contains a splat param ':${p}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`
34
34
  ), { invalid: !0 };
35
- s.push(p), i.push(b ? "__SPLAT__" : "([^/]+)");
35
+ o.push(p), s.push(w ? "__SPLAT__" : "([^/]+)");
36
36
  continue;
37
37
  }
38
- i.push(V(d));
38
+ s.push(H(d));
39
39
  }
40
- let o;
41
- if (i.length === 0)
42
- o = "^/$";
43
- else if (i[i.length - 1] === "__SPLAT__") {
44
- const d = i.slice(0, -1).join("/");
45
- d ? o = `^/${d}(?:/(.*))?(?:/)?$` : o = "^(?:/(.*))?(?:/)?$";
40
+ let c;
41
+ if (s.length === 0)
42
+ c = "^/$";
43
+ else if (s[s.length - 1] === "__SPLAT__") {
44
+ const d = s.slice(0, -1).join("/");
45
+ d ? c = `^/${d}(?:/(.*))?(?:/)?$` : c = "^(?:/(.*))?(?:/)?$";
46
46
  } else
47
- o = `^/${i.join("/")}(?:/)?$`;
47
+ c = `^/${s.join("/")}(?:/)?$`;
48
48
  try {
49
- return { regex: new RegExp(o), paramNames: s };
50
- } catch (c) {
51
- return $(`Failed to compile route regex for '${n.path}': ${String(c)}`), { invalid: !0 };
49
+ return { regex: new RegExp(c), paramNames: o };
50
+ } catch (u) {
51
+ return $(`Failed to compile route regex for '${n.path}': ${String(u)}`), { invalid: !0 };
52
52
  }
53
53
  }
54
- const x = (n, r) => {
55
- const t = D(r);
56
- for (const f of n) {
57
- let s = U.get(f);
58
- if (s || (s = z(f), U.set(f, s)), s.invalid) continue;
59
- const { regex: i, paramNames: o } = s, c = i.exec(t);
60
- if (c) {
61
- const d = {}, w = (p) => {
54
+ const C = (n, r) => {
55
+ const t = _(r);
56
+ for (const h of n) {
57
+ let o = F.get(h);
58
+ if (o || (o = Q(h), F.set(h, o)), o.invalid) continue;
59
+ const { regex: s, paramNames: c } = o, u = s.exec(t);
60
+ if (u) {
61
+ const d = {}, y = (p) => {
62
62
  try {
63
63
  return decodeURIComponent(p);
64
64
  } catch {
65
65
  return p;
66
66
  }
67
67
  };
68
- for (let p = 0; p < o.length; p++) {
69
- const b = c[p + 1] || "";
70
- d[o[p]] = b ? w(b) : "";
68
+ for (let p = 0; p < c.length; p++) {
69
+ const w = u[p + 1] || "";
70
+ d[c[p]] = w ? y(w) : "";
71
71
  }
72
- return { route: f, params: d };
72
+ return { route: h, params: d };
73
73
  }
74
74
  }
75
75
  return { route: null, params: {} };
76
76
  };
77
- function A(n, r) {
77
+ function L(n, r) {
78
78
  for (const t of n)
79
- if (x([t], r).route !== null) return t;
79
+ if (C([t], r).route !== null) return t;
80
80
  return null;
81
81
  }
82
- const L = {};
83
- async function H(n) {
82
+ const j = {};
83
+ async function Z(n) {
84
84
  if (n.component) return n.component;
85
85
  if (n.load) {
86
- if (L[n.path]) return L[n.path];
86
+ if (j[n.path]) return j[n.path];
87
87
  try {
88
88
  const r = await n.load();
89
- return L[n.path] = r.default, r.default;
89
+ return j[n.path] = r.default, r.default;
90
90
  } catch {
91
91
  throw new Error(`Failed to load component for route: ${n.path}`);
92
92
  }
93
93
  }
94
94
  throw new Error(`No component or loader defined for route: ${n.path}`);
95
95
  }
96
- function I(n) {
97
- const { routes: r, base: t = "", initialUrl: f } = n;
98
- let s, i, o, c, d, w, p;
99
- const b = async (u, l) => {
100
- const e = A(r, u.path);
96
+ function G(n) {
97
+ const { routes: r, base: t = "", initialUrl: h } = n;
98
+ let o, s, c, u, d, y, p;
99
+ const w = async (f, i) => {
100
+ const e = L(r, f.path);
101
101
  if (!e || !e.beforeEnter) return !0;
102
102
  try {
103
- const a = await e.beforeEnter(u, l);
103
+ const a = await e.beforeEnter(f, i);
104
104
  return typeof a == "string" ? (await R(a, !0), !1) : a !== !1;
105
105
  } catch (a) {
106
- return C("beforeEnter error", a), !1;
106
+ return A("beforeEnter error", a), !1;
107
107
  }
108
- }, k = async (u, l) => {
109
- const e = A(r, u.path);
108
+ }, q = async (f, i) => {
109
+ const e = L(r, f.path);
110
110
  if (!e || !e.onEnter) return !0;
111
111
  try {
112
- const a = await e.onEnter(u, l);
112
+ const a = await e.onEnter(f, i);
113
113
  return typeof a == "string" ? (await R(a, !0), !1) : a !== !1;
114
114
  } catch (a) {
115
- return C("onEnter error", a), !1;
115
+ return A("onEnter error", a), !1;
116
116
  }
117
- }, q = (u, l) => {
118
- const e = A(r, u.path);
117
+ }, N = (f, i) => {
118
+ const e = L(r, f.path);
119
119
  if (!(!e || !e.afterEnter))
120
120
  try {
121
- e.afterEnter(u, l);
121
+ e.afterEnter(f, i);
122
122
  } catch (a) {
123
- C("afterEnter error", a);
123
+ A("afterEnter error", a);
124
124
  }
125
- }, R = async (u, l = !1) => {
125
+ }, R = async (f, i = !1) => {
126
126
  try {
127
- const e = {
128
- path: u.replace(t, "") || "/",
129
- query: {}
130
- }, a = x(r, e.path);
131
- if (!a.route) throw new Error(`No route found for ${e.path}`);
132
- const m = o.getState(), h = {
133
- path: e.path,
134
- params: a.params,
135
- query: e.query
127
+ const e = f.indexOf("#"), a = e >= 0 ? f.slice(e + 1) : "", l = {
128
+ path: (e >= 0 ? f.slice(0, e) : f).replace(t, "") || "/",
129
+ query: {},
130
+ fragment: a
131
+ }, m = C(r, l.path);
132
+ if (!m.route) throw new Error(`No route found for ${l.path}`);
133
+ const v = c.getState(), E = {
134
+ path: l.path,
135
+ params: m.params,
136
+ query: l.query,
137
+ fragment: l.fragment
136
138
  };
137
- if (!await b(h, m) || !await k(h, m)) return;
138
- typeof window < "u" && typeof document < "u" && (l ? window.history.replaceState({}, "", t + u) : window.history.pushState({}, "", t + u)), o.setState(h), q(h, m);
139
+ if (!await w(E, v) || !await q(E, v)) return;
140
+ typeof window < "u" && typeof document < "u" && (i ? window.history.replaceState({}, "", t + f) : window.history.pushState({}, "", t + f)), c.setState(E), N(E, v);
139
141
  } catch (e) {
140
- C("Navigation error:", e);
142
+ A("Navigation error:", e);
141
143
  }
142
144
  };
143
- if (typeof window < "u" && typeof document < "u" && typeof f > "u") {
144
- s = () => {
145
- const l = new URL(window.location.href), e = l.pathname.replace(t, "") || "/", a = T(l.search);
146
- return { path: e, query: a };
147
- }, i = s();
148
- const u = x(r, i.path);
149
- o = B({
150
- path: i.path,
151
- params: u.params,
152
- query: i.query
153
- }), c = async (l = !1) => {
154
- const e = s();
155
- await R(e.path, l);
156
- }, window.addEventListener("popstate", () => c(!0)), d = (l) => R(l, !1), w = (l) => R(l, !0), p = () => window.history.back();
145
+ if (typeof window < "u" && typeof document < "u" && typeof h > "u") {
146
+ o = () => {
147
+ const i = new URL(window.location.href), e = i.pathname.replace(t, "") || "/", a = I(i.search), g = i.hash && i.hash.length ? i.hash.slice(1) : "";
148
+ return { path: e, query: a, fragment: g };
149
+ }, s = o();
150
+ const f = C(r, s.path);
151
+ c = D({
152
+ path: s.path,
153
+ params: f.params,
154
+ query: s.query,
155
+ fragment: s.fragment
156
+ }), u = async (i = !1) => {
157
+ const e = o();
158
+ await R(e.path, i);
159
+ }, window.addEventListener("popstate", () => u(!0)), d = (i) => R(i, !1), y = (i) => R(i, !0), p = () => window.history.back();
157
160
  } else {
158
- s = () => {
159
- const e = new URL(f || "/", "http://localhost"), a = e.pathname.replace(t, "") || "/", m = T(e.search);
160
- return { path: a, query: m };
161
- }, i = s();
162
- const u = x(r, i.path);
163
- o = B({
164
- path: i.path,
165
- params: u.params,
166
- query: i.query
167
- }), c = async () => {
168
- const e = s();
169
- await l(e.path);
161
+ o = () => {
162
+ const e = new URL(h || "/", "http://localhost"), a = e.pathname.replace(t, "") || "/", g = I(e.search), l = e.hash && e.hash.length ? e.hash.slice(1) : "";
163
+ return { path: a, query: g, fragment: l };
164
+ }, s = o();
165
+ const f = C(r, s.path);
166
+ c = D({
167
+ path: s.path,
168
+ params: f.params,
169
+ query: s.query,
170
+ fragment: s.fragment
171
+ }), u = async () => {
172
+ const e = o();
173
+ await i(e.path);
170
174
  };
171
- const l = async (e) => {
175
+ const i = async (e) => {
172
176
  try {
173
- const a = {
174
- path: e.replace(t, "") || "/",
175
- query: {}
176
- }, m = x(r, a.path);
177
- if (!m.route) throw new Error(`No route found for ${a.path}`);
178
- const h = o.getState(), v = {
179
- path: a.path,
180
- params: m.params,
181
- query: a.query
182
- }, y = A(r, v.path);
183
- if (y?.beforeEnter) {
184
- const E = await y.beforeEnter(v, h);
185
- if (typeof E == "string") {
186
- await l(E);
177
+ const a = e.indexOf("#"), g = a >= 0 ? e.slice(a + 1) : "", m = {
178
+ path: (a >= 0 ? e.slice(0, a) : e).replace(t, "") || "/",
179
+ query: {},
180
+ fragment: g
181
+ }, v = C(r, m.path);
182
+ if (!v.route) throw new Error(`No route found for ${m.path}`);
183
+ const E = c.getState(), k = {
184
+ path: m.path,
185
+ params: v.params,
186
+ query: m.query,
187
+ fragment: m.fragment
188
+ }, x = L(r, k.path);
189
+ if (x?.beforeEnter) {
190
+ const S = await x.beforeEnter(k, E);
191
+ if (typeof S == "string") {
192
+ await i(S);
187
193
  return;
188
194
  }
189
- if (E === !1) return;
195
+ if (S === !1) return;
190
196
  }
191
- if (y?.onEnter) {
192
- const E = await y.onEnter(v, h);
193
- if (typeof E == "string") {
194
- await l(E);
197
+ if (x?.onEnter) {
198
+ const S = await x.onEnter(k, E);
199
+ if (typeof S == "string") {
200
+ await i(S);
195
201
  return;
196
202
  }
197
- if (E === !1) return;
203
+ if (S === !1) return;
198
204
  }
199
- o.setState(v), y?.afterEnter && y.afterEnter(v, h);
205
+ c.setState(k), x?.afterEnter && x.afterEnter(k, E);
200
206
  } catch (a) {
201
- throw C("SSR navigation error:", a), a;
207
+ throw A("SSR navigation error:", a), a;
202
208
  }
203
209
  };
204
- d = async (e) => l(e), w = async (e) => l(e), p = () => {
210
+ d = async (e) => i(e), y = async (e) => i(e), p = () => {
205
211
  };
206
212
  }
207
213
  return {
208
- store: o,
214
+ store: c,
209
215
  push: d,
210
- replace: w,
216
+ replace: y,
211
217
  back: p,
212
- subscribe: o.subscribe,
213
- matchRoute: (u) => x(r, u),
214
- getCurrent: () => o.getState(),
215
- resolveRouteComponent: H
218
+ subscribe: c.subscribe,
219
+ matchRoute: (f) => C(r, f),
220
+ getCurrent: () => c.getState(),
221
+ resolveRouteComponent: Z
216
222
  };
217
223
  }
218
- function X(n, r) {
219
- return x(n, r);
224
+ function et(n, r) {
225
+ return C(n, r);
220
226
  }
221
- let P = null;
222
- function Y(n) {
223
- const r = I(n);
224
- return P = r, O("router-view", async () => {
225
- const t = P || r;
226
- if (!t) return S`<div>Router not initialized.</div>`;
227
- const f = _(t.getCurrent());
228
- let s;
229
- N(() => {
227
+ let B = null;
228
+ function rt(n) {
229
+ const r = G(n);
230
+ return B = r, T("router-view", async () => {
231
+ const t = B || r;
232
+ if (!t) return P`<div>Router not initialized.</div>`;
233
+ const h = O(t.getCurrent());
234
+ let o;
235
+ U(() => {
230
236
  try {
231
- t && typeof t.subscribe == "function" && (s = t.subscribe((o) => {
237
+ t && typeof t.subscribe == "function" && (o = t.subscribe((c) => {
232
238
  try {
233
- f.value = o;
234
- } catch (c) {
235
- $("router-view subscription update failed", c);
239
+ h.value = c;
240
+ } catch (u) {
241
+ $("router-view subscription update failed", u);
236
242
  }
237
243
  }));
238
- } catch (o) {
239
- $("router-view subscribe failed", o);
244
+ } catch (c) {
245
+ $("router-view subscribe failed", c);
240
246
  }
241
- }), j(() => {
242
- if (typeof s == "function")
247
+ }), W(() => {
248
+ if (typeof o == "function")
243
249
  try {
244
- s();
245
- } catch (o) {
246
- $("router-view unsubscribe failed", o);
250
+ o();
251
+ } catch (c) {
252
+ $("router-view unsubscribe failed", c);
247
253
  }
248
254
  });
249
- const i = t.matchRoute(f.value.path);
250
- if (!i || !i.route) return S`<div>Not found</div>`;
255
+ const s = t.matchRoute(h.value.path);
256
+ if (!s || !s.route) return P`<div>Not found</div>`;
251
257
  try {
252
- const c = await t.resolveRouteComponent(i.route);
253
- if (typeof c == "string")
254
- return { tag: c, props: {}, children: [] };
255
- if (typeof c == "function") {
256
- const d = c();
258
+ const u = await t.resolveRouteComponent(s.route);
259
+ if (typeof u == "string")
260
+ return { tag: u, props: {}, children: [] };
261
+ if (typeof u == "function") {
262
+ const d = u();
257
263
  return (d instanceof Promise ? d : Promise.resolve(d)).then((p) => typeof p == "string" ? { tag: p, props: {}, children: [] } : p);
258
264
  }
259
- return S`<div>Invalid route component</div>`;
265
+ return P`<div>Invalid route component</div>`;
260
266
  } catch {
261
- return S`<div>Invalid route component</div>`;
267
+ return P`<div>Invalid route component</div>`;
262
268
  }
263
- }), O("router-link", () => {
264
- const t = W({
269
+ }), T("router-link", () => {
270
+ const t = M({
265
271
  to: "",
266
272
  tag: "a",
267
273
  replace: !1,
@@ -274,94 +280,106 @@ function Y(n) {
274
280
  // allow host `class` and `style` attributes to be read via useProps
275
281
  class: "",
276
282
  style: ""
277
- }), f = P || r, s = _(f.getCurrent());
278
- let i;
279
- F(() => "a,button{display:inline-block;}");
280
- const o = _(t.class || ""), c = _(t.style || "");
281
- N((m) => {
283
+ }), h = B || r, o = O(h.getCurrent());
284
+ let s;
285
+ V(() => "a,button{display:inline-block;}");
286
+ const c = O(t.class || ""), u = O(t.style || "");
287
+ U((g) => {
282
288
  try {
283
- f && typeof f.subscribe == "function" && (i = f.subscribe((h) => {
289
+ h && typeof h.subscribe == "function" && (s = h.subscribe((l) => {
284
290
  try {
285
- s.value = h;
286
- } catch (v) {
287
- $("router-link subscription update failed", v);
291
+ o.value = l;
292
+ } catch (m) {
293
+ $("router-link subscription update failed", m);
288
294
  }
289
295
  }));
290
- } catch (h) {
291
- $("router-link subscribe failed", h);
296
+ } catch (l) {
297
+ $("router-link subscribe failed", l);
292
298
  }
293
299
  try {
294
- const h = m?._host;
295
- if (h instanceof HTMLElement) {
296
- const v = h.getAttribute("class"), y = h.getAttribute("style");
297
- v && (o.value = v), y && (c.value = y), v !== null && h.removeAttribute("class"), y !== null && h.removeAttribute("style");
300
+ const l = g?._host;
301
+ if (l instanceof HTMLElement) {
302
+ const m = l.getAttribute("class"), v = l.getAttribute("style");
303
+ m && (c.value = m), v && (u.value = v), m !== null && l.removeAttribute("class"), v !== null && l.removeAttribute("style");
298
304
  }
299
- } catch (h) {
300
- $("router-link host migration failed", h);
305
+ } catch (l) {
306
+ $("router-link host migration failed", l);
301
307
  }
302
- }), j(() => {
303
- if (typeof i == "function")
308
+ }), W(() => {
309
+ if (typeof s == "function")
304
310
  try {
305
- i();
306
- } catch (m) {
307
- $("router-link unsubscribe failed", m);
311
+ s();
312
+ } catch (g) {
313
+ $("router-link unsubscribe failed", g);
308
314
  }
309
315
  });
310
- const d = g(
311
- () => s.value.path === t.to
312
- ), w = g(
313
- () => t.exact ? d.value : s.value && typeof s.value.path == "string" ? s.value.path.startsWith(t.to) : !1
314
- ), p = g(() => {
315
- const h = (o && o.value || t.class || "").split(/\s+/).filter(Boolean), v = {};
316
- for (const y of h) v[y] = !0;
317
- return v;
318
- }), b = g(() => ({
316
+ const d = b(() => {
317
+ const l = (t.to || "").split("#")[0];
318
+ try {
319
+ return _(o.value.path) === _(l);
320
+ } catch {
321
+ return o.value.path === l;
322
+ }
323
+ }), y = b(() => {
324
+ const l = (t.to || "").split("#")[0];
325
+ if (t.exact) return d.value;
326
+ try {
327
+ const m = _(o.value.path), v = _(l);
328
+ return m.startsWith(v);
329
+ } catch {
330
+ return o.value && typeof o.value.path == "string" && o.value.path.startsWith(l);
331
+ }
332
+ }), p = b(() => {
333
+ const l = (c && c.value || t.class || "").split(/\s+/).filter(Boolean), m = {};
334
+ for (const v of l) m[v] = !0;
335
+ return m;
336
+ }), w = b(() => ({
319
337
  ...p.value,
320
- [t.activeClass || "active"]: w.value,
338
+ [t.activeClass || "active"]: y.value,
321
339
  [t.exactActiveClass || "exact-active"]: d.value
322
- })), k = g(
323
- () => Object.keys(b.value).filter((m) => b.value[m]).join(" ")
324
- ), q = g(() => t.tag === "button"), R = g(
340
+ })), q = b(
341
+ () => Object.keys(w.value).filter((g) => w.value[g]).join(" ")
342
+ ), N = b(() => t.tag === "button"), R = b(
325
343
  () => d.value ? t.ariaCurrentValue : ""
326
- ), u = g(() => !!t.disabled), l = g(
344
+ ), f = b(() => !!t.disabled), i = b(
327
345
  () => !!t.external && (t.tag === "a" || !t.tag)
328
- ), e = g(
329
- () => c && c.value || t.style || ""
330
- ), a = (m) => {
346
+ ), e = b(
347
+ () => u && u.value || t.style || ""
348
+ ), a = (g) => {
331
349
  if (t.disabled) {
332
- m.preventDefault();
350
+ g.preventDefault();
333
351
  return;
334
352
  }
335
- t.external && (t.tag === "a" || !t.tag) || (m.preventDefault(), t.replace ? f.replace(t.to) : f.push(t.to));
353
+ t.external && (t.tag === "a" || !t.tag) || (g.preventDefault(), t.replace ? h.replace(t.to) : h.push(t.to));
336
354
  };
337
- return S`
338
- ${M().when(
339
- q.value,
340
- S`
355
+ return P`
356
+ ${z().when(
357
+ N.value,
358
+ P`
341
359
  <button
342
360
  part="button"
343
- class="${k.value}"
361
+ class="${q.value}"
344
362
  style="${e.value || null}"
345
363
  aria-current="${R.value}"
346
- disabled="${u.value ? "" : null}"
347
- aria-disabled="${u.value ? "true" : null}"
348
- tabindex="${u.value ? "-1" : null}"
364
+ disabled="${f.value ? "" : null}"
365
+ aria-disabled="${f.value ? "true" : null}"
366
+ tabindex="${f.value ? "-1" : null}"
349
367
  @click="${a}"
350
368
  >
351
369
  <slot></slot>
352
370
  </button>
353
371
  `
354
- ).otherwise(S`
372
+ ).otherwise(P`
355
373
  <a
356
374
  part="link"
357
375
  href="${t.to}"
358
- class="${k.value}"
376
+ class="${q.value}"
359
377
  style="${e.value || null}"
360
378
  aria-current="${R.value}"
361
- aria-disabled="${u.value ? "true" : null}"
362
- tabindex="${u.value ? "-1" : null}"
363
- target="${l.value ? "_blank" : null}"
364
- rel="${l.value ? "noopener noreferrer" : null}"
379
+ aria-disabled="${f.value ? "true" : null}"
380
+ tabindex="${f.value ? "-1" : null}"
381
+ target="${i.value ? "_blank" : null}"
382
+ rel="${i.value ? "noopener noreferrer" : null}"
365
383
  @click="${a}"
366
384
  ><slot></slot
367
385
  ></a>
@@ -370,11 +388,12 @@ function Y(n) {
370
388
  }), r;
371
389
  }
372
390
  export {
373
- Y as initRouter,
374
- x as matchRoute,
375
- X as matchRouteSSR,
376
- T as parseQuery,
377
- H as resolveRouteComponent,
378
- I as useRouter
391
+ rt as initRouter,
392
+ C as matchRoute,
393
+ et as matchRouteSSR,
394
+ _ as normalizePathForRoute,
395
+ I as parseQuery,
396
+ Z as resolveRouteComponent,
397
+ G as useRouter
379
398
  };
380
399
  //# sourceMappingURL=custom-elements-runtime.router.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-elements-runtime.router.es.js","sources":["../src/lib/router.ts"],"sourcesContent":["import { html } from './runtime/template-compiler';\nimport { component } from './runtime/component';\nimport {\n useProps,\n useOnConnected,\n useOnDisconnected,\n useStyle,\n} from './runtime/hooks';\nimport { ref, computed } from './runtime/reactive';\nimport { createStore, type Store } from './store';\nimport { devError, devWarn } from './runtime/logger';\nimport { match } from './directives';\n\nexport type RouteComponent =\n | { new (...args: unknown[]): unknown } // class components\n | ((...args: unknown[]) => unknown); // functional components\n\nexport interface RouteState {\n path: string;\n params: Record<string, string>;\n query: Record<string, string>;\n}\n\nexport type GuardResult = boolean | string | Promise<boolean | string>;\n\nexport interface Route {\n path: string;\n\n /**\n * Statically available component (already imported)\n */\n component?: string | (() => unknown);\n\n /**\n * Lazy loader that resolves to something renderable\n */\n load?: () => Promise<{\n default: string | HTMLElement | ((...args: unknown[]) => unknown);\n }>;\n\n /**\n * Runs before matching — return false to cancel,\n * or a string to redirect\n */\n beforeEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs right before navigation commits — can cancel or redirect\n */\n onEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs after navigation completes — cannot cancel\n */\n afterEnter?: (to: RouteState, from: RouteState) => void;\n}\n\nexport interface RouterLinkProps {\n to: string;\n tag: string;\n replace: boolean;\n exact: boolean;\n activeClass: string;\n exactActiveClass: string;\n ariaCurrentValue: string;\n disabled: boolean;\n external: boolean;\n class?: string;\n style?: string;\n}\n\nexport interface RouterLinkComputed {\n current: RouteState;\n isExactActive: boolean;\n isActive: boolean;\n className: string;\n ariaCurrent: string;\n isButton: boolean;\n disabledAttr: string;\n externalAttr: string;\n}\n\nexport interface RouterConfig {\n routes: Route[];\n base?: string;\n initialUrl?: string; // For SSR: explicitly pass the URL\n}\n\nexport const parseQuery = (search: string): Record<string, string> => {\n if (!search) return {};\n if (typeof URLSearchParams === 'undefined') return {};\n return Object.fromEntries(new URLSearchParams(search));\n};\n\n// Cache compiled route regexes to avoid rebuilding on every navigation.\ntype CompiledRoute =\n | { regex: RegExp; paramNames: string[] }\n | { invalid: true };\nconst compileCache: WeakMap<Route, CompiledRoute> = new WeakMap();\n\nfunction escapeSeg(seg: string) {\n return seg.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction normalizePathForRoute(p: string) {\n if (!p) return '/';\n // Collapse duplicate slashes, ensure leading slash, remove trailing slash\n let out = p.replace(/\\/+/g, '/');\n if (!out.startsWith('/')) out = '/' + out;\n if (out.length > 1 && out.endsWith('/')) out = out.slice(0, -1);\n return out;\n}\n\nfunction compileRoute(route: Route): CompiledRoute {\n const raw = route.path || '/';\n const routePath = normalizePathForRoute(raw);\n\n const segments =\n routePath === '/' ? [] : routePath.split('/').filter(Boolean);\n\n const paramNames: string[] = [];\n const regexParts: string[] = [];\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n\n // Anonymous wildcard\n if (seg === '*') {\n // splat must be terminal\n if (i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n const name = `splat${paramNames.length}`;\n paramNames.push(name);\n // mark splat token; pattern will be built specially so the\n // preceding slash can be optional (allow empty splat)\n regexParts.push('__SPLAT__');\n continue;\n }\n\n const paramMatch = seg.match(/^:([A-Za-z0-9_-]+)(\\*)?$/);\n if (paramMatch) {\n const name = paramMatch[1];\n const isSplat = !!paramMatch[2];\n // If splat, ensure terminal\n if (isSplat && i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a splat param ':${name}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n paramNames.push(name);\n regexParts.push(isSplat ? '__SPLAT__' : '([^/]+)');\n continue;\n }\n\n // Static\n regexParts.push(escapeSeg(seg));\n }\n\n let pattern: string;\n if (regexParts.length === 0) {\n pattern = '^/$';\n } else {\n const last = regexParts[regexParts.length - 1];\n if (last === '__SPLAT__') {\n const prefix = regexParts.slice(0, -1).join('/');\n if (!prefix) {\n // route is like '/:rest*' or '/*' -> allow '/' or '/x' etc.\n pattern = '^(?:/(.*))?(?:/)?$';\n } else {\n pattern = `^/${prefix}(?:/(.*))?(?:/)?$`;\n }\n } else {\n pattern = `^/${regexParts.join('/')}(?:/)?$`;\n }\n }\n try {\n const regex = new RegExp(pattern);\n return { regex, paramNames };\n } catch (e) {\n devWarn(`Failed to compile route regex for '${route.path}': ${String(e)}`);\n return { invalid: true };\n }\n}\n\nexport const matchRoute = (\n routes: Route[],\n path: string,\n): { route: Route | null; params: Record<string, string> } => {\n const incoming = normalizePathForRoute(path);\n\n for (const route of routes) {\n let compiled = compileCache.get(route);\n if (!compiled) {\n compiled = compileRoute(route);\n compileCache.set(route, compiled);\n }\n\n if ((compiled as { invalid?: true }).invalid) continue;\n\n const { regex, paramNames } = compiled as {\n regex: RegExp;\n paramNames: string[];\n };\n const m = regex.exec(incoming);\n if (m) {\n const params: Record<string, string> = {};\n const safeDecode = (v: string) => {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n };\n\n for (let i = 0; i < paramNames.length; i++) {\n const raw = m[i + 1] || '';\n params[paramNames[i]] = raw ? safeDecode(raw) : '';\n }\n\n return { route, params };\n }\n }\n\n return { route: null, params: {} };\n};\n\n/**\n * Find the first route that matches the given path.\n * Consolidates repeated inline checks like `routes.find(r => matchRoute([r], path).route !== null)`\n */\nfunction findMatchedRoute(routes: Route[], path: string): Route | null {\n for (const r of routes) {\n if (matchRoute([r], path).route !== null) return r;\n }\n return null;\n}\n\n// Async component loader cache\nconst componentCache: Record<\n string,\n string | HTMLElement | ((...args: unknown[]) => unknown)\n> = {};\n\n/**\n * Loads a route's component, supporting both static and async.\n * @param route Route object\n * @returns Promise resolving to the component\n */\nexport async function resolveRouteComponent(\n route: Route,\n): Promise<string | HTMLElement | ((...args: unknown[]) => unknown)> {\n if (route.component) return route.component;\n if (route.load) {\n if (componentCache[route.path]) return componentCache[route.path];\n try {\n const mod = await route.load();\n componentCache[route.path] = mod.default;\n return mod.default;\n } catch {\n throw new Error(`Failed to load component for route: ${route.path}`);\n }\n }\n throw new Error(`No component or loader defined for route: ${route.path}`);\n}\n\nexport function useRouter(config: RouterConfig) {\n const { routes, base = '', initialUrl } = config;\n\n let getLocation: () => { path: string; query: Record<string, string> };\n let initial: { path: string; query: Record<string, string> };\n let store: Store<RouteState>;\n let update: (replace?: boolean) => Promise<void>;\n let push: (path: string) => Promise<void>;\n let replaceFn: (path: string) => Promise<void>;\n let back: () => void;\n\n // Run matching route guards/hooks\n const runBeforeEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.beforeEnter) return true;\n try {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('beforeEnter error', err);\n return false;\n }\n };\n\n const runOnEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.onEnter) return true;\n try {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('onEnter error', err);\n return false;\n }\n };\n\n const runAfterEnter = (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.afterEnter) return;\n try {\n matched.afterEnter(to, from);\n } catch (err) {\n devError('afterEnter error', err);\n }\n };\n\n const navigate = async (path: string, replace = false) => {\n try {\n const loc = {\n path: path.replace(base, '') || '/',\n query: {},\n };\n const match = matchRoute(routes, loc.path);\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n };\n\n // beforeEnter guard\n const allowedBefore = await runBeforeEnter(to, from);\n if (!allowedBefore) return;\n\n // onEnter guard (right before commit)\n const allowedOn = await runOnEnter(to, from);\n if (!allowedOn) return;\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (replace) {\n window.history.replaceState({}, '', base + path);\n } else {\n window.history.pushState({}, '', base + path);\n }\n }\n\n store.setState(to);\n\n // afterEnter hook (post commit)\n runAfterEnter(to, from);\n } catch (err) {\n devError('Navigation error:', err);\n }\n };\n\n // If an explicit `initialUrl` is provided we treat this as SSR/static rendering\n // even if a `window` exists (useful for hydration tests). Browser mode only\n // applies when `initialUrl` is undefined.\n if (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof initialUrl === 'undefined'\n ) {\n // Browser mode\n getLocation = () => {\n const url = new URL(window.location.href);\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n return { path, query };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n });\n\n update = async (replace = false) => {\n const loc = getLocation();\n await navigate(loc.path, replace);\n };\n\n window.addEventListener('popstate', () => update(true));\n\n push = (path: string) => navigate(path, false);\n replaceFn = (path: string) => navigate(path, true);\n back = () => window.history.back();\n } else {\n // SSR mode\n getLocation = () => {\n const url = new URL(initialUrl || '/', 'http://localhost');\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n return { path, query };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n });\n\n update = async () => {\n const loc = getLocation();\n await navigateSSR(loc.path);\n };\n\n // SSR navigation contract:\n // - `push` / `replace` call into `navigateSSR` and return a Promise.\n // - On the server we intentionally surface navigation failures so\n // server-side logic (or tests) can react: missing routes or thrown\n // errors from `beforeEnter`/`onEnter` will cause the Promise to\n // reject. This lets the server render 404s or abort builds.\n // - For valid routes the server-side navigation resolves and updates\n // the internal store state so rendered output matches the target\n // path. The `back()` operation is client-only and is a synchronous\n // no-op in SSR mode.\n const navigateSSR = async (path: string) => {\n try {\n const loc = {\n path: path.replace(base, '') || '/',\n query: {},\n };\n const match = matchRoute(routes, loc.path);\n // In SSR mode we intentionally surface navigation errors (missing\n // route) to the caller so server-side logic may handle them. If no\n // route matches, throw and let the caller observe the rejection.\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n };\n\n // beforeEnter guard\n const matched = findMatchedRoute(routes, to.path);\n if (matched?.beforeEnter) {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n // onEnter guard\n if (matched?.onEnter) {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n store.setState(to);\n\n // afterEnter hook\n if (matched?.afterEnter) {\n matched.afterEnter(to, from);\n }\n } catch (err) {\n // Surface SSR navigation errors so callers (and tests) can observe\n // failures during server-side resolution.\n devError('SSR navigation error:', err);\n throw err;\n }\n };\n\n push = async (path: string) => navigateSSR(path);\n replaceFn = async (path: string) => navigateSSR(path);\n back = () => {};\n }\n\n return {\n store,\n push,\n replace: replaceFn,\n back,\n subscribe: store.subscribe,\n matchRoute: (path: string) => matchRoute(routes, path),\n getCurrent: (): RouteState => store.getState(),\n resolveRouteComponent,\n };\n}\n\n// SSR/static site support: match route for a given path\nexport function matchRouteSSR(routes: Route[], path: string) {\n return matchRoute(routes, path);\n}\n\n// Module-level reference to the latest initialized router. Tests and\n// components may rely on re-initializing the router during their setup,\n// so exposing this lets components pick up the most recent instance.\nlet activeRouter: ReturnType<typeof useRouter> | null = null;\n\n/**\n * Singleton router instance for global access.\n *\n * Define here to prevent circular dependency\n * issue with component.\n */\n\nexport function initRouter(config: RouterConfig) {\n const router = useRouter(config);\n // Expose the most recently initialized router to components defined\n // earlier in the process (tests may call initRouter multiple times).\n // Components reference `activeRouter` so re-calling initRouter updates\n // the router instance they use.\n activeRouter = router;\n\n component('router-view', async () => {\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current route so the component re-renders when router updates\n if (!r) return html`<div>Router not initialized.</div>`;\n\n const current = ref(r.getCurrent());\n\n // We'll capture the unsubscribe function when the component connects\n // and register a disconnect cleanup during render-time (useOnDisconnected\n // must be called during the component render/execution).\n let unsubRouterView: (() => void) | undefined;\n\n useOnConnected(() => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterView = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-view subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-view subscribe failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterView === 'function') {\n try {\n unsubRouterView();\n } catch (e) {\n devWarn('router-view unsubscribe failed', e);\n }\n }\n });\n\n const match = r.matchRoute(current.value.path);\n if (!match || !match.route) return html`<div>Not found</div>`;\n\n // Resolve the component (supports cached async loaders)\n try {\n const compRaw = await r.resolveRouteComponent(match.route);\n const comp = compRaw as\n | string\n | HTMLElement\n | ((...args: unknown[]) => unknown)\n | undefined;\n // String tag (custom element) -> render as VNode\n if (typeof comp === 'string') {\n return { tag: comp, props: {}, children: [] };\n }\n\n // Function component (sync or async) -> call and return its VNode(s)\n if (typeof comp === 'function') {\n const out = comp();\n const resolved = out instanceof Promise ? out : Promise.resolve(out);\n return resolved.then((resolvedComp) => {\n if (typeof resolvedComp === 'string')\n return { tag: resolvedComp, props: {}, children: [] };\n return resolvedComp;\n });\n }\n\n return html`<div>Invalid route component</div>`;\n } catch {\n return html`<div>Invalid route component</div>`;\n }\n });\n\n component('router-link', () => {\n // Declare props via useProps so observedAttributes are correct\n const props = useProps<Partial<RouterLinkProps>>({\n to: '',\n tag: 'a',\n replace: false,\n exact: false,\n activeClass: 'active',\n exactActiveClass: 'exact-active',\n ariaCurrentValue: 'page',\n disabled: false,\n external: false,\n // allow host `class` and `style` attributes to be read via useProps\n class: '',\n style: '',\n });\n\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current state so link updates when route changes\n const current = ref(r.getCurrent());\n // Capture unsubscribe for link subscriptions and register disconnect\n // cleanup during render time.\n let unsubRouterLink: (() => void) | undefined;\n\n // Keep a minimal internal host-scoped style for element display.\n // Host `style` will be applied to the inner anchor/button element.\n useStyle(() => `a,button{display:inline-block;}`);\n\n // We capture host attributes at connection time and migrate them to\n // internal refs so we can remove them from the host. This prevents\n // global/author CSS targeting the host from styling the host element\n // itself while still allowing authors to use `class`/`style` on the\n // router-link to style the inner anchor/button.\n const hostClassRef = ref((props.class as string) || '');\n const hostStyleRef = ref((props.style as string) || '');\n\n useOnConnected((ctx?: unknown) => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterLink = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-link subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-link subscribe failed', e);\n }\n\n // Migrate host `class`/`style` into internal refs and remove them\n // from the host so only the inner element is styled.\n try {\n const host = (ctx as { _host?: HTMLElement } | undefined)?._host;\n if (host instanceof HTMLElement) {\n const hc = host.getAttribute('class');\n const hs = host.getAttribute('style');\n if (hc) hostClassRef.value = hc;\n if (hs) hostStyleRef.value = hs;\n // Remove attributes from host to avoid styling the host\n if (hc !== null) host.removeAttribute('class');\n if (hs !== null) host.removeAttribute('style');\n }\n } catch (e) {\n devWarn('router-link host migration failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterLink === 'function') {\n try {\n unsubRouterLink();\n } catch (e) {\n devWarn('router-link unsubscribe failed', e);\n }\n }\n });\n\n const isExactActive = computed(\n () => current.value.path === (props.to as string),\n );\n const isActive = computed(() =>\n props.exact\n ? isExactActive.value\n : current.value && typeof current.value.path === 'string'\n ? current.value.path.startsWith(props.to as string)\n : false,\n );\n\n // Build user classes reactively from the host `class` attribute prop.\n // We intentionally apply classes to the inner element so the consumer\n // can style the link via `class=\"...\"`.\n const userClasses = computed(() => {\n const rawHost =\n (hostClassRef && hostClassRef.value) || (props.class as string) || '';\n const list = rawHost.split(/\\s+/).filter(Boolean);\n const map: Record<string, boolean> = {};\n for (const c of list) map[c] = true;\n return map;\n });\n\n const classObject = computed(() => ({\n ...userClasses.value,\n [(props.activeClass as string) || 'active']: isActive.value,\n [(props.exactActiveClass as string) || 'exact-active']:\n isExactActive.value,\n }));\n\n // Compute a final class string (template accepts object or string; we\n // convert to string to safely include host classes and conditionals).\n const classString = computed(() =>\n Object.keys(classObject.value)\n .filter((k) => classObject.value[k])\n .join(' '),\n );\n\n const isButton = computed(() => (props.tag as string) === 'button');\n // Instead of pre-building attribute fragments as strings (which can\n // accidentally inject invalid attribute names into the template and\n // cause DOMExceptions), compute simple booleans/values and apply\n // attributes explicitly in the template below.\n const ariaCurrentValue = computed(() =>\n isExactActive.value ? (props.ariaCurrentValue as string) : '',\n );\n const isDisabled = computed(() => !!props.disabled);\n const isExternal = computed(\n () =>\n !!props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string)),\n );\n\n // Inline style from host `style` attribute.\n const inlineStyle = computed(\n () =>\n (hostStyleRef && hostStyleRef.value) || (props.style as string) || '',\n );\n\n const navigate = (e: MouseEvent) => {\n if (props.disabled) {\n e.preventDefault();\n return;\n }\n if (\n props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string))\n ) {\n return;\n }\n e.preventDefault();\n if (props.replace) {\n r.replace(props.to as string);\n } else {\n r.push(props.to as string);\n }\n };\n\n return html`\n ${match()\n .when(\n isButton.value,\n html`\n <button\n part=\"button\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n disabled=\"${isDisabled.value ? '' : null}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n @click=\"${navigate}\"\n >\n <slot></slot>\n </button>\n `,\n )\n .otherwise(html`\n <a\n part=\"link\"\n href=\"${props.to}\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n target=\"${isExternal.value ? '_blank' : null}\"\n rel=\"${isExternal.value ? 'noopener noreferrer' : null}\"\n @click=\"${navigate}\"\n ><slot></slot\n ></a>\n `)\n .done()}\n `;\n });\n\n return router;\n}\n"],"names":["parseQuery","search","compileCache","escapeSeg","seg","normalizePathForRoute","p","out","compileRoute","route","raw","routePath","segments","paramNames","regexParts","i","devWarn","name","paramMatch","isSplat","pattern","prefix","e","matchRoute","routes","path","incoming","compiled","regex","m","params","safeDecode","v","findMatchedRoute","r","componentCache","resolveRouteComponent","mod","useRouter","config","base","initialUrl","getLocation","initial","store","update","push","replaceFn","back","runBeforeEnter","to","from","matched","result","navigate","err","devError","runOnEnter","runAfterEnter","replace","loc","match","url","query","createStore","navigateSSR","matchRouteSSR","activeRouter","initRouter","router","component","html","current","ref","unsubRouterView","useOnConnected","s","useOnDisconnected","comp","resolvedComp","props","useProps","unsubRouterLink","useStyle","hostClassRef","hostStyleRef","ctx","host","hc","hs","isExactActive","computed","isActive","userClasses","list","map","c","classObject","classString","k","isButton","ariaCurrentValue","isDisabled","isExternal","inlineStyle"],"mappings":"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"}
1
+ {"version":3,"file":"custom-elements-runtime.router.es.js","sources":["../src/lib/router.ts"],"sourcesContent":["import { html } from './runtime/template-compiler';\nimport { component } from './runtime/component';\nimport {\n useProps,\n useOnConnected,\n useOnDisconnected,\n useStyle,\n} from './runtime/hooks';\nimport { ref, computed } from './runtime/reactive';\nimport { createStore, type Store } from './store';\nimport { devError, devWarn } from './runtime/logger';\nimport { match } from './directives';\n\nexport type RouteComponent =\n | { new (...args: unknown[]): unknown } // class components\n | ((...args: unknown[]) => unknown); // functional components\n\nexport interface RouteState {\n path: string;\n params: Record<string, string>;\n query: Record<string, string>;\n // Optional fragment (hash) portion of the URL, without the leading '#'\n fragment?: string;\n}\n\nexport type GuardResult = boolean | string | Promise<boolean | string>;\n\nexport interface Route {\n path: string;\n\n /**\n * Statically available component (already imported)\n */\n component?: string | (() => unknown);\n\n /**\n * Lazy loader that resolves to something renderable\n */\n load?: () => Promise<{\n default: string | HTMLElement | ((...args: unknown[]) => unknown);\n }>;\n\n /**\n * Runs before matching — return false to cancel,\n * or a string to redirect\n */\n beforeEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs right before navigation commits — can cancel or redirect\n */\n onEnter?: (to: RouteState, from: RouteState) => GuardResult;\n\n /**\n * Runs after navigation completes — cannot cancel\n */\n afterEnter?: (to: RouteState, from: RouteState) => void;\n}\n\nexport interface RouterLinkProps {\n to: string;\n tag: string;\n replace: boolean;\n exact: boolean;\n activeClass: string;\n exactActiveClass: string;\n ariaCurrentValue: string;\n disabled: boolean;\n external: boolean;\n class?: string;\n style?: string;\n}\n\nexport interface RouterLinkComputed {\n current: RouteState;\n isExactActive: boolean;\n isActive: boolean;\n className: string;\n ariaCurrent: string;\n isButton: boolean;\n disabledAttr: string;\n externalAttr: string;\n}\n\nexport interface RouterConfig {\n routes: Route[];\n base?: string;\n initialUrl?: string; // For SSR: explicitly pass the URL\n}\n\nexport const parseQuery = (search: string): Record<string, string> => {\n if (!search) return {};\n if (typeof URLSearchParams === 'undefined') return {};\n return Object.fromEntries(new URLSearchParams(search));\n};\n\n// Cache compiled route regexes to avoid rebuilding on every navigation.\ntype CompiledRoute =\n | { regex: RegExp; paramNames: string[] }\n | { invalid: true };\nconst compileCache: WeakMap<Route, CompiledRoute> = new WeakMap();\n\nfunction escapeSeg(seg: string) {\n return seg.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function normalizePathForRoute(p: string) {\n if (!p) return '/';\n // Collapse duplicate slashes, ensure leading slash, remove trailing slash\n let out = p.replace(/\\/+/g, '/');\n if (!out.startsWith('/')) out = '/' + out;\n if (out.length > 1 && out.endsWith('/')) out = out.slice(0, -1);\n return out;\n}\n\nfunction compileRoute(route: Route): CompiledRoute {\n const raw = route.path || '/';\n const routePath = normalizePathForRoute(raw);\n\n const segments =\n routePath === '/' ? [] : routePath.split('/').filter(Boolean);\n\n const paramNames: string[] = [];\n const regexParts: string[] = [];\n\n for (let i = 0; i < segments.length; i++) {\n const seg = segments[i];\n\n // Anonymous wildcard\n if (seg === '*') {\n // splat must be terminal\n if (i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a '*' splat in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n const name = `splat${paramNames.length}`;\n paramNames.push(name);\n // mark splat token; pattern will be built specially so the\n // preceding slash can be optional (allow empty splat)\n regexParts.push('__SPLAT__');\n continue;\n }\n\n const paramMatch = seg.match(/^:([A-Za-z0-9_-]+)(\\*)?$/);\n if (paramMatch) {\n const name = paramMatch[1];\n const isSplat = !!paramMatch[2];\n // If splat, ensure terminal\n if (isSplat && i !== segments.length - 1) {\n devWarn(\n `Route '${route.path}' contains a splat param ':${name}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`,\n );\n return { invalid: true };\n }\n paramNames.push(name);\n regexParts.push(isSplat ? '__SPLAT__' : '([^/]+)');\n continue;\n }\n\n // Static\n regexParts.push(escapeSeg(seg));\n }\n\n let pattern: string;\n if (regexParts.length === 0) {\n pattern = '^/$';\n } else {\n const last = regexParts[regexParts.length - 1];\n if (last === '__SPLAT__') {\n const prefix = regexParts.slice(0, -1).join('/');\n if (!prefix) {\n // route is like '/:rest*' or '/*' -> allow '/' or '/x' etc.\n pattern = '^(?:/(.*))?(?:/)?$';\n } else {\n pattern = `^/${prefix}(?:/(.*))?(?:/)?$`;\n }\n } else {\n pattern = `^/${regexParts.join('/')}(?:/)?$`;\n }\n }\n try {\n const regex = new RegExp(pattern);\n return { regex, paramNames };\n } catch (e) {\n devWarn(`Failed to compile route regex for '${route.path}': ${String(e)}`);\n return { invalid: true };\n }\n}\n\nexport const matchRoute = (\n routes: Route[],\n path: string,\n): { route: Route | null; params: Record<string, string> } => {\n const incoming = normalizePathForRoute(path);\n\n for (const route of routes) {\n let compiled = compileCache.get(route);\n if (!compiled) {\n compiled = compileRoute(route);\n compileCache.set(route, compiled);\n }\n\n if ((compiled as { invalid?: true }).invalid) continue;\n\n const { regex, paramNames } = compiled as {\n regex: RegExp;\n paramNames: string[];\n };\n const m = regex.exec(incoming);\n if (m) {\n const params: Record<string, string> = {};\n const safeDecode = (v: string) => {\n try {\n return decodeURIComponent(v);\n } catch {\n return v;\n }\n };\n\n for (let i = 0; i < paramNames.length; i++) {\n const raw = m[i + 1] || '';\n params[paramNames[i]] = raw ? safeDecode(raw) : '';\n }\n\n return { route, params };\n }\n }\n\n return { route: null, params: {} };\n};\n\n/**\n * Find the first route that matches the given path.\n * Consolidates repeated inline checks like `routes.find(r => matchRoute([r], path).route !== null)`\n */\nfunction findMatchedRoute(routes: Route[], path: string): Route | null {\n for (const r of routes) {\n if (matchRoute([r], path).route !== null) return r;\n }\n return null;\n}\n\n// Async component loader cache\nconst componentCache: Record<\n string,\n string | HTMLElement | ((...args: unknown[]) => unknown)\n> = {};\n\n/**\n * Loads a route's component, supporting both static and async.\n * @param route Route object\n * @returns Promise resolving to the component\n */\nexport async function resolveRouteComponent(\n route: Route,\n): Promise<string | HTMLElement | ((...args: unknown[]) => unknown)> {\n if (route.component) return route.component;\n if (route.load) {\n if (componentCache[route.path]) return componentCache[route.path];\n try {\n const mod = await route.load();\n componentCache[route.path] = mod.default;\n return mod.default;\n } catch {\n throw new Error(`Failed to load component for route: ${route.path}`);\n }\n }\n throw new Error(`No component or loader defined for route: ${route.path}`);\n}\n\nexport function useRouter(config: RouterConfig) {\n const { routes, base = '', initialUrl } = config;\n\n let getLocation: () => { path: string; query: Record<string, string> };\n let initial: { path: string; query: Record<string, string> };\n let store: Store<RouteState>;\n let update: (replace?: boolean) => Promise<void>;\n let push: (path: string) => Promise<void>;\n let replaceFn: (path: string) => Promise<void>;\n let back: () => void;\n\n // Run matching route guards/hooks\n const runBeforeEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.beforeEnter) return true;\n try {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('beforeEnter error', err);\n return false;\n }\n };\n\n const runOnEnter = async (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.onEnter) return true;\n try {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigate(result, true);\n return false;\n }\n return result !== false;\n } catch (err) {\n devError('onEnter error', err);\n return false;\n }\n };\n\n const runAfterEnter = (to: RouteState, from: RouteState) => {\n const matched = findMatchedRoute(routes, to.path);\n if (!matched || !matched.afterEnter) return;\n try {\n matched.afterEnter(to, from);\n } catch (err) {\n devError('afterEnter error', err);\n }\n };\n\n const navigate = async (path: string, replace = false) => {\n try {\n // Separate fragment (hash) from path so matching ignores it while\n // the fragment is preserved on the RouteState.\n const hashIndex = path.indexOf('#');\n const fragment = hashIndex >= 0 ? path.slice(hashIndex + 1) : '';\n const rawPath = hashIndex >= 0 ? path.slice(0, hashIndex) : path;\n const loc = {\n path: rawPath.replace(base, '') || '/',\n query: {},\n fragment,\n };\n const match = matchRoute(routes, loc.path);\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n fragment: (loc as { fragment?: string }).fragment,\n };\n\n // beforeEnter guard\n const allowedBefore = await runBeforeEnter(to, from);\n if (!allowedBefore) return;\n\n // onEnter guard (right before commit)\n const allowedOn = await runOnEnter(to, from);\n if (!allowedOn) return;\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (replace) {\n window.history.replaceState({}, '', base + path);\n } else {\n window.history.pushState({}, '', base + path);\n }\n }\n\n store.setState(to);\n\n // afterEnter hook (post commit)\n runAfterEnter(to, from);\n } catch (err) {\n devError('Navigation error:', err);\n }\n };\n\n // If an explicit `initialUrl` is provided we treat this as SSR/static rendering\n // even if a `window` exists (useful for hydration tests). Browser mode only\n // applies when `initialUrl` is undefined.\n if (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof initialUrl === 'undefined'\n ) {\n // Browser mode\n getLocation = () => {\n const url = new URL(window.location.href);\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n const fragment = url.hash && url.hash.length ? url.hash.slice(1) : '';\n return { path, query, fragment };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n fragment: (initial as { fragment?: string }).fragment,\n });\n\n update = async (replace = false) => {\n const loc = getLocation();\n await navigate(loc.path, replace);\n };\n\n window.addEventListener('popstate', () => update(true));\n\n push = (path: string) => navigate(path, false);\n replaceFn = (path: string) => navigate(path, true);\n back = () => window.history.back();\n } else {\n // SSR mode\n getLocation = () => {\n const url = new URL(initialUrl || '/', 'http://localhost');\n const path = url.pathname.replace(base, '') || '/';\n const query = parseQuery(url.search);\n const fragment = url.hash && url.hash.length ? url.hash.slice(1) : '';\n return { path, query, fragment };\n };\n\n initial = getLocation();\n const match = matchRoute(routes, initial.path);\n store = createStore<RouteState>({\n path: initial.path,\n params: match.params,\n query: initial.query,\n fragment: (initial as { fragment?: string }).fragment,\n });\n\n update = async () => {\n const loc = getLocation();\n await navigateSSR(loc.path);\n };\n\n // SSR navigation contract:\n // - `push` / `replace` call into `navigateSSR` and return a Promise.\n // - On the server we intentionally surface navigation failures so\n // server-side logic (or tests) can react: missing routes or thrown\n // errors from `beforeEnter`/`onEnter` will cause the Promise to\n // reject. This lets the server render 404s or abort builds.\n // - For valid routes the server-side navigation resolves and updates\n // the internal store state so rendered output matches the target\n // path. The `back()` operation is client-only and is a synchronous\n // no-op in SSR mode.\n const navigateSSR = async (path: string) => {\n try {\n const hashIndex = path.indexOf('#');\n const fragment = hashIndex >= 0 ? path.slice(hashIndex + 1) : '';\n const rawPath = hashIndex >= 0 ? path.slice(0, hashIndex) : path;\n const loc = {\n path: rawPath.replace(base, '') || '/',\n query: {},\n fragment,\n };\n const match = matchRoute(routes, loc.path);\n // In SSR mode we intentionally surface navigation errors (missing\n // route) to the caller so server-side logic may handle them. If no\n // route matches, throw and let the caller observe the rejection.\n if (!match.route) throw new Error(`No route found for ${loc.path}`);\n\n const from = store.getState();\n const to: RouteState = {\n path: loc.path,\n params: match.params,\n query: loc.query,\n fragment: (loc as { fragment?: string }).fragment,\n };\n\n // beforeEnter guard\n const matched = findMatchedRoute(routes, to.path);\n if (matched?.beforeEnter) {\n const result = await matched.beforeEnter(to, from);\n if (typeof result === 'string') {\n // Redirect\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n // onEnter guard\n if (matched?.onEnter) {\n const result = await matched.onEnter(to, from);\n if (typeof result === 'string') {\n await navigateSSR(result);\n return;\n }\n if (result === false) return;\n }\n\n store.setState(to);\n\n // afterEnter hook\n if (matched?.afterEnter) {\n matched.afterEnter(to, from);\n }\n } catch (err) {\n // Surface SSR navigation errors so callers (and tests) can observe\n // failures during server-side resolution.\n devError('SSR navigation error:', err);\n throw err;\n }\n };\n\n push = async (path: string) => navigateSSR(path);\n replaceFn = async (path: string) => navigateSSR(path);\n back = () => {};\n }\n\n return {\n store,\n push,\n replace: replaceFn,\n back,\n subscribe: store.subscribe,\n matchRoute: (path: string) => matchRoute(routes, path),\n getCurrent: (): RouteState => store.getState(),\n resolveRouteComponent,\n };\n}\n\n// SSR/static site support: match route for a given path\nexport function matchRouteSSR(routes: Route[], path: string) {\n return matchRoute(routes, path);\n}\n\n// Module-level reference to the latest initialized router. Tests and\n// components may rely on re-initializing the router during their setup,\n// so exposing this lets components pick up the most recent instance.\nlet activeRouter: ReturnType<typeof useRouter> | null = null;\n\n/**\n * Singleton router instance for global access.\n *\n * Define here to prevent circular dependency\n * issue with component.\n */\n\nexport function initRouter(config: RouterConfig) {\n const router = useRouter(config);\n // Expose the most recently initialized router to components defined\n // earlier in the process (tests may call initRouter multiple times).\n // Components reference `activeRouter` so re-calling initRouter updates\n // the router instance they use.\n activeRouter = router;\n\n component('router-view', async () => {\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current route so the component re-renders when router updates\n if (!r) return html`<div>Router not initialized.</div>`;\n\n const current = ref(r.getCurrent());\n\n // We'll capture the unsubscribe function when the component connects\n // and register a disconnect cleanup during render-time (useOnDisconnected\n // must be called during the component render/execution).\n let unsubRouterView: (() => void) | undefined;\n\n useOnConnected(() => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterView = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-view subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-view subscribe failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterView === 'function') {\n try {\n unsubRouterView();\n } catch (e) {\n devWarn('router-view unsubscribe failed', e);\n }\n }\n });\n\n const match = r.matchRoute(current.value.path);\n if (!match || !match.route) return html`<div>Not found</div>`;\n\n // Resolve the component (supports cached async loaders)\n try {\n const compRaw = await r.resolveRouteComponent(match.route);\n const comp = compRaw as\n | string\n | HTMLElement\n | ((...args: unknown[]) => unknown)\n | undefined;\n // String tag (custom element) -> render as VNode\n if (typeof comp === 'string') {\n return { tag: comp, props: {}, children: [] };\n }\n\n // Function component (sync or async) -> call and return its VNode(s)\n if (typeof comp === 'function') {\n const out = comp();\n const resolved = out instanceof Promise ? out : Promise.resolve(out);\n return resolved.then((resolvedComp) => {\n if (typeof resolvedComp === 'string')\n return { tag: resolvedComp, props: {}, children: [] };\n return resolvedComp;\n });\n }\n\n return html`<div>Invalid route component</div>`;\n } catch {\n return html`<div>Invalid route component</div>`;\n }\n });\n\n component('router-link', () => {\n // Declare props via useProps so observedAttributes are correct\n const props = useProps<Partial<RouterLinkProps>>({\n to: '',\n tag: 'a',\n replace: false,\n exact: false,\n activeClass: 'active',\n exactActiveClass: 'exact-active',\n ariaCurrentValue: 'page',\n disabled: false,\n external: false,\n // allow host `class` and `style` attributes to be read via useProps\n class: '',\n style: '',\n });\n\n // Prefer the latest initialized router (tests may re-init). Fallback\n // to the router captured at init time.\n const r = activeRouter || router;\n // Reactive current state so link updates when route changes\n const current = ref(r.getCurrent());\n // Capture unsubscribe for link subscriptions and register disconnect\n // cleanup during render time.\n let unsubRouterLink: (() => void) | undefined;\n\n // Keep a minimal internal host-scoped style for element display.\n // Host `style` will be applied to the inner anchor/button element.\n useStyle(() => `a,button{display:inline-block;}`);\n\n // We capture host attributes at connection time and migrate them to\n // internal refs so we can remove them from the host. This prevents\n // global/author CSS targeting the host from styling the host element\n // itself while still allowing authors to use `class`/`style` on the\n // router-link to style the inner anchor/button.\n const hostClassRef = ref((props.class as string) || '');\n const hostStyleRef = ref((props.style as string) || '');\n\n useOnConnected((ctx?: unknown) => {\n try {\n if (r && typeof r.subscribe === 'function') {\n unsubRouterLink = r.subscribe((s) => {\n try {\n current.value = s;\n } catch (e) {\n devWarn('router-link subscription update failed', e);\n }\n });\n }\n } catch (e) {\n devWarn('router-link subscribe failed', e);\n }\n\n // Migrate host `class`/`style` into internal refs and remove them\n // from the host so only the inner element is styled.\n try {\n const host = (ctx as { _host?: HTMLElement } | undefined)?._host;\n if (host instanceof HTMLElement) {\n const hc = host.getAttribute('class');\n const hs = host.getAttribute('style');\n if (hc) hostClassRef.value = hc;\n if (hs) hostStyleRef.value = hs;\n // Remove attributes from host to avoid styling the host\n if (hc !== null) host.removeAttribute('class');\n if (hs !== null) host.removeAttribute('style');\n }\n } catch (e) {\n devWarn('router-link host migration failed', e);\n }\n });\n\n useOnDisconnected(() => {\n if (typeof unsubRouterLink === 'function') {\n try {\n unsubRouterLink();\n } catch (e) {\n devWarn('router-link unsubscribe failed', e);\n }\n }\n });\n\n const isExactActive = computed(() => {\n const targetRaw = (props.to as string) || '';\n // strip fragment from target when comparing\n const targetPathOnly = targetRaw.split('#')[0];\n try {\n return (\n normalizePathForRoute(current.value.path) ===\n normalizePathForRoute(targetPathOnly)\n );\n } catch {\n return current.value.path === targetPathOnly;\n }\n });\n\n const isActive = computed(() => {\n const targetRaw = (props.to as string) || '';\n const targetPathOnly = targetRaw.split('#')[0];\n if (props.exact) return isExactActive.value;\n try {\n const cur = normalizePathForRoute(current.value.path);\n const tgt = normalizePathForRoute(targetPathOnly);\n return cur.startsWith(tgt);\n } catch {\n return (\n current.value &&\n typeof current.value.path === 'string' &&\n current.value.path.startsWith(targetPathOnly)\n );\n }\n });\n\n // Build user classes reactively from the host `class` attribute prop.\n // We intentionally apply classes to the inner element so the consumer\n // can style the link via `class=\"...\"`.\n const userClasses = computed(() => {\n const rawHost =\n (hostClassRef && hostClassRef.value) || (props.class as string) || '';\n const list = rawHost.split(/\\s+/).filter(Boolean);\n const map: Record<string, boolean> = {};\n for (const c of list) map[c] = true;\n return map;\n });\n\n const classObject = computed(() => ({\n ...userClasses.value,\n [(props.activeClass as string) || 'active']: isActive.value,\n [(props.exactActiveClass as string) || 'exact-active']:\n isExactActive.value,\n }));\n\n // Compute a final class string (template accepts object or string; we\n // convert to string to safely include host classes and conditionals).\n const classString = computed(() =>\n Object.keys(classObject.value)\n .filter((k) => classObject.value[k])\n .join(' '),\n );\n\n const isButton = computed(() => (props.tag as string) === 'button');\n // Instead of pre-building attribute fragments as strings (which can\n // accidentally inject invalid attribute names into the template and\n // cause DOMExceptions), compute simple booleans/values and apply\n // attributes explicitly in the template below.\n const ariaCurrentValue = computed(() =>\n isExactActive.value ? (props.ariaCurrentValue as string) : '',\n );\n const isDisabled = computed(() => !!props.disabled);\n const isExternal = computed(\n () =>\n !!props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string)),\n );\n\n // Inline style from host `style` attribute.\n const inlineStyle = computed(\n () =>\n (hostStyleRef && hostStyleRef.value) || (props.style as string) || '',\n );\n\n const navigate = (e: MouseEvent) => {\n if (props.disabled) {\n e.preventDefault();\n return;\n }\n if (\n props.external &&\n ((props.tag as string) === 'a' || !(props.tag as string))\n ) {\n return;\n }\n e.preventDefault();\n if (props.replace) {\n r.replace(props.to as string);\n } else {\n r.push(props.to as string);\n }\n };\n\n return html`\n ${match()\n .when(\n isButton.value,\n html`\n <button\n part=\"button\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n disabled=\"${isDisabled.value ? '' : null}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n @click=\"${navigate}\"\n >\n <slot></slot>\n </button>\n `,\n )\n .otherwise(html`\n <a\n part=\"link\"\n href=\"${props.to}\"\n class=\"${classString.value}\"\n style=\"${inlineStyle.value || null}\"\n aria-current=\"${ariaCurrentValue.value}\"\n aria-disabled=\"${isDisabled.value ? 'true' : null}\"\n tabindex=\"${isDisabled.value ? '-1' : null}\"\n target=\"${isExternal.value ? '_blank' : null}\"\n rel=\"${isExternal.value ? 'noopener noreferrer' : null}\"\n @click=\"${navigate}\"\n ><slot></slot\n ></a>\n `)\n .done()}\n `;\n });\n\n return router;\n}\n"],"names":["parseQuery","search","compileCache","escapeSeg","seg","normalizePathForRoute","p","out","compileRoute","route","raw","routePath","segments","paramNames","regexParts","i","devWarn","name","paramMatch","isSplat","pattern","prefix","e","matchRoute","routes","path","incoming","compiled","regex","m","params","safeDecode","v","findMatchedRoute","r","componentCache","resolveRouteComponent","mod","useRouter","config","base","initialUrl","getLocation","initial","store","update","push","replaceFn","back","runBeforeEnter","to","from","matched","result","navigate","err","devError","runOnEnter","runAfterEnter","replace","hashIndex","fragment","loc","match","url","query","createStore","navigateSSR","matchRouteSSR","activeRouter","initRouter","router","component","html","current","ref","unsubRouterView","useOnConnected","s","useOnDisconnected","comp","resolvedComp","props","useProps","unsubRouterLink","useStyle","hostClassRef","hostStyleRef","ctx","host","hc","hs","isExactActive","computed","targetPathOnly","isActive","cur","tgt","userClasses","list","map","c","classObject","classString","k","isButton","ariaCurrentValue","isDisabled","isExternal","inlineStyle"],"mappings":";;;;;AA0FO,MAAMA,IAAa,CAACC,MACpBA,IACD,OAAO,kBAAoB,MAAoB,CAAA,IAC5C,OAAO,YAAY,IAAI,gBAAgBA,CAAM,CAAC,IAFjC,CAAA,GAShBC,wBAAkD,QAAA;AAExD,SAASC,EAAUC,GAAa;AAC9B,SAAOA,EAAI,QAAQ,uBAAuB,MAAM;AAClD;AAEO,SAASC,EAAsBC,GAAW;AAC/C,MAAI,CAACA,EAAG,QAAO;AAEf,MAAIC,IAAMD,EAAE,QAAQ,QAAQ,GAAG;AAC/B,SAAKC,EAAI,WAAW,GAAG,UAAS,MAAMA,IAClCA,EAAI,SAAS,KAAKA,EAAI,SAAS,GAAG,MAAGA,IAAMA,EAAI,MAAM,GAAG,EAAE,IACvDA;AACT;AAEA,SAASC,EAAaC,GAA6B;AACjD,QAAMC,IAAMD,EAAM,QAAQ,KACpBE,IAAYN,EAAsBK,CAAG,GAErCE,IACJD,MAAc,MAAM,CAAA,IAAKA,EAAU,MAAM,GAAG,EAAE,OAAO,OAAO,GAExDE,IAAuB,CAAA,GACvBC,IAAuB,CAAA;AAE7B,WAASC,IAAI,GAAGA,IAAIH,EAAS,QAAQG,KAAK;AACxC,UAAMX,IAAMQ,EAASG,CAAC;AAGtB,QAAIX,MAAQ,KAAK;AAEf,UAAIW,MAAMH,EAAS,SAAS;AAC1B,eAAAI;AAAA,UACE,UAAUP,EAAM,IAAI;AAAA,QAAA,GAEf,EAAE,SAAS,GAAA;AAEpB,YAAMQ,IAAO,QAAQJ,EAAW,MAAM;AACtC,MAAAA,EAAW,KAAKI,CAAI,GAGpBH,EAAW,KAAK,WAAW;AAC3B;AAAA,IACF;AAEA,UAAMI,IAAad,EAAI,MAAM,0BAA0B;AACvD,QAAIc,GAAY;AACd,YAAMD,IAAOC,EAAW,CAAC,GACnBC,IAAU,CAAC,CAACD,EAAW,CAAC;AAE9B,UAAIC,KAAWJ,MAAMH,EAAS,SAAS;AACrC,eAAAI;AAAA,UACE,UAAUP,EAAM,IAAI,8BAA8BQ,CAAI;AAAA,QAAA,GAEjD,EAAE,SAAS,GAAA;AAEpB,MAAAJ,EAAW,KAAKI,CAAI,GACpBH,EAAW,KAAKK,IAAU,cAAc,SAAS;AACjD;AAAA,IACF;AAGA,IAAAL,EAAW,KAAKX,EAAUC,CAAG,CAAC;AAAA,EAChC;AAEA,MAAIgB;AACJ,MAAIN,EAAW,WAAW;AACxB,IAAAM,IAAU;AAAA,WAEGN,EAAWA,EAAW,SAAS,CAAC,MAChC,aAAa;AACxB,UAAMO,IAASP,EAAW,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG;AAC/C,IAAKO,IAIHD,IAAU,KAAKC,CAAM,sBAFrBD,IAAU;AAAA,EAId;AACE,IAAAA,IAAU,KAAKN,EAAW,KAAK,GAAG,CAAC;AAGvC,MAAI;AAEF,WAAO,EAAE,OADK,IAAI,OAAOM,CAAO,GAChB,YAAAP,EAAA;AAAA,EAClB,SAASS,GAAG;AACV,WAAAN,EAAQ,sCAAsCP,EAAM,IAAI,MAAM,OAAOa,CAAC,CAAC,EAAE,GAClE,EAAE,SAAS,GAAA;AAAA,EACpB;AACF;AAEO,MAAMC,IAAa,CACxBC,GACAC,MAC4D;AAC5D,QAAMC,IAAWrB,EAAsBoB,CAAI;AAE3C,aAAWhB,KAASe,GAAQ;AAC1B,QAAIG,IAAWzB,EAAa,IAAIO,CAAK;AAMrC,QALKkB,MACHA,IAAWnB,EAAaC,CAAK,GAC7BP,EAAa,IAAIO,GAAOkB,CAAQ,IAG7BA,EAAgC,QAAS;AAE9C,UAAM,EAAE,OAAAC,GAAO,YAAAf,EAAA,IAAec,GAIxBE,IAAID,EAAM,KAAKF,CAAQ;AAC7B,QAAIG,GAAG;AACL,YAAMC,IAAiC,CAAA,GACjCC,IAAa,CAACC,MAAc;AAChC,YAAI;AACF,iBAAO,mBAAmBA,CAAC;AAAA,QAC7B,QAAQ;AACN,iBAAOA;AAAA,QACT;AAAA,MACF;AAEA,eAASjB,IAAI,GAAGA,IAAIF,EAAW,QAAQE,KAAK;AAC1C,cAAML,IAAMmB,EAAEd,IAAI,CAAC,KAAK;AACxB,QAAAe,EAAOjB,EAAWE,CAAC,CAAC,IAAIL,IAAMqB,EAAWrB,CAAG,IAAI;AAAA,MAClD;AAEA,aAAO,EAAE,OAAAD,GAAO,QAAAqB,EAAA;AAAA,IAClB;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,MAAM,QAAQ,CAAA,EAAC;AACjC;AAMA,SAASG,EAAiBT,GAAiBC,GAA4B;AACrE,aAAWS,KAAKV;AACd,QAAID,EAAW,CAACW,CAAC,GAAGT,CAAI,EAAE,UAAU,KAAM,QAAOS;AAEnD,SAAO;AACT;AAGA,MAAMC,IAGF,CAAA;AAOJ,eAAsBC,EACpB3B,GACmE;AACnE,MAAIA,EAAM,UAAW,QAAOA,EAAM;AAClC,MAAIA,EAAM,MAAM;AACd,QAAI0B,EAAe1B,EAAM,IAAI,EAAG,QAAO0B,EAAe1B,EAAM,IAAI;AAChE,QAAI;AACF,YAAM4B,IAAM,MAAM5B,EAAM,KAAA;AACxB,aAAA0B,EAAe1B,EAAM,IAAI,IAAI4B,EAAI,SAC1BA,EAAI;AAAA,IACb,QAAQ;AACN,YAAM,IAAI,MAAM,uCAAuC5B,EAAM,IAAI,EAAE;AAAA,IACrE;AAAA,EACF;AACA,QAAM,IAAI,MAAM,6CAA6CA,EAAM,IAAI,EAAE;AAC3E;AAEO,SAAS6B,EAAUC,GAAsB;AAC9C,QAAM,EAAE,QAAAf,GAAQ,MAAAgB,IAAO,IAAI,YAAAC,MAAeF;AAE1C,MAAIG,GACAC,GACAC,GACAC,GACAC,GACAC,GACAC;AAGJ,QAAMC,IAAiB,OAAOC,GAAgBC,MAAqB;AACjE,UAAMC,IAAUnB,EAAiBT,GAAQ0B,EAAG,IAAI;AAChD,QAAI,CAACE,KAAW,CAACA,EAAQ,YAAa,QAAO;AAC7C,QAAI;AACF,YAAMC,IAAS,MAAMD,EAAQ,YAAYF,GAAIC,CAAI;AACjD,aAAI,OAAOE,KAAW,YAEpB,MAAMC,EAASD,GAAQ,EAAI,GACpB,MAEFA,MAAW;AAAA,IACpB,SAASE,GAAK;AACZ,aAAAC,EAAS,qBAAqBD,CAAG,GAC1B;AAAA,IACT;AAAA,EACF,GAEME,IAAa,OAAOP,GAAgBC,MAAqB;AAC7D,UAAMC,IAAUnB,EAAiBT,GAAQ0B,EAAG,IAAI;AAChD,QAAI,CAACE,KAAW,CAACA,EAAQ,QAAS,QAAO;AACzC,QAAI;AACF,YAAMC,IAAS,MAAMD,EAAQ,QAAQF,GAAIC,CAAI;AAC7C,aAAI,OAAOE,KAAW,YACpB,MAAMC,EAASD,GAAQ,EAAI,GACpB,MAEFA,MAAW;AAAA,IACpB,SAASE,GAAK;AACZ,aAAAC,EAAS,iBAAiBD,CAAG,GACtB;AAAA,IACT;AAAA,EACF,GAEMG,IAAgB,CAACR,GAAgBC,MAAqB;AAC1D,UAAMC,IAAUnB,EAAiBT,GAAQ0B,EAAG,IAAI;AAChD,QAAI,GAACE,KAAW,CAACA,EAAQ;AACzB,UAAI;AACF,QAAAA,EAAQ,WAAWF,GAAIC,CAAI;AAAA,MAC7B,SAASI,GAAK;AACZ,QAAAC,EAAS,oBAAoBD,CAAG;AAAA,MAClC;AAAA,EACF,GAEMD,IAAW,OAAO7B,GAAckC,IAAU,OAAU;AACxD,QAAI;AAGF,YAAMC,IAAYnC,EAAK,QAAQ,GAAG,GAC5BoC,IAAWD,KAAa,IAAInC,EAAK,MAAMmC,IAAY,CAAC,IAAI,IAExDE,IAAM;AAAA,QACV,OAFcF,KAAa,IAAInC,EAAK,MAAM,GAAGmC,CAAS,IAAInC,GAE5C,QAAQe,GAAM,EAAE,KAAK;AAAA,QACnC,OAAO,CAAA;AAAA,QACP,UAAAqB;AAAA,MAAA,GAEIE,IAAQxC,EAAWC,GAAQsC,EAAI,IAAI;AACzC,UAAI,CAACC,EAAM,MAAO,OAAM,IAAI,MAAM,sBAAsBD,EAAI,IAAI,EAAE;AAElE,YAAMX,IAAOP,EAAM,SAAA,GACbM,IAAiB;AAAA,QACrB,MAAMY,EAAI;AAAA,QACV,QAAQC,EAAM;AAAA,QACd,OAAOD,EAAI;AAAA,QACX,UAAWA,EAA8B;AAAA,MAAA;AAS3C,UAJI,CADkB,MAAMb,EAAeC,GAAIC,CAAI,KAK/C,CADc,MAAMM,EAAWP,GAAIC,CAAI,EAC3B;AAEhB,MAAI,OAAO,SAAW,OAAe,OAAO,WAAa,QACnDQ,IACF,OAAO,QAAQ,aAAa,CAAA,GAAI,IAAInB,IAAOf,CAAI,IAE/C,OAAO,QAAQ,UAAU,CAAA,GAAI,IAAIe,IAAOf,CAAI,IAIhDmB,EAAM,SAASM,CAAE,GAGjBQ,EAAcR,GAAIC,CAAI;AAAA,IACxB,SAASI,GAAK;AACZ,MAAAC,EAAS,qBAAqBD,CAAG;AAAA,IACnC;AAAA,EACF;AAKA,MACE,OAAO,SAAW,OAClB,OAAO,WAAa,OACpB,OAAOd,IAAe,KACtB;AAEA,IAAAC,IAAc,MAAM;AAClB,YAAMsB,IAAM,IAAI,IAAI,OAAO,SAAS,IAAI,GAClCvC,IAAOuC,EAAI,SAAS,QAAQxB,GAAM,EAAE,KAAK,KACzCyB,IAAQjE,EAAWgE,EAAI,MAAM,GAC7BH,IAAWG,EAAI,QAAQA,EAAI,KAAK,SAASA,EAAI,KAAK,MAAM,CAAC,IAAI;AACnE,aAAO,EAAE,MAAAvC,GAAM,OAAAwC,GAAO,UAAAJ,EAAA;AAAA,IACxB,GAEAlB,IAAUD,EAAA;AACV,UAAMqB,IAAQxC,EAAWC,GAAQmB,EAAQ,IAAI;AAC7C,IAAAC,IAAQsB,EAAwB;AAAA,MAC9B,MAAMvB,EAAQ;AAAA,MACd,QAAQoB,EAAM;AAAA,MACd,OAAOpB,EAAQ;AAAA,MACf,UAAWA,EAAkC;AAAA,IAAA,CAC9C,GAEDE,IAAS,OAAOc,IAAU,OAAU;AAClC,YAAMG,IAAMpB,EAAA;AACZ,YAAMY,EAASQ,EAAI,MAAMH,CAAO;AAAA,IAClC,GAEA,OAAO,iBAAiB,YAAY,MAAMd,EAAO,EAAI,CAAC,GAEtDC,IAAO,CAACrB,MAAiB6B,EAAS7B,GAAM,EAAK,GAC7CsB,IAAY,CAACtB,MAAiB6B,EAAS7B,GAAM,EAAI,GACjDuB,IAAO,MAAM,OAAO,QAAQ,KAAA;AAAA,EAC9B,OAAO;AAEL,IAAAN,IAAc,MAAM;AAClB,YAAMsB,IAAM,IAAI,IAAIvB,KAAc,KAAK,kBAAkB,GACnDhB,IAAOuC,EAAI,SAAS,QAAQxB,GAAM,EAAE,KAAK,KACzCyB,IAAQjE,EAAWgE,EAAI,MAAM,GAC7BH,IAAWG,EAAI,QAAQA,EAAI,KAAK,SAASA,EAAI,KAAK,MAAM,CAAC,IAAI;AACnE,aAAO,EAAE,MAAAvC,GAAM,OAAAwC,GAAO,UAAAJ,EAAA;AAAA,IACxB,GAEAlB,IAAUD,EAAA;AACV,UAAMqB,IAAQxC,EAAWC,GAAQmB,EAAQ,IAAI;AAC7C,IAAAC,IAAQsB,EAAwB;AAAA,MAC9B,MAAMvB,EAAQ;AAAA,MACd,QAAQoB,EAAM;AAAA,MACd,OAAOpB,EAAQ;AAAA,MACf,UAAWA,EAAkC;AAAA,IAAA,CAC9C,GAEDE,IAAS,YAAY;AACnB,YAAMiB,IAAMpB,EAAA;AACZ,YAAMyB,EAAYL,EAAI,IAAI;AAAA,IAC5B;AAYA,UAAMK,IAAc,OAAO1C,MAAiB;AAC1C,UAAI;AACF,cAAMmC,IAAYnC,EAAK,QAAQ,GAAG,GAC5BoC,IAAWD,KAAa,IAAInC,EAAK,MAAMmC,IAAY,CAAC,IAAI,IAExDE,IAAM;AAAA,UACV,OAFcF,KAAa,IAAInC,EAAK,MAAM,GAAGmC,CAAS,IAAInC,GAE5C,QAAQe,GAAM,EAAE,KAAK;AAAA,UACnC,OAAO,CAAA;AAAA,UACP,UAAAqB;AAAA,QAAA,GAEIE,IAAQxC,EAAWC,GAAQsC,EAAI,IAAI;AAIzC,YAAI,CAACC,EAAM,MAAO,OAAM,IAAI,MAAM,sBAAsBD,EAAI,IAAI,EAAE;AAElE,cAAMX,IAAOP,EAAM,SAAA,GACbM,IAAiB;AAAA,UACrB,MAAMY,EAAI;AAAA,UACV,QAAQC,EAAM;AAAA,UACd,OAAOD,EAAI;AAAA,UACX,UAAWA,EAA8B;AAAA,QAAA,GAIrCV,IAAUnB,EAAiBT,GAAQ0B,EAAG,IAAI;AAChD,YAAIE,GAAS,aAAa;AACxB,gBAAMC,IAAS,MAAMD,EAAQ,YAAYF,GAAIC,CAAI;AACjD,cAAI,OAAOE,KAAW,UAAU;AAE9B,kBAAMc,EAAYd,CAAM;AACxB;AAAA,UACF;AACA,cAAIA,MAAW,GAAO;AAAA,QACxB;AAGA,YAAID,GAAS,SAAS;AACpB,gBAAMC,IAAS,MAAMD,EAAQ,QAAQF,GAAIC,CAAI;AAC7C,cAAI,OAAOE,KAAW,UAAU;AAC9B,kBAAMc,EAAYd,CAAM;AACxB;AAAA,UACF;AACA,cAAIA,MAAW,GAAO;AAAA,QACxB;AAEA,QAAAT,EAAM,SAASM,CAAE,GAGbE,GAAS,cACXA,EAAQ,WAAWF,GAAIC,CAAI;AAAA,MAE/B,SAASI,GAAK;AAGZ,cAAAC,EAAS,yBAAyBD,CAAG,GAC/BA;AAAA,MACR;AAAA,IACF;AAEA,IAAAT,IAAO,OAAOrB,MAAiB0C,EAAY1C,CAAI,GAC/CsB,IAAY,OAAOtB,MAAiB0C,EAAY1C,CAAI,GACpDuB,IAAO,MAAM;AAAA,IAAC;AAAA,EAChB;AAEA,SAAO;AAAA,IACL,OAAAJ;AAAA,IACA,MAAAE;AAAA,IACA,SAASC;AAAA,IACT,MAAAC;AAAA,IACA,WAAWJ,EAAM;AAAA,IACjB,YAAY,CAACnB,MAAiBF,EAAWC,GAAQC,CAAI;AAAA,IACrD,YAAY,MAAkBmB,EAAM,SAAA;AAAA,IACpC,uBAAAR;AAAA,EAAA;AAEJ;AAGO,SAASgC,GAAc5C,GAAiBC,GAAc;AAC3D,SAAOF,EAAWC,GAAQC,CAAI;AAChC;AAKA,IAAI4C,IAAoD;AASjD,SAASC,GAAW/B,GAAsB;AAC/C,QAAMgC,IAASjC,EAAUC,CAAM;AAK/B,SAAA8B,IAAeE,GAEfC,EAAU,eAAe,YAAY;AAGnC,UAAMtC,IAAImC,KAAgBE;AAE1B,QAAI,CAACrC,EAAG,QAAOuC;AAEf,UAAMC,IAAUC,EAAIzC,EAAE,WAAA,CAAY;AAKlC,QAAI0C;AAEJ,IAAAC,EAAe,MAAM;AACnB,UAAI;AACF,QAAI3C,KAAK,OAAOA,EAAE,aAAc,eAC9B0C,IAAkB1C,EAAE,UAAU,CAAC4C,MAAM;AACnC,cAAI;AACF,YAAAJ,EAAQ,QAAQI;AAAA,UAClB,SAASxD,GAAG;AACV,YAAAN,EAAQ,0CAA0CM,CAAC;AAAA,UACrD;AAAA,QACF,CAAC;AAAA,MAEL,SAASA,GAAG;AACV,QAAAN,EAAQ,gCAAgCM,CAAC;AAAA,MAC3C;AAAA,IACF,CAAC,GAEDyD,EAAkB,MAAM;AACtB,UAAI,OAAOH,KAAoB;AAC7B,YAAI;AACF,UAAAA,EAAA;AAAA,QACF,SAAStD,GAAG;AACV,UAAAN,EAAQ,kCAAkCM,CAAC;AAAA,QAC7C;AAAA,IAEJ,CAAC;AAED,UAAMyC,IAAQ7B,EAAE,WAAWwC,EAAQ,MAAM,IAAI;AAC7C,QAAI,CAACX,KAAS,CAACA,EAAM,MAAO,QAAOU;AAGnC,QAAI;AAEF,YAAMO,IADU,MAAM9C,EAAE,sBAAsB6B,EAAM,KAAK;AAOzD,UAAI,OAAOiB,KAAS;AAClB,eAAO,EAAE,KAAKA,GAAM,OAAO,CAAA,GAAI,UAAU,GAAC;AAI5C,UAAI,OAAOA,KAAS,YAAY;AAC9B,cAAMzE,IAAMyE,EAAA;AAEZ,gBADiBzE,aAAe,UAAUA,IAAM,QAAQ,QAAQA,CAAG,GACnD,KAAK,CAAC0E,MAChB,OAAOA,KAAiB,WACnB,EAAE,KAAKA,GAAc,OAAO,CAAA,GAAI,UAAU,GAAC,IAC7CA,CACR;AAAA,MACH;AAEA,aAAOR;AAAA,IACT,QAAQ;AACN,aAAOA;AAAA,IACT;AAAA,EACF,CAAC,GAEDD,EAAU,eAAe,MAAM;AAE7B,UAAMU,IAAQC,EAAmC;AAAA,MAC/C,IAAI;AAAA,MACJ,KAAK;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,MAClB,UAAU;AAAA,MACV,UAAU;AAAA;AAAA,MAEV,OAAO;AAAA,MACP,OAAO;AAAA,IAAA,CACR,GAIKjD,IAAImC,KAAgBE,GAEpBG,IAAUC,EAAIzC,EAAE,WAAA,CAAY;AAGlC,QAAIkD;AAIJ,IAAAC,EAAS,MAAM,iCAAiC;AAOhD,UAAMC,IAAeX,EAAKO,EAAM,SAAoB,EAAE,GAChDK,IAAeZ,EAAKO,EAAM,SAAoB,EAAE;AAEtD,IAAAL,EAAe,CAACW,MAAkB;AAChC,UAAI;AACF,QAAItD,KAAK,OAAOA,EAAE,aAAc,eAC9BkD,IAAkBlD,EAAE,UAAU,CAAC4C,MAAM;AACnC,cAAI;AACF,YAAAJ,EAAQ,QAAQI;AAAA,UAClB,SAASxD,GAAG;AACV,YAAAN,EAAQ,0CAA0CM,CAAC;AAAA,UACrD;AAAA,QACF,CAAC;AAAA,MAEL,SAASA,GAAG;AACV,QAAAN,EAAQ,gCAAgCM,CAAC;AAAA,MAC3C;AAIA,UAAI;AACF,cAAMmE,IAAQD,GAA6C;AAC3D,YAAIC,aAAgB,aAAa;AAC/B,gBAAMC,IAAKD,EAAK,aAAa,OAAO,GAC9BE,IAAKF,EAAK,aAAa,OAAO;AACpC,UAAIC,QAAiB,QAAQA,IACzBC,QAAiB,QAAQA,IAEzBD,MAAO,QAAMD,EAAK,gBAAgB,OAAO,GACzCE,MAAO,QAAMF,EAAK,gBAAgB,OAAO;AAAA,QAC/C;AAAA,MACF,SAASnE,GAAG;AACV,QAAAN,EAAQ,qCAAqCM,CAAC;AAAA,MAChD;AAAA,IACF,CAAC,GAEDyD,EAAkB,MAAM;AACtB,UAAI,OAAOK,KAAoB;AAC7B,YAAI;AACF,UAAAA,EAAA;AAAA,QACF,SAAS9D,GAAG;AACV,UAAAN,EAAQ,kCAAkCM,CAAC;AAAA,QAC7C;AAAA,IAEJ,CAAC;AAED,UAAMsE,IAAgBC,EAAS,MAAM;AAGnC,YAAMC,KAFaZ,EAAM,MAAiB,IAET,MAAM,GAAG,EAAE,CAAC;AAC7C,UAAI;AACF,eACE7E,EAAsBqE,EAAQ,MAAM,IAAI,MACxCrE,EAAsByF,CAAc;AAAA,MAExC,QAAQ;AACN,eAAOpB,EAAQ,MAAM,SAASoB;AAAA,MAChC;AAAA,IACF,CAAC,GAEKC,IAAWF,EAAS,MAAM;AAE9B,YAAMC,KADaZ,EAAM,MAAiB,IACT,MAAM,GAAG,EAAE,CAAC;AAC7C,UAAIA,EAAM,MAAO,QAAOU,EAAc;AACtC,UAAI;AACF,cAAMI,IAAM3F,EAAsBqE,EAAQ,MAAM,IAAI,GAC9CuB,IAAM5F,EAAsByF,CAAc;AAChD,eAAOE,EAAI,WAAWC,CAAG;AAAA,MAC3B,QAAQ;AACN,eACEvB,EAAQ,SACR,OAAOA,EAAQ,MAAM,QAAS,YAC9BA,EAAQ,MAAM,KAAK,WAAWoB,CAAc;AAAA,MAEhD;AAAA,IACF,CAAC,GAKKI,IAAcL,EAAS,MAAM;AAGjC,YAAMM,KADHb,KAAgBA,EAAa,SAAWJ,EAAM,SAAoB,IAChD,MAAM,KAAK,EAAE,OAAO,OAAO,GAC1CkB,IAA+B,CAAA;AACrC,iBAAWC,KAAKF,EAAM,CAAAC,EAAIC,CAAC,IAAI;AAC/B,aAAOD;AAAA,IACT,CAAC,GAEKE,IAAcT,EAAS,OAAO;AAAA,MAClC,GAAGK,EAAY;AAAA,MACf,CAAEhB,EAAM,eAA0B,QAAQ,GAAGa,EAAS;AAAA,MACtD,CAAEb,EAAM,oBAA+B,cAAc,GACnDU,EAAc;AAAA,IAAA,EAChB,GAIIW,IAAcV;AAAA,MAAS,MAC3B,OAAO,KAAKS,EAAY,KAAK,EAC1B,OAAO,CAACE,MAAMF,EAAY,MAAME,CAAC,CAAC,EAClC,KAAK,GAAG;AAAA,IAAA,GAGPC,IAAWZ,EAAS,MAAOX,EAAM,QAAmB,QAAQ,GAK5DwB,IAAmBb;AAAA,MAAS,MAChCD,EAAc,QAASV,EAAM,mBAA8B;AAAA,IAAA,GAEvDyB,IAAad,EAAS,MAAM,CAAC,CAACX,EAAM,QAAQ,GAC5C0B,IAAaf;AAAA,MACjB,MACE,CAAC,CAACX,EAAM,aACNA,EAAM,QAAmB,OAAO,CAAEA,EAAM;AAAA,IAAA,GAIxC2B,IAAchB;AAAA,MAClB,MACGN,KAAgBA,EAAa,SAAWL,EAAM,SAAoB;AAAA,IAAA,GAGjE5B,IAAW,CAAChC,MAAkB;AAClC,UAAI4D,EAAM,UAAU;AAClB,QAAA5D,EAAE,eAAA;AACF;AAAA,MACF;AACA,MACE4D,EAAM,aACJA,EAAM,QAAmB,OAAO,CAAEA,EAAM,SAI5C5D,EAAE,eAAA,GACE4D,EAAM,UACRhD,EAAE,QAAQgD,EAAM,EAAY,IAE5BhD,EAAE,KAAKgD,EAAM,EAAY;AAAA,IAE7B;AAEA,WAAOT;AAAA,QACHV,IACC;AAAA,MACC0C,EAAS;AAAA,MACThC;AAAA;AAAA;AAAA,uBAGa8B,EAAY,KAAK;AAAA,uBACjBM,EAAY,SAAS,IAAI;AAAA,8BAClBH,EAAiB,KAAK;AAAA,0BAC1BC,EAAW,QAAQ,KAAK,IAAI;AAAA,+BACvBA,EAAW,QAAQ,SAAS,IAAI;AAAA,0BACrCA,EAAW,QAAQ,OAAO,IAAI;AAAA,wBAChCrD,CAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA,EAMvB,UAAUmB;AAAA;AAAA;AAAA,oBAGCS,EAAM,EAAE;AAAA,qBACPqB,EAAY,KAAK;AAAA,qBACjBM,EAAY,SAAS,IAAI;AAAA,4BAClBH,EAAiB,KAAK;AAAA,6BACrBC,EAAW,QAAQ,SAAS,IAAI;AAAA,wBACrCA,EAAW,QAAQ,OAAO,IAAI;AAAA,sBAChCC,EAAW,QAAQ,WAAW,IAAI;AAAA,mBACrCA,EAAW,QAAQ,wBAAwB,IAAI;AAAA,sBAC5CtD,CAAQ;AAAA;AAAA;AAAA,SAGrB,EACA,MAAM;AAAA;AAAA,EAEb,CAAC,GAEMiB;AACT;"}
package/dist/router.d.ts CHANGED
@@ -6,6 +6,7 @@ export interface RouteState {
6
6
  path: string;
7
7
  params: Record<string, string>;
8
8
  query: Record<string, string>;
9
+ fragment?: string;
9
10
  }
10
11
  export type GuardResult = boolean | string | Promise<boolean | string>;
11
12
  export interface Route {
@@ -63,6 +64,7 @@ export interface RouterConfig {
63
64
  initialUrl?: string;
64
65
  }
65
66
  export declare const parseQuery: (search: string) => Record<string, string>;
67
+ export declare function normalizePathForRoute(p: string): string;
66
68
  export declare const matchRoute: (routes: Route[], path: string) => {
67
69
  route: Route | null;
68
70
  params: Record<string, string>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jasonshimmy/custom-elements-runtime",
3
3
  "description": "A powerful, modern, and lightweight runtime for creating reactive web components with TypeScript",
4
- "version": "2.3.1",
4
+ "version": "2.4.0",
5
5
  "type": "module",
6
6
  "keywords": [
7
7
  "web-components",