@devwareng/vanilla-ts 1.2.118 → 1.2.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var pe=Object.create;var L=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var Te=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},Z=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of he(e))!Se.call(n,o)&&o!==t&&L(n,o,{get:()=>e[o],enumerable:!(r=fe(e,o))||r.enumerable});return n};var p=(n,e,t)=>(t=n!=null?pe(ge(n)):{},Z(e||!n||!n.__esModule?L(t,"default",{value:n,enumerable:!0}):t,n)),ye=n=>Z(L({},"__esModule",{value:!0}),n);var we={};Te(we,{TSRouter:()=>x,createEffect:()=>G,createSignal:()=>Q,html:()=>R,loadPyFiles:()=>J,renderChildRoutes:()=>j,useAnchorSingle:()=>q,useInitialDOM:()=>k,useTSAnchorMount:()=>V,useTSAuth:()=>U,useTSCollection:()=>N,useTSComponent:()=>y,useTSElementEach:()=>E,useTSElements:()=>$,useTSEvent:()=>b,useTSEventAll:()=>z,useTSExtractParams:()=>O,useTSLazy:()=>Y,useTSMetaData:()=>F,useTSNavigate:()=>B,useTSOutlet:()=>W,useTSParams:()=>T,useTSPurifier:()=>H,useTSSelect:()=>_,useTSloadBrython:()=>X});module.exports=ye(we);function R(n,...e){return n.reduce((t,r,o)=>t+r+(e[o]||""),"")}function w(){let n=new Set;document.querySelectorAll("*").forEach(e=>{let t=e.tagName.toLowerCase();t.includes("-")&&n.add(t)}),n.forEach(e=>{customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=`<div style="padding:10px;background:#eee;">${e} (Auto)</div>`}})})}var C=p(require("dompurify"),1),H=(n,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof n=="string"?C.default.sanitize(n,r):C.default.sanitize(n.innerHTML,r)};var b=(n,e,t)=>{if(typeof n=="string"){let r=document.getElementById(n);r?r.addEventListener(e,t):console.warn(`Element with id '${n}' not found.`)}else n===document?document.addEventListener(e,t):console.warn("Invalid id parameter provided.")};var ee=require("zustand/vanilla"),D=p(require("dompurify"),1);function Ee(n,e){let t=[],r=n.replace(/:[^/]+/g,a=>(t.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&t.forEach((a,l)=>{i[a]=D.default.sanitize(s[l+1]??"")}),i}function ve(n){let e={},t=new URLSearchParams(n);for(let[r,o]of t.entries())e[r]=D.default.sanitize(o);return e}var T=(0,ee.createStore)((n,e)=>({params:{},query:{},setFromPattern:t=>{let r=window.location.pathname,o=Ee(t,r),s=ve(window.location.search);n({params:o,query:s})},getParam:t=>e().params[t],getQuery:t=>e().query[t]}));function O(n){let e=T.getState();e.setFromPattern(n);let t=e.params,r=e.query;return{...t,...r}}var z=(n,e,t)=>{let r=document.querySelectorAll(n);return r.forEach(o=>{o.addEventListener(e,t)}),()=>{r.forEach(o=>{o.removeEventListener(e,t)})}};var M=p(require("dompurify"),1),$=(n,e,t)=>{let r={USE_PROFILES:{svg:!0,html:!0},ALLOWED_TAGS:["svg","path","circle","rect","line","polyline","polygon","g","main","div","h1","h2","h3","h4","h5","h6","p","button","span","a","img","input","ul","li","i"],ALLOWED_ATTR:["class","id","href","src","alt","fill","stroke","stroke-width","viewBox","xmlns","d","x","y","cx","cy","r","width","height"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...t};M.default.addHook("uponSanitizeElement",(s,i)=>{let a=i.tagName.toLowerCase();a.includes("-")&&(i.allowedTags[a]=!0)}),M.default.addHook("uponSanitizeAttribute",(s,i)=>{i.attrName&&i.attrName.toLowerCase().startsWith("on")&&(i.keepAttr=!1)});let o=M.default.sanitize(e,r);n.innerHTML!==o&&(n.innerHTML=o)};var te=p(require("dompurify"),1),P=null,k=(n,e)=>{if(typeof document>"u")return;let t=document.getElementById(n);if(!t)return;let r=t.innerHTML,o=te.default.sanitize(r);if(P!==null&&o!==P){let s=document.createElement("div");e(s),t.innerHTML=P}else P=o,e(t)};var I=p(require("dompurify"),1);typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",n=>{let e=n.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var q=(n,e,t,r="",o=null)=>{if(!n)return;let s=I.default.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=I.default.sanitize(t,{USE_PROFILES:{html:!1}});n.setAttribute("href",s),n.setAttribute("aria-label",i),r&&(n.className=r.trim()),o&&n.replaceChildren(o),typeof window<"u"&&n.addEventListener("click",a=>{a.preventDefault();let d=a.currentTarget.getAttribute("href");if(d){let u=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:u},"",d),dispatchEvent(new PopStateEvent("popstate"))}})};var g=p(require("dompurify"),1);var ne=(n="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",t="'none'",r="'self' https://fonts.googleapis.com https://fonts.gstatic.com",o="'self' https://blogger.googleusercontent.com",s=["'self'","https://fonts.googleapis.com","https://fonts.gstatic.com","https://www.google.com/maps/"],i="'self' https://www.youtube.com",a="'self'",l="/csp-report",d=!1)=>{let u=()=>{try{let c=document.querySelector('meta[http-equiv="Content-Security-Policy"]');c||(c=document.createElement("meta"),c.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(c));let f=d?`report-uri ${l};`:"";c.setAttribute("content",`default-src 'self'; script-src ${n}; style-src ${e}; object-src ${t}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${f}`)}catch(c){console.error("Error adding CSP meta element:",c)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u):u()};var F=(n,e)=>{let t={name:g.default.sanitize(n.name||""),description:g.default.sanitize(n.description||"Default description"),author:g.default.sanitize(n.author||"")},r=m=>{t.name=g.default.sanitize(m),c("name",t.name)},o=m=>{t.description=g.default.sanitize(m),c("description",t.description)},s=m=>{t.author=g.default.sanitize(m),c("author",t.author)},i=()=>t.name,a=()=>t.description,l=()=>t.author,d=()=>t,u=(m,v)=>{let S=document.createElement("meta");S.setAttribute("name",m),S.setAttribute("content",v),document.head.appendChild(S)},c=(m,v)=>{let S=document.querySelector(`meta[name="${m}"]`);S?S.setAttribute("content",v):u(m,v)},f=()=>{c("name",t.name),c("description",t.description),c("author",t.author)};return e&&ne(e.scriptSrc,e.styleSrc,e.objectSrc,Array.isArray(e.connectSrc)?e.connectSrc.join(" "):e.connectSrc,e.reportOnly!==void 0?String(e.reportOnly):void 0),f(),{setName:r,setDescription:o,setAuthor:s,getName:i,getDescription:a,getAuthor:l,getAllMetaData:d,appendMetaTagsToHead:f}};var re=p(require("dompurify"),1),y=(n,e,t,r,o)=>{let s=`#${n}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${n}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${n}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=re.default.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),t(a,r,o)};var N=(n,e,t,r=[])=>{let o=new Set;n.forEach((s,i)=>{if(o.has(s)){console.warn(`[useTSCollection] Duplicate ID in collection array: "${s}" \u2014 skipping.`);return}o.add(s);let a=e.querySelectorAll(`#${s}`);if(a.length>1){console.warn(`[useTSCollection] Duplicate ID in DOM: "${s}" (${a.length} elements found) \u2014 skipping component mount.`);return}let l=t[i],d=Array.isArray(r)?r[i]:void 0;typeof l=="function"?y(s,e,l,d):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var _=n=>{let e=document.querySelectorAll(n);if(e.length===0)return console.warn(`[useTSSelect] No element found for selector: '${n}'`),null;if(n.startsWith("#")&&e.length>1)throw new Error(`[useTSSelect] Duplicate ID detected: '${n}'. Found ${e.length} elements with this ID.`);return e.length>1&&console.warn(`[useTSSelect] Multiple elements found for selector: '${n}'. Returning the first one.`),e[0]};var oe=require("jwt-decode"),U=(n,e)=>{let t=localStorage.getItem("token");if(!t)return window.location.href=e,null;try{let r=(0,oe.jwtDecode)(t),o=Date.now()/1e3;return r.exp&&r.exp<o&&(console.error("Token has expired"),window.localStorage.removeItem("token"),window.location.href=e),null}catch(r){return console.error("Invalid token:",r),window.location.href=e,null}};var E=(n,e,t)=>{n.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{t(r,s)})})})};var B=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var W=(n,e)=>{let t=document.querySelector(`#${n}`)||document.querySelector(`.${n}`);if(!t)return;let r=window.location.pathname.replace(/\/$/,"");for(let o of e){let s=o.path.replace(/\/$/,"");if(r===s||r.startsWith(`${s}/`)){o.component(t);break}}};function j(n,e){let t=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(t===s||t.startsWith(`${s}/`)){let i=n.querySelector(`#${o.outlet}`)||n.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}var se=require("zustand/vanilla");function Q(n){let e=(0,se.createStore)(()=>({value:n})),t=new Set;return{get:()=>e.getState().value,set:r=>{e.setState({value:r}),t.forEach(o=>o(r))},subscribe:r=>(t.add(r),r(e.getState().value),()=>t.delete(r))}}function G(n){let e=n();typeof e=="function"&&e()}var ie=()=>{let n=document.querySelectorAll('a[href^="#"]');E(n,["click"],(e,t)=>{t.preventDefault();let r=e.getAttribute("href")?.substring(1),o=r?document.getElementById(r):null;o&&o.scrollIntoView({behavior:"smooth",block:"start"})})};var ae=require("lodash-es"),A=n=>n;typeof window<"u"&&typeof document<"u"&&(A=n=>{let e=document.createElement("div");return e.innerText=n,e.innerHTML});var Le=(0,ae.debounce)(n=>{(n?Array.isArray(n)?n:n instanceof HTMLAnchorElement?[n]:Array.from(n):Array.from(document.querySelectorAll("a"))).forEach(t=>{if(!t||t.dataset.anchorEnhanced==="true")return;t.dataset.anchorEnhanced="true";let r=t.getAttribute("href")||"#",o=A(r);t.setAttribute("href",o);let s=t.getAttribute("class")||"";t.setAttribute("class",A(s));let i=t.getAttribute("aria-label");i&&t.setAttribute("aria-label",A(i));let a=t.querySelector(":scope > *");a&&(t.innerHTML="",t.appendChild(a));let l=t.getAttribute("href")||"";if(!l.startsWith("#")){try{if(new URL(l,window.location.href).origin!==window.location.origin)return}catch{return}t.addEventListener("click",d=>{d.preventDefault();try{let u=new URL(l,window.location.href);window.history.pushState({},"",u.pathname+u.search+u.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(u){console.error("Invalid URL in anchor:",l,u)}})}})},50),ce=n=>{Le(n)};var le=()=>{let n=document.querySelectorAll("a");return ce(n)};var V=()=>{le(),ie()};var X=async()=>{let n="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",t=r=>new Promise((o,s)=>{let i=document.createElement("script");i.src=r,i.onload=()=>o(),i.onerror=()=>s(new Error(`Failed to load ${r}`)),document.head.appendChild(i)});await t(n),await t(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},J=n=>new Promise((e,t)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${n}`,r.onload=()=>e(),r.onerror=()=>t(new Error(`Failed to load ${n}`)),document.body.appendChild(r)});function Y(n,e){let t=null,r=null;async function o(){t||(r||(r=n().then(i=>{t=i.default})),await r)}let s=function(i,a){if(!(i instanceof HTMLElement)){if(typeof window>"u")return typeof t=="function"&&t.length===0?t(i):"";console.warn("useTSLazy: Expected HTMLElement as first arg, got",i);return}let l=i,d=a;if(typeof window>"u"||typeof document>"u")return;let u=document.createElement("div");u.setAttribute("data-lazy-placeholder",""),l.appendChild(u);try{e?.(u)}catch(c){console.error("useLazy placeholder render failed",c)}o().then(()=>{if(t){try{u.remove()}catch{}try{if(t.length>=1)t(l,d);else{let c=t(d);l.innerHTML=c}}catch(c){console.error("useLazy loaded component render failed",c)}}}).catch(c=>{console.error("useLazy loader failed",c);try{u.textContent="Failed to load component."}catch{}})};return s.preload=async()=>{await o()},s}var K=p(require("dompurify"),1);var de=require("zustand/vanilla"),me=p(require("dompurify"),1),h=(0,de.createStore)(n=>({params:{},query:{},setParams:e=>n(()=>({params:ue(e)})),setQuery:e=>n(()=>({query:ue(e)}))}));function ue(n){let e={};for(let t in n)e[t]=me.default.sanitize(n[t]);return e}var x=class{constructor(e,t){this.routes=[];this.routes=e,this.expectedParams=new Set(t),window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,t=window.location.search,r=this.parseQueryParams(t),o=this.findMatchingRoute(e,this.routes);if(o){if(o.routeto){this.navigate(o.routeto);return}let s=this.filterAndSanitizeParams(o.params);h.getState().setParams(s),h.getState().setQuery(r);let i=document.createElement("div");if(o.element?.(i,s,r),o.children){let a=e.slice(o.path.length),l=i.querySelector("#child");l&&this.renderChildren(o.children,a,l,s,r)}}else{let s=this.findMatchingRoute("*",this.routes);if(s){let i=this.filterAndSanitizeParams(s.params);h.getState().setParams(i),h.getState().setQuery(r);let a=document.createElement("div");s.element?.(a,i,r)}}}renderChildren(e,t,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(t,e);if(i){let a=document.createElement("div");a.id="child";let l={...o,...i.params},d=this.filterAndSanitizeParams(l);if(h.getState().setParams(d),h.getState().setQuery(s),i.element?.(a,d,s),r.appendChild(a),i.children){let u=t.slice(i.path.length);this.renderChildren(i.children,u,a,d,s)}}}parseQueryParams(e){let t={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(t[o]=K.default.sanitize(s));return t}findMatchingRoute(e,t,r={}){for(let o of t){let s=o.path;if(s==="*")return o;{let a=[],l=s.replace(/:[^\s/]+/g,c=>(a.push(c.substring(1)),"([^\\s/]+)")),d=new RegExp(`^${l}(?:/|$)`),u=e.match(d);if(u){let c={...r};if(a.forEach((f,m)=>{c[f]=u[m+1]??""}),o.children){let f=e.slice(u[0].length),m=this.findMatchingRoute(f,o.children,c);if(m)return m}return{...o,params:c}}}}}filterAndSanitizeParams(e){if(!e)return{};let t={};for(let r in e)this.expectedParams.has(r)&&(t[r]=K.default.sanitize(e[r]??""));return t}navigate(e){history.pushState(null,"",e),this.handlePopState()}addRoute(e){this.routes.push(e)}};typeof window<"u"&&(window.addEventListener("popstate",()=>{w()}),document.addEventListener("DOMContentLoaded",w));0&&(module.exports={TSRouter,createEffect,createSignal,html,loadPyFiles,renderChildRoutes,useAnchorSingle,useInitialDOM,useTSAnchorMount,useTSAuth,useTSCollection,useTSComponent,useTSElementEach,useTSElements,useTSEvent,useTSEventAll,useTSExtractParams,useTSLazy,useTSMetaData,useTSNavigate,useTSOutlet,useTSParams,useTSPurifier,useTSSelect,useTSloadBrython});
1
+ "use strict";var pe=Object.create;var L=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var he=Object.getOwnPropertyNames;var ge=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var Te=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},Z=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of he(e))!Se.call(n,o)&&o!==t&&L(n,o,{get:()=>e[o],enumerable:!(r=fe(e,o))||r.enumerable});return n};var p=(n,e,t)=>(t=n!=null?pe(ge(n)):{},Z(e||!n||!n.__esModule?L(t,"default",{value:n,enumerable:!0}):t,n)),Ee=n=>Z(L({},"__esModule",{value:!0}),n);var we={};Te(we,{TSRouter:()=>x,createEffect:()=>G,createSignal:()=>Q,html:()=>R,loadPyFiles:()=>V,renderChildRoutes:()=>W,useAnchorSingle:()=>q,useInitialDOM:()=>k,useTSAnchorMount:()=>X,useTSAuth:()=>U,useTSCollection:()=>N,useTSComponent:()=>E,useTSElementEach:()=>y,useTSElements:()=>z,useTSEvent:()=>H,useTSEventAll:()=>$,useTSExtractParams:()=>O,useTSLazy:()=>Y,useTSMetaData:()=>F,useTSNavigate:()=>B,useTSOutlet:()=>j,useTSParams:()=>T,useTSPurifier:()=>b,useTSSelect:()=>_,useTSloadBrython:()=>J});module.exports=Ee(we);function R(n,...e){return n.reduce((t,r,o)=>t+r+(e[o]||""),"")}function w(){let n=new Set;document.querySelectorAll("*").forEach(e=>{let t=e.tagName.toLowerCase();t.includes("-")&&n.add(t)}),n.forEach(e=>{customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=`<div style="padding:10px;background:#eee;">${e} (Auto)</div>`}})})}var C=p(require("dompurify"),1),b=(n,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof n=="string"?C.default.sanitize(n,r):C.default.sanitize(n.innerHTML,r)};var H=(n,e,t)=>{if(typeof n=="string"){let r=document.getElementById(n);r?r.addEventListener(e,t):console.warn(`Element with id '${n}' not found.`)}else n===document?document.addEventListener(e,t):console.warn("Invalid id parameter provided.")};var ee=require("zustand/vanilla"),D=p(require("dompurify"),1);function ye(n,e){let t=[],r=n.replace(/:[^/]+/g,a=>(t.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&t.forEach((a,c)=>{i[a]=D.default.sanitize(s[c+1]??"")}),i}function ve(n){let e={},t=new URLSearchParams(n);for(let[r,o]of t.entries())e[r]=D.default.sanitize(o);return e}var T=(0,ee.createStore)((n,e)=>({params:{},query:{},setFromPattern:t=>{let r=window.location.pathname,o=ye(t,r),s=ve(window.location.search);n({params:o,query:s})},getParam:t=>e().params[t],getQuery:t=>e().query[t]}));function O(n){let e=T.getState();e.setFromPattern(n);let t=e.params,r=e.query;return{...t,...r}}var $=(n,e,t)=>{let r=document.querySelectorAll(n);return r.forEach(o=>{o.addEventListener(e,t)}),()=>{r.forEach(o=>{o.removeEventListener(e,t)})}};var M=p(require("dompurify"),1),z=(n,e,t)=>{let r={USE_PROFILES:{svg:!0,html:!0},ALLOWED_TAGS:["svg","path","circle","rect","line","polyline","polygon","g","main","div","h1","h2","h3","h4","h5","h6","p","button","span","a","img","input","ul","li","i"],ALLOWED_ATTR:["class","id","href","src","alt","fill","stroke","stroke-width","viewBox","xmlns","d","x","y","cx","cy","r","width","height"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...t};M.default.addHook("uponSanitizeElement",(s,i)=>{let a=i.tagName.toLowerCase();a.includes("-")&&(i.allowedTags[a]=!0)}),M.default.addHook("uponSanitizeAttribute",(s,i)=>{i.attrName&&i.attrName.toLowerCase().startsWith("on")&&(i.keepAttr=!1)});let o=M.default.sanitize(e,r);n.innerHTML!==o&&(n.innerHTML=o)};var te=p(require("dompurify"),1),P=null,k=(n,e)=>{if(typeof document>"u")return;let t=document.getElementById(n);if(!t)return;let r=t.innerHTML,o=te.default.sanitize(r);if(P!==null&&o!==P){let s=document.createElement("div");e(s),t.innerHTML=P}else P=o,e(t)};var I=p(require("dompurify"),1);typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",n=>{let e=n.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var q=(n,e,t,r="",o=null)=>{if(!n)return;let s=I.default.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=I.default.sanitize(t,{USE_PROFILES:{html:!1}});n.setAttribute("href",s),n.setAttribute("aria-label",i),r&&(n.className=r.trim()),o&&n.replaceChildren(o),typeof window<"u"&&n.addEventListener("click",a=>{a.preventDefault();let d=a.currentTarget.getAttribute("href");if(d){let u=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:u},"",d),dispatchEvent(new PopStateEvent("popstate"))}})};var g=p(require("dompurify"),1);var ne=(n="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",t="'none'",r="'self' https://fonts.googleapis.com https://fonts.gstatic.com",o="'self' https://blogger.googleusercontent.com",s=["'self'","https://fonts.googleapis.com","https://fonts.gstatic.com","https://www.google.com/maps/"],i="'self' https://www.youtube.com",a="'self'",c="/csp-report",d=!1)=>{let u=()=>{try{let l=document.querySelector('meta[http-equiv="Content-Security-Policy"]');l||(l=document.createElement("meta"),l.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(l));let f=d?`report-uri ${c};`:"";l.setAttribute("content",`default-src 'self'; script-src ${n}; style-src ${e}; object-src ${t}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${f}`)}catch(l){console.error("Error adding CSP meta element:",l)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u):u()};var F=(n,e)=>{let t={name:g.default.sanitize(n.name||""),description:g.default.sanitize(n.description||"Default description"),author:g.default.sanitize(n.author||"")},r=m=>{t.name=g.default.sanitize(m),l("name",t.name)},o=m=>{t.description=g.default.sanitize(m),l("description",t.description)},s=m=>{t.author=g.default.sanitize(m),l("author",t.author)},i=()=>t.name,a=()=>t.description,c=()=>t.author,d=()=>t,u=(m,v)=>{let S=document.createElement("meta");S.setAttribute("name",m),S.setAttribute("content",v),document.head.appendChild(S)},l=(m,v)=>{let S=document.querySelector(`meta[name="${m}"]`);S?S.setAttribute("content",v):u(m,v)},f=()=>{l("name",t.name),l("description",t.description),l("author",t.author)};return e&&ne(e.scriptSrc,e.styleSrc,e.objectSrc,Array.isArray(e.connectSrc)?e.connectSrc.join(" "):e.connectSrc,e.reportOnly!==void 0?String(e.reportOnly):void 0),f(),{setName:r,setDescription:o,setAuthor:s,getName:i,getDescription:a,getAuthor:c,getAllMetaData:d,appendMetaTagsToHead:f}};var re=p(require("dompurify"),1),E=(n,e,t,r,o)=>{let s=`#${n}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${n}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${n}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=re.default.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),t(a,r,o)};var N=(n,e,t,r=[])=>{let o=new Set;n.forEach((s,i)=>{if(o.has(s)){console.warn(`[useTSCollection] Duplicate ID in collection array: "${s}" \u2014 skipping.`);return}o.add(s);let a=e.querySelectorAll(`#${s}`);if(a.length>1){console.warn(`[useTSCollection] Duplicate ID in DOM: "${s}" (${a.length} elements found) \u2014 skipping component mount.`);return}let c=t[i],d=Array.isArray(r)?r[i]:void 0;typeof c=="function"?E(s,e,c,d):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var _=n=>{let e=document.querySelectorAll(n);if(e.length===0)return console.warn(`[useTSSelect] No element found for selector: '${n}'`),null;if(n.startsWith("#")&&e.length>1)throw new Error(`[useTSSelect] Duplicate ID detected: '${n}'. Found ${e.length} elements with this ID.`);return e.length>1&&console.warn(`[useTSSelect] Multiple elements found for selector: '${n}'. Returning the first one.`),e[0]};var oe=require("jwt-decode"),U=(n,e)=>{let t=localStorage.getItem("token");if(!t)return window.location.href=e,null;try{let r=(0,oe.jwtDecode)(t),o=Date.now()/1e3;return r.exp&&r.exp<o&&(console.error("Token has expired"),window.localStorage.removeItem("token"),window.location.href=e),null}catch(r){return console.error("Invalid token:",r),window.location.href=e,null}};var y=(n,e,t)=>{n.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{t(r,s)})})})};var B=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var j=(n,e)=>{let t=document.querySelector(`#${n}`)||document.querySelector(`.${n}`);if(!t)return;let r=window.location.pathname.replace(/\/$/,"");for(let o of e){let s=o.path.replace(/\/$/,"");if(r===s||r.startsWith(`${s}/`)){o.component(t);break}}};function W(n,e){let t=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(t===s||t.startsWith(`${s}/`)){let i=n.querySelector(`#${o.outlet}`)||n.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}var se=require("zustand/vanilla");function Q(n){let e=(0,se.createStore)(()=>({value:n})),t=new Set;return{get:()=>e.getState().value,set:r=>{e.setState({value:r}),t.forEach(o=>o(r))},subscribe:r=>(t.add(r),r(e.getState().value),()=>t.delete(r))}}function G(n){let e=n();typeof e=="function"&&e()}var ie=()=>{let n=document.querySelectorAll('a[href^="#"]');y(n,["click"],(e,t)=>{t.preventDefault();let r=e.getAttribute("href")?.substring(1),o=r?document.getElementById(r):null;o&&o.scrollIntoView({behavior:"smooth",block:"start"})})};var ae=require("lodash-es"),A=n=>n;typeof window<"u"&&typeof document<"u"&&(A=n=>{let e=document.createElement("div");return e.innerText=n,e.innerHTML});var Le=(0,ae.debounce)(n=>{(n?Array.isArray(n)?n:n instanceof HTMLAnchorElement?[n]:Array.from(n):Array.from(document.querySelectorAll("a"))).forEach(t=>{if(!t||t.dataset.anchorEnhanced==="true")return;t.dataset.anchorEnhanced="true";let r=t.getAttribute("href")||"#",o=A(r);t.setAttribute("href",o);let s=t.getAttribute("class")||"";t.setAttribute("class",A(s));let i=t.getAttribute("aria-label");i&&t.setAttribute("aria-label",A(i));let a=t.querySelector(":scope > *");a&&(t.innerHTML="",t.appendChild(a));let c=t.getAttribute("href")||"";if(!c.startsWith("#")){try{if(new URL(c,window.location.href).origin!==window.location.origin)return}catch{return}t.addEventListener("click",d=>{d.preventDefault();try{let u=new URL(c,window.location.href);window.history.pushState({},"",u.pathname+u.search+u.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(u){console.error("Invalid URL in anchor:",c,u)}})}})},50),ce=n=>{Le(n)};var le=()=>{let n=document.querySelectorAll("a");return ce(n)};var X=()=>{le(),ie()};var J=async()=>{let n="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",t=r=>new Promise((o,s)=>{let i=document.createElement("script");i.src=r,i.onload=()=>o(),i.onerror=()=>s(new Error(`Failed to load ${r}`)),document.head.appendChild(i)});await t(n),await t(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},V=n=>new Promise((e,t)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${n}`,r.onload=()=>e(),r.onerror=()=>t(new Error(`Failed to load ${n}`)),document.body.appendChild(r)});function Y(n){let e=null;return async(t,r)=>{try{if(!e){let o=await n();e=o.default||o}if(typeof e=="function")return e(t,r);if(e instanceof HTMLElement){t.appendChild(e);return}if(e&&typeof e.render=="function")return e.render(t,r);console.warn("useTSLazy: Unsupported module type",e)}catch(o){console.error("useTSLazy failed:",o)}}}var K=p(require("dompurify"),1);var de=require("zustand/vanilla"),me=p(require("dompurify"),1),h=(0,de.createStore)(n=>({params:{},query:{},setParams:e=>n(()=>({params:ue(e)})),setQuery:e=>n(()=>({query:ue(e)}))}));function ue(n){let e={};for(let t in n)e[t]=me.default.sanitize(n[t]);return e}var x=class{constructor(e,t){this.routes=[];this.routes=e,this.expectedParams=new Set(t),window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,t=window.location.search,r=this.parseQueryParams(t),o=this.findMatchingRoute(e,this.routes);if(o){if(o.routeto){this.navigate(o.routeto);return}let s=this.filterAndSanitizeParams(o.params);h.getState().setParams(s),h.getState().setQuery(r);let i=document.createElement("div");if(o.element?.(i,s,r),o.children){let a=e.slice(o.path.length),c=i.querySelector("#child");c&&this.renderChildren(o.children,a,c,s,r)}}else{let s=this.findMatchingRoute("*",this.routes);if(s){let i=this.filterAndSanitizeParams(s.params);h.getState().setParams(i),h.getState().setQuery(r);let a=document.createElement("div");s.element?.(a,i,r)}}}renderChildren(e,t,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(t,e);if(i){let a=document.createElement("div");a.id="child";let c={...o,...i.params},d=this.filterAndSanitizeParams(c);if(h.getState().setParams(d),h.getState().setQuery(s),i.element?.(a,d,s),r.appendChild(a),i.children){let u=t.slice(i.path.length);this.renderChildren(i.children,u,a,d,s)}}}parseQueryParams(e){let t={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(t[o]=K.default.sanitize(s));return t}findMatchingRoute(e,t,r={}){for(let o of t){let s=o.path;if(s==="*")return o;{let a=[],c=s.replace(/:[^\s/]+/g,l=>(a.push(l.substring(1)),"([^\\s/]+)")),d=new RegExp(`^${c}(?:/|$)`),u=e.match(d);if(u){let l={...r};if(a.forEach((f,m)=>{l[f]=u[m+1]??""}),o.children){let f=e.slice(u[0].length),m=this.findMatchingRoute(f,o.children,l);if(m)return m}return{...o,params:l}}}}}filterAndSanitizeParams(e){if(!e)return{};let t={};for(let r in e)this.expectedParams.has(r)&&(t[r]=K.default.sanitize(e[r]??""));return t}navigate(e){history.pushState(null,"",e),this.handlePopState()}addRoute(e){this.routes.push(e)}};typeof window<"u"&&(window.addEventListener("popstate",()=>{w()}),document.addEventListener("DOMContentLoaded",w));0&&(module.exports={TSRouter,createEffect,createSignal,html,loadPyFiles,renderChildRoutes,useAnchorSingle,useInitialDOM,useTSAnchorMount,useTSAuth,useTSCollection,useTSComponent,useTSElementEach,useTSElements,useTSEvent,useTSEventAll,useTSExtractParams,useTSLazy,useTSMetaData,useTSNavigate,useTSOutlet,useTSParams,useTSPurifier,useTSSelect,useTSloadBrython});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.mts","../src/define/html.ts","../src/define/auto-register.ts","../src/hooks/useTSPurifier.ts","../src/hooks/useTSEvent.ts","../src/hooks/useTSParams.ts","../src/hooks/useTSExtract.ts","../src/hooks/useTSAllElements.ts","../src/hooks/useTSElements.ts","../src/hooks/useIntialDOM.ts","../src/hooks/useTSAnchorSingle.ts","../src/hooks/useTSMetaData.ts","../src/hooks/useTSCSP.ts","../src/hooks/useTSComponent.ts","../src/hooks/useTSCollection.ts","../src/hooks/useTSSelect.ts","../src/hooks/useTSAuth.ts","../src/hooks/useTSForEach.ts","../src/hooks/useTSNavigate.ts","../src/hooks/useTSOutlet.ts","../src/hooks/useReactivity.ts","../src/hooks/useTSHashAnchor.ts","../src/hooks/useTSAnchor.ts","../src/hooks/useTSNoReload.ts","../src/hooks/useTSAnchorMount.ts","../src/hooks/useTSInitializedBrython.ts","../src/hooks/useTSLazy.ts","../src/routes/class/Router.class.ts","../src/store/useTSParam.store.ts"],"sourcesContent":["import { autoRegister } from './src/define';\r\n\r\nexport { html } from './src/define';\r\nexport { createEffect, createSignal, renderChildRoutes, useTSLazy, useTSOutlet, useTSloadBrython, loadPyFiles, useTSNavigate, useTSMetaData, useTSSelect, useTSCollection, useTSComponent, useTSAuth, useTSElementEach, useInitialDOM, useAnchorSingle, useTSPurifier, useTSEvent, useTSExtractParams, useTSParams, useTSEventAll, useTSElements, useTSAnchorMount } from \"./src/hooks\"\r\nexport { TSRouter } from \"./src/routes/class/Router.class\";\r\n\r\nif (typeof window !== 'undefined') {\r\n window.addEventListener('popstate', () => {\r\n autoRegister();\r\n });\r\n document.addEventListener('DOMContentLoaded', autoRegister);\r\n}\r\n\r\n","export function html(strings: TemplateStringsArray, ...values: any[]): string {\r\n return strings.reduce((result, str, i) => {\r\n return result + str + (values[i] || '');\r\n }, '');\r\n}","// auto-register-runtime.ts\r\nfunction autoRegister() {\r\n const allTags = new Set<string>();\r\n document.querySelectorAll('*').forEach((el) => {\r\n const tagName = el.tagName.toLowerCase();\r\n if (!tagName.includes('-')) return; // Only register custom tags with a dash\r\n allTags.add(tagName);\r\n });\r\n\r\n allTags.forEach(tag => {\r\n if (!customElements.get(tag)) {\r\n customElements.define(tag, class extends HTMLElement {\r\n connectedCallback() {\r\n this.innerHTML = `<div style=\"padding:10px;background:#eee;\">${tag} (Auto)</div>`;\r\n }\r\n });\r\n }\r\n });\r\n}\r\n\r\n\r\nexport { autoRegister };","import DOMPurify from \"dompurify\";\r\nimport type { Config } from \"dompurify\";\r\n\r\ntype TSPurifier = (input: string | HTMLElement, config?: Config) => string;\r\n\r\nexport const useTSPurifier: TSPurifier = (\r\n input,\r\n config?\r\n) => {\r\n const defaultConfig: Config = {\r\n ADD_TAGS: [\"my-custom-tag\"],\r\n };\r\n\r\n const mergedConfig: Config = { ...defaultConfig, ...config };\r\n\r\n if (typeof input === \"string\") {\r\n return DOMPurify.sanitize(input, mergedConfig);\r\n } else {\r\n return DOMPurify.sanitize(input.innerHTML, mergedConfig);\r\n }\r\n};\r\n","type TSEvent = (\r\n id: string | Document,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: HTMLElementEventMap[keyof HTMLElementEventMap]) => void\r\n) => void;\r\n\r\nexport const useTSEvent: TSEvent = (\r\n id,\r\n eventType,\r\n handler\r\n) => {\r\n if (typeof id === 'string') {\r\n const element = document.getElementById(id);\r\n if (element) {\r\n element.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Element with id '${id}' not found.`);\r\n }\r\n } else if (id === document) {\r\n document.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Invalid id parameter provided.`);\r\n }\r\n};\r\n","// utils/hooks/useTSParams.ts\r\nimport { createStore } from 'zustand/vanilla';\r\nimport DOMPurify from 'dompurify';\r\n\r\ntype ParamStore = {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setFromPattern: (pattern: MustURL) => void;\r\n getParam: (key: string) => string | undefined;\r\n getQuery: (key: string) => string | undefined;\r\n};\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nfunction extractPatternParams(pattern: MustURL, path: string): Record<string, string> {\r\n const paramNames: string[] = [];\r\n const regexPattern = pattern.replace(/:[^/]+/g, (match) => {\r\n paramNames.push(match.slice(1));\r\n return '([^/]+)';\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}$`);\r\n const match = path.match(regex);\r\n const result: Record<string, string> = {};\r\n\r\n if (match) {\r\n paramNames.forEach((name, i) => {\r\n result[name] = DOMPurify.sanitize(match[i + 1] ?? '');\r\n });\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction extractQueryParams(search: MustURL): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n result[key] = DOMPurify.sanitize(value);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport const useTSParams = createStore<ParamStore>((set, get) => ({\r\n params: {},\r\n query: {},\r\n setFromPattern: (pattern: MustURL) => {\r\n const path = window.location.pathname;\r\n const params = extractPatternParams(pattern, path);\r\n const query = extractQueryParams(window.location.search as MustURL);\r\n set({ params, query });\r\n },\r\n getParam: (key: string) => get().params[key],\r\n getQuery: (key: string) => get().query[key],\r\n}));\r\n","import { useTSParams } from './useTSParams';\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nexport function useTSExtractParams(pattern: MustURL) {\r\n const store = useTSParams.getState();\r\n\r\n // Populate internal param/query store\r\n store.setFromPattern(pattern);\r\n\r\n const params = store.params;\r\n const query = store.query;\r\n\r\n return { ...params, ...query };\r\n}\r\n","export const useTSEventAll = <T extends Event>(\r\n selector: string,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n\r\n return () => {\r\n elements.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n };\r\n};\r\n\r\nexport const useTSEventSelectAll = <T extends Event>(\r\n selectors: string[],\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements: NodeListOf<HTMLElement>[] = [];\r\n\r\n selectors.forEach(selector => {\r\n const selectedElements = document.querySelectorAll(\r\n selector\r\n ) as NodeListOf<HTMLElement>;\r\n selectedElements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n elements.push(selectedElements);\r\n });\r\n\r\n return () => {\r\n elements.forEach(nodeList => {\r\n nodeList.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n });\r\n };\r\n};\r\n","import DOMPurify, { Config } from \"dompurify\";\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (htmlElement, element, config) => {\r\n const defaultConfig: Config = {\r\n USE_PROFILES: { svg: true, html: true },\r\n ALLOWED_TAGS: [\r\n \"svg\", \"path\", \"circle\", \"rect\", \"line\", \"polyline\", \"polygon\", \"g\",\r\n \"main\", \"div\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"p\", \"button\", \"span\", \"a\", \"img\", \"input\", \"ul\", \"li\", \"i\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"class\", \"id\", \"href\", \"src\", \"alt\", \"fill\", \"stroke\", \"stroke-width\",\r\n \"viewBox\", \"xmlns\", \"d\", \"x\", \"y\", \"cx\", \"cy\", \"r\", \"width\", \"height\"\r\n ],\r\n FORBID_TAGS: [\"script\", \"iframe\"],\r\n ALLOWED_URI_REGEXP:\r\n /^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\r\n ...config,\r\n };\r\n\r\n // ✅ Allow custom elements dynamically\r\n DOMPurify.addHook(\"uponSanitizeElement\", (node, data) => {\r\n const tagName = data.tagName.toLowerCase();\r\n if (tagName.includes(\"-\")) {\r\n data.allowedTags[tagName] = true;\r\n }\r\n });\r\n\r\n // ✅ Strip dangerous event handlers\r\n DOMPurify.addHook(\"uponSanitizeAttribute\", (node, data) => {\r\n if (data.attrName && data.attrName.toLowerCase().startsWith(\"on\")) {\r\n data.keepAttr = false;\r\n }\r\n });\r\n\r\n const sanitizedContent = DOMPurify.sanitize(element, defaultConfig);\r\n\r\n if (htmlElement.innerHTML !== sanitizedContent) {\r\n htmlElement.innerHTML = sanitizedContent;\r\n }\r\n};\r\n\r\n","import DOMPurify from \"dompurify\"\r\n\r\nlet previousHTML: string | null = null\r\n\r\ntype TSInitialDOM = (id: string, mount: (el: HTMLElement) => void) => void;\r\n\r\nexport const useInitialDOM: TSInitialDOM = (id, mount) => {\r\n // SSR guard\r\n if (typeof document === \"undefined\") return\r\n\r\n const targetElement = document.getElementById(id)\r\n if (!targetElement) return\r\n\r\n const currentHTML = targetElement.innerHTML\r\n const sanitizedHTML = DOMPurify.sanitize(currentHTML)\r\n\r\n if (previousHTML !== null && sanitizedHTML !== previousHTML) {\r\n // DOM changed externally — reset and remount in a temp container\r\n const fallbackEl = document.createElement(\"div\")\r\n mount(fallbackEl)\r\n targetElement.innerHTML = previousHTML\r\n } else {\r\n // First time or same sanitized DOM — mount to target\r\n previousHTML = sanitizedHTML\r\n mount(targetElement)\r\n }\r\n}\r\n","import DOMPurify from \"dompurify\";\r\n\r\ndeclare global {\r\n interface Window {\r\n __anchorSinglePopstateHandlerAttached?: boolean;\r\n }\r\n}\r\n\r\ntype AnchorSingle = (\r\n element: HTMLAnchorElement | null,\r\n href: string,\r\n ariaLabel: string,\r\n className?: string,\r\n childElement?: HTMLElement | null\r\n) => void;\r\n\r\n// Attach popstate listener only in the browser\r\nif (typeof window !== \"undefined\" && !window.__anchorSinglePopstateHandlerAttached) {\r\n window.addEventListener(\"popstate\", (e) => {\r\n const state = e.state as { scrollPosition?: number };\r\n if (state?.scrollPosition !== undefined) {\r\n window.scrollTo(0, state.scrollPosition);\r\n }\r\n });\r\n window.__anchorSinglePopstateHandlerAttached = true;\r\n}\r\n\r\nexport const useAnchorSingle: AnchorSingle = (\r\n element,\r\n href,\r\n ariaLabel,\r\n className = \"\",\r\n childElement = null\r\n) => {\r\n if (!element) return;\r\n\r\n // Sanitize string inputs\r\n const sanitizedHref = DOMPurify.sanitize(href, { ALLOWED_URI_REGEXP: /^(https?:|\\/)/ });\r\n const sanitizedAriaLabel = DOMPurify.sanitize(ariaLabel, { USE_PROFILES: { html: false } });\r\n\r\n element.setAttribute(\"href\", sanitizedHref);\r\n element.setAttribute(\"aria-label\", sanitizedAriaLabel);\r\n\r\n if (className) {\r\n element.className = className.trim();\r\n }\r\n\r\n if (childElement) {\r\n element.replaceChildren(childElement);\r\n }\r\n\r\n // Event binding only in browser\r\n if (typeof window !== \"undefined\") {\r\n element.addEventListener(\"click\", (e) => {\r\n e.preventDefault();\r\n const target = e.currentTarget as HTMLAnchorElement;\r\n const hrefAttr = target.getAttribute(\"href\");\r\n if (hrefAttr) {\r\n const scrollPosition = window.scrollY;\r\n window.scrollTo(0, 0);\r\n window.history.pushState({ scrollPosition }, \"\", hrefAttr);\r\n dispatchEvent(new PopStateEvent(\"popstate\"));\r\n }\r\n });\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\nimport { useTSCSP } from \"./useTSCSP\";\r\n\r\ntype SEOConfig = {\r\n name?: string;\r\n description?: string;\r\n author?: string;\r\n}\r\n\r\ntype CSPConfig = {\r\n scriptSrc?: string;\r\n styleSrc?: string;\r\n objectSrc?: string;\r\n connectSrc?: string[];\r\n reportOnly?: boolean;\r\n}\r\n\r\ntype SEOHandler = {\r\n setName: (name: string) => void;\r\n setDescription: (description: string) => void;\r\n setAuthor: (author: string) => void;\r\n getName: () => string;\r\n getDescription: () => string;\r\n getAuthor: () => string;\r\n getAllMetaData: () => SEOConfig;\r\n appendMetaTagsToHead: () => void;\r\n}\r\n\r\nexport const useTSMetaData = (\r\n config: SEOConfig,\r\n cspConfig?: CSPConfig\r\n): SEOHandler => {\r\n let metaData: SEOConfig = {\r\n name: DOMPurify.sanitize(config.name || \"\"),\r\n description: DOMPurify.sanitize(\r\n config.description || \"Default description\"\r\n ),\r\n author: DOMPurify.sanitize(config.author || \"\"),\r\n };\r\n\r\n const setName = (name: string): void => {\r\n metaData.name = DOMPurify.sanitize(name);\r\n updateMetaTag(\"name\", metaData.name);\r\n };\r\n\r\n const setDescription = (description: string): void => {\r\n metaData.description = DOMPurify.sanitize(description);\r\n updateMetaTag(\"description\", metaData.description);\r\n };\r\n\r\n const setAuthor = (author: string): void => {\r\n metaData.author = DOMPurify.sanitize(author);\r\n updateMetaTag(\"author\", metaData.author);\r\n };\r\n\r\n const getName = (): string => {\r\n return metaData.name!;\r\n };\r\n\r\n const getDescription = (): string => {\r\n return metaData.description!;\r\n };\r\n\r\n const getAuthor = (): string => {\r\n return metaData.author!;\r\n };\r\n\r\n const getAllMetaData = (): SEOConfig => {\r\n return metaData;\r\n };\r\n\r\n const createMetaTag = (name: string, content: string) => {\r\n const metaTag = document.createElement(\"meta\");\r\n metaTag.setAttribute(\"name\", name);\r\n metaTag.setAttribute(\"content\", content);\r\n document.head.appendChild(metaTag);\r\n };\r\n\r\n const updateMetaTag = (name: string, content: string) => {\r\n let metaTag = document.querySelector(`meta[name=\"${name}\"]`);\r\n if (metaTag) {\r\n metaTag.setAttribute(\"content\", content);\r\n } else {\r\n createMetaTag(name, content);\r\n }\r\n };\r\n\r\n const appendMetaTagsToHead = () => {\r\n updateMetaTag(\"name\", metaData.name!);\r\n updateMetaTag(\"description\", metaData.description!);\r\n updateMetaTag(\"author\", metaData.author!);\r\n };\r\n\r\n // Integrate with useTSCSP for CSP enforcement\r\n if (cspConfig) {\r\n useTSCSP(\r\n cspConfig.scriptSrc,\r\n cspConfig.styleSrc,\r\n cspConfig.objectSrc,\r\n Array.isArray(cspConfig.connectSrc) ? cspConfig.connectSrc.join(\" \") : cspConfig.connectSrc,\r\n cspConfig.reportOnly !== undefined ? String(cspConfig.reportOnly) : undefined\r\n );\r\n }\r\n\r\n appendMetaTagsToHead();\r\n\r\n return {\r\n setName,\r\n setDescription,\r\n setAuthor,\r\n getName,\r\n getDescription,\r\n getAuthor,\r\n getAllMetaData,\r\n appendMetaTagsToHead,\r\n };\r\n};\r\n","export const useTSCSP = (\r\n scriptSrc = `'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'`,\r\n styleSrc = \"'self' 'nonce-rAnd0m123'\", // Use nonce for inline styles\r\n objectSrc = \"'none'\",\r\n fontSrc = \"'self' https://fonts.googleapis.com https://fonts.gstatic.com\",\r\n imgSrc = \"'self' https://blogger.googleusercontent.com\",\r\n connectSrc = [\r\n \"'self'\",\r\n \"https://fonts.googleapis.com\",\r\n \"https://fonts.gstatic.com\",\r\n \"https://www.google.com/maps/\",\r\n ],\r\n frameSrc = \"'self' https://www.youtube.com\", // Add frame-src for embedding\r\n baseUri = \"'self'\",\r\n reportUri = \"/csp-report\",\r\n reportOnly = false\r\n) => {\r\n const addOrUpdateCSPMeta = () => {\r\n try {\r\n let metaElement = document.querySelector(\r\n 'meta[http-equiv=\"Content-Security-Policy\"]'\r\n );\r\n if (!metaElement) {\r\n metaElement = document.createElement(\"meta\");\r\n metaElement.setAttribute(\"http-equiv\", \"Content-Security-Policy\");\r\n document.head.appendChild(metaElement);\r\n }\r\n\r\n const reportUriDirective = reportOnly ? `report-uri ${reportUri};` : \"\";\r\n metaElement.setAttribute(\r\n \"content\",\r\n `default-src 'self'; script-src ${scriptSrc}; style-src ${styleSrc}; object-src ${objectSrc}; font-src ${fontSrc}; img-src ${imgSrc}; connect-src ${connectSrc.join(\r\n \" \"\r\n )}; frame-src ${frameSrc}; base-uri ${baseUri}; ${reportUriDirective}`\r\n );\r\n } catch (error) {\r\n console.error(\"Error adding CSP meta element:\", error);\r\n }\r\n };\r\n\r\n if (document.readyState === \"loading\") {\r\n document.addEventListener(\"DOMContentLoaded\", addOrUpdateCSPMeta);\r\n } else {\r\n addOrUpdateCSPMeta();\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\n\r\ntype TSComponent = (\r\n id: string,\r\n parent: HTMLElement,\r\n element: Function,\r\n params?: any,\r\n params2?: any\r\n) => void;\r\n\r\nexport const useTSComponent: TSComponent = (\r\n id,\r\n parent,\r\n element,\r\n params,\r\n params2\r\n) => {\r\n const selector = `#${id}`;\r\n const matches = parent.querySelectorAll<HTMLElement>(selector);\r\n\r\n // 1. Missing element check\r\n if (matches.length === 0) {\r\n throw new Error(`[useTSComponent] No element found with id '${id}' in the given parent.`);\r\n }\r\n\r\n // 2. Duplicate ID check\r\n if (matches.length > 1) {\r\n throw new Error(`[useTSComponent] Duplicate id '${id}' detected. Found ${matches.length} elements.`);\r\n }\r\n\r\n const target = matches[0];\r\n\r\n // 3. Sanitize the target’s existing HTML content\r\n target.innerHTML = DOMPurify.sanitize(target.innerHTML, { USE_PROFILES: { html: true } });\r\n\r\n // 4. Call the component function with the target\r\n element(target, params, params2);\r\n};\r\n","import { useTSComponent } from \"./useTSComponent\";\r\n\r\ntype TSCollection = (\r\n collections: string[],\r\n DOM: HTMLElement,\r\n elements: Function[],\r\n params?: any[]\r\n) => void;\r\n\r\nexport const useTSCollection: TSCollection = (\r\n collections,\r\n DOM,\r\n elements,\r\n params = []\r\n) => {\r\n const seenIds = new Set<string>();\r\n\r\n collections.forEach((id, index) => {\r\n // Check for duplicate IDs in the collection list itself\r\n if (seenIds.has(id)) {\r\n console.warn(`[useTSCollection] Duplicate ID in collection array: \"${id}\" — skipping.`);\r\n return;\r\n }\r\n seenIds.add(id);\r\n\r\n // Check for duplicates already in DOM\r\n const matches = DOM.querySelectorAll(`#${id}`);\r\n if (matches.length > 1) {\r\n console.warn(\r\n `[useTSCollection] Duplicate ID in DOM: \"${id}\" (${matches.length} elements found) — skipping component mount.`\r\n );\r\n return;\r\n }\r\n\r\n const elementFn = elements[index];\r\n const param = Array.isArray(params) ? params[index] : undefined;\r\n\r\n if (typeof elementFn === \"function\") {\r\n useTSComponent(id, DOM, elementFn, param);\r\n } else {\r\n console.warn(`[useTSCollection] No valid component function found for ID: \"${id}\"`);\r\n }\r\n });\r\n};\r\n","type TSSelect = <T extends Element = HTMLElement>(selector: string) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(selector: string): T | null => {\r\n const elements = document.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n throw new Error(\r\n `[useTSSelect] Duplicate ID detected: '${selector}'. Found ${elements.length} elements with this ID.`\r\n );\r\n }\r\n\r\n if (elements.length > 1) {\r\n console.warn(\r\n `[useTSSelect] Multiple elements found for selector: '${selector}'. Returning the first one.`\r\n );\r\n }\r\n\r\n return elements[0];\r\n};\r\n\r\nexport { useTSSelect };\r\n","import { jwtDecode } from \"jwt-decode\";\r\n\r\nexport const useTSAuth = (_Component: HTMLElement | void, loginUrl: string) => {\r\n const token = localStorage.getItem(\"token\");\r\n\r\n if (!token) {\r\n // Redirect to login page if token is missing\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n try {\r\n const decodedToken: any = jwtDecode(token);\r\n\r\n // Example: Check if the token has expired\r\n const currentTime = Date.now() / 1000;\r\n if (decodedToken.exp && decodedToken.exp < currentTime) {\r\n console.error(\"Token has expired\");\r\n window.localStorage.removeItem(\"token\");\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n // If the user is authenticated, return the component\r\n return null;\r\n } catch (error) {\r\n console.error(\"Invalid token:\", error);\r\n // Redirect to login page if token decoding fails\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n};\r\n","\r\ntype TSElementEach = (\r\n elements: NodeListOf<HTMLElement> | HTMLElement[],\r\n events: (keyof HTMLElementEventMap)[],\r\n callback: (element: HTMLElement, event: Event) => void\r\n) => void;\r\n\r\nexport const useTSElementEach: TSElementEach = (\r\n elements,\r\n events,\r\n callback\r\n) => {\r\n elements.forEach(element => {\r\n events.forEach(eventType => {\r\n element.addEventListener(eventType, event => {\r\n callback(element, event);\r\n });\r\n });\r\n });\r\n};\r\n","export const useTSNavigate = () => {\r\n const back = () => window.history.back();\r\n const forward = () => window.history.forward();\r\n\r\n return {\r\n back,\r\n forward,\r\n };\r\n};\r\n","// types.ts\r\nexport type OutletComponent = (DOM: HTMLElement) => void;\r\n\r\nexport type ChildRoute = {\r\n path: string;\r\n outlet: string;\r\n element: OutletComponent;\r\n};\r\n\r\nexport type Route = {\r\n path: string;\r\n element: (DOM: HTMLElement) => void;\r\n children?: ChildRoute[];\r\n};\r\n\r\n// You don't actually need to import the class TSRouter type.\r\n// Instead, export a cleaner interface with routes.\r\nexport interface RouterInstance {\r\n routes: Route[];\r\n}\r\n\r\n\r\ntype OutletOptions = {\r\n path: string;\r\n component: OutletComponent;\r\n};\r\n\r\nexport const useTSOutlet = (\r\n selector: string,\r\n outlets: OutletOptions[]\r\n): void => {\r\n const outletDOM = document.querySelector<HTMLElement>(`#${selector}`)\r\n || document.querySelector<HTMLElement>(`.${selector}`);\r\n\r\n if (!outletDOM) return;\r\n\r\n const currentPath = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n for (const outlet of outlets) {\r\n const base = outlet.path.replace(/\\/$/, \"\");\r\n\r\n // Match exact or nested path (e.g., /openai/child/1)\r\n if (currentPath === base || currentPath.startsWith(`${base}/`)) {\r\n outlet.component(outletDOM);\r\n break;\r\n }\r\n }\r\n};\r\n\r\n\r\nexport function renderChildRoutes(DOM: HTMLElement, router: RouterInstance): void {\r\n const pathname = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n router.routes.forEach((route) => {\r\n if (!route.children?.length) return;\r\n\r\n route.children.forEach((child) => {\r\n const childPath = child.path.replace(/\\/$/, \"\");\r\n\r\n if (pathname === childPath || pathname.startsWith(`${childPath}/`)) {\r\n const outlet = DOM.querySelector(`#${child.outlet}`)\r\n || DOM.querySelector(`.${child.outlet}`);\r\n if (outlet instanceof HTMLElement && child.element) {\r\n child.element(outlet);\r\n }\r\n }\r\n });\r\n });\r\n}","// useTSReactivity.ts\r\nimport { createStore } from 'zustand/vanilla';\r\n\r\ntype Listener<T> = (value: T) => void;\r\n\r\ninterface Signal<T> {\r\n get: () => T;\r\n set: (newValue: T) => void;\r\n subscribe: (listener: Listener<T>) => () => void;\r\n}\r\n\r\nexport function createSignal<T>(initialValue: T): Signal<T> {\r\n const store = createStore<{ value: T }>(() => ({ value: initialValue }));\r\n const listeners = new Set<Listener<T>>();\r\n\r\n return {\r\n get: () => store.getState().value,\r\n set: (newValue: T) => {\r\n store.setState({ value: newValue });\r\n listeners.forEach((listener) => listener(newValue));\r\n },\r\n subscribe: (listener: Listener<T>) => {\r\n listeners.add(listener);\r\n listener(store.getState().value); // Trigger immediately\r\n return () => listeners.delete(listener);\r\n },\r\n };\r\n}\r\n\r\ntype CleanupFn = () => void;\r\n\r\nexport function createEffect(effectFn: () => void | CleanupFn): void {\r\n const cleanup = effectFn();\r\n\r\n // Optional: return a way to dispose the effect manually\r\n if (typeof cleanup === 'function') {\r\n // You may store this and call it later if needed\r\n cleanup();\r\n }\r\n}\r\n","import { useTSElementEach } from './useTSForEach';\r\n\r\n\r\nconst useTSHashAnchor = () => {\r\n const links = document.querySelectorAll<HTMLAnchorElement>('a[href^=\"#\"]');\r\n\r\n useTSElementEach(\r\n links,\r\n ['click'],\r\n (element, e) => {\r\n e.preventDefault();\r\n const targetId = element.getAttribute('href')?.substring(1);\r\n const targetElement = targetId ? document.getElementById(targetId) : null;\r\n\r\n if (targetElement) {\r\n targetElement.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'start'\r\n });\r\n }\r\n }\r\n );\r\n}\r\n\r\nexport { useTSHashAnchor }","import { debounce } from 'lodash-es';\r\n\r\nlet sanitizeInput = (input: string): string => input;\r\n\r\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\r\n sanitizeInput = (input: string): string => {\r\n const element = document.createElement(\"div\");\r\n element.innerText = input;\r\n return element.innerHTML;\r\n };\r\n}\r\n\r\ntype AnchorInput =\r\n | NodeListOf<HTMLAnchorElement>\r\n | HTMLAnchorElement[]\r\n | HTMLAnchorElement\r\n | null\r\n | undefined;\r\n\r\nconst _enhanceAnchors = debounce((anchors: AnchorInput) => {\r\n const resolvedAnchors: HTMLAnchorElement[] = (() => {\r\n if (!anchors) return Array.from(document.querySelectorAll(\"a\"));\r\n if (Array.isArray(anchors)) return anchors;\r\n if (anchors instanceof HTMLAnchorElement) return [anchors];\r\n return Array.from(anchors);\r\n })();\r\n\r\n resolvedAnchors.forEach(anchor => {\r\n if (!anchor || anchor.dataset.anchorEnhanced === 'true') return;\r\n anchor.dataset.anchorEnhanced = 'true';\r\n\r\n // Sanitize attributes\r\n const originalHref = anchor.getAttribute(\"href\") || \"#\";\r\n const sanitizedHref = sanitizeInput(originalHref);\r\n anchor.setAttribute(\"href\", sanitizedHref);\r\n\r\n const originalClassName = anchor.getAttribute(\"class\") || \"\";\r\n anchor.setAttribute(\"class\", sanitizeInput(originalClassName));\r\n\r\n const ariaLabel = anchor.getAttribute(\"aria-label\");\r\n if (ariaLabel) {\r\n anchor.setAttribute(\"aria-label\", sanitizeInput(ariaLabel));\r\n }\r\n\r\n // Keep child elements safe (optional — you can remove this block if not needed)\r\n const child = anchor.querySelector(\":scope > *\") as HTMLElement;\r\n if (child) {\r\n anchor.innerHTML = \"\";\r\n anchor.appendChild(child);\r\n }\r\n\r\n // Skip attaching click listener if:\r\n // - It's a hash link (in-page navigation)\r\n // - It's an external link\r\n const href = anchor.getAttribute(\"href\") || \"\";\r\n if (href.startsWith(\"#\")) return; // Let browser handle hash scrolling normally\r\n\r\n try {\r\n const url = new URL(href, window.location.href);\r\n if (url.origin !== window.location.origin) return; // external link\r\n } catch {\r\n return; // invalid URL — skip\r\n }\r\n\r\n // Intercept same-origin navigation for SPA\r\n anchor.addEventListener(\"click\", (e: MouseEvent) => {\r\n e.preventDefault();\r\n try {\r\n const url = new URL(href, window.location.href);\r\n window.history.pushState({}, \"\", url.pathname + url.search + url.hash);\r\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\r\n } catch (err) {\r\n console.error(\"Invalid URL in anchor:\", href, err);\r\n }\r\n });\r\n });\r\n}, 50);\r\n\r\nexport const useAnchor = (anchors?: AnchorInput): void => {\r\n _enhanceAnchors(anchors);\r\n};\r\n","import { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = () => {\r\n const a = document.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n return useAnchor(a);\r\n}\r\n\r\nexport { useTSNoReload };","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = () => {\r\n useTSNoReload();\r\n useTSHashAnchor();\r\n};\r\n\r\nexport { useTSAnchorMount };","// src/loadBrython.ts\r\ntype LoadBrython = (src: string) => Promise<void>;\r\n\r\ndeclare global {\r\n interface Window {\r\n brython: Function;\r\n }\r\n}\r\n\r\nconst useTSloadBrython = async () => {\r\n const brythonJS = \"https://cdn.jsdelivr.net/npm/brython@3/brython.min.js\";\r\n const brythonStdlib = \"https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js\";\r\n\r\n // Utility function to load a script\r\n const loadScript: LoadBrython = (src) => {\r\n return new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.src = src;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.head.appendChild(script);\r\n });\r\n };\r\n\r\n // Load both scripts sequentially\r\n await loadScript(brythonJS);\r\n await loadScript(brythonStdlib);\r\n\r\n // Call brython() after scripts are loaded\r\n if (typeof window.brython === \"function\") {\r\n window.brython();\r\n } else {\r\n console.error(\"Brython did not load correctly.\");\r\n }\r\n};\r\n\r\ntype RequirePy = `${string}.py`;\r\n\r\ntype LoadPy = (src: RequirePy) => Promise<void>;\r\n\r\nconst loadPyFiles: LoadPy = (src) =>\r\n new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.type = \"text/python\";\r\n script.src = `/src/python/${src}`;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.body.appendChild(script);\r\n });\r\n\r\nexport { useTSloadBrython, loadPyFiles };\r\n","// lazy code spitter\r\n\r\nexport type VComponent<P = any> = (mount: HTMLElement, props?: P) => any;\r\nexport type Loader<P = any> = () => Promise<{ default: VComponent<P> }>;\r\n\r\nexport interface LazyComponent<P = any> {\r\n (mount: HTMLElement, props?: P): void;\r\n preload?: () => Promise<void>;\r\n}\r\n\r\nexport function useTSLazy(loader: Loader, placeholder?: (mount: HTMLElement) => void): LazyComponent {\r\n let loaded: VComponent | null = null;\r\n let loadingPromise: Promise<void> | null = null;\r\n\r\n async function ensureLoaded() {\r\n if (loaded) return;\r\n if (!loadingPromise) {\r\n loadingPromise = loader().then((mod) => {\r\n loaded = mod.default;\r\n });\r\n }\r\n await loadingPromise;\r\n }\r\n\r\n const lazyFn = function (mountOrProps?: any, maybeProps?: any) {\r\n // Case 1: SSR or string-returning usage (no HTMLElement)\r\n if (!(mountOrProps instanceof HTMLElement)) {\r\n // we’re being called like LazyPillar(props)\r\n if (typeof window === \"undefined\") {\r\n // server-side: return string directly if loaded\r\n if (typeof loaded === \"function\" && loaded.length === 0) {\r\n return (loaded as (props?: any) => string)(mountOrProps);\r\n }\r\n return \"\";\r\n }\r\n console.warn(\"useTSLazy: Expected HTMLElement as first arg, got\", mountOrProps);\r\n return;\r\n }\r\n\r\n // Case 2: Normal DOM mounting\r\n const mount = mountOrProps as HTMLElement;\r\n const props = maybeProps;\r\n\r\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\r\n return;\r\n }\r\n\r\n const placeholderWrapper = document.createElement(\"div\");\r\n placeholderWrapper.setAttribute(\"data-lazy-placeholder\", \"\");\r\n mount.appendChild(placeholderWrapper);\r\n\r\n try {\r\n placeholder?.(placeholderWrapper);\r\n } catch (err) {\r\n console.error(\"useLazy placeholder render failed\", err);\r\n }\r\n\r\n ensureLoaded()\r\n .then(() => {\r\n if (!loaded) return;\r\n\r\n try {\r\n placeholderWrapper.remove();\r\n } catch { }\r\n\r\n try {\r\n if (loaded.length >= 1) {\r\n // (mount, props) style\r\n (loaded as (mount: HTMLElement, props?: any) => any)(mount, props);\r\n } else {\r\n // (props) => string style\r\n const html = (loaded as (props?: any) => string)(props);\r\n mount.innerHTML = html;\r\n }\r\n } catch (err) {\r\n console.error(\"useLazy loaded component render failed\", err);\r\n }\r\n })\r\n .catch((err) => {\r\n console.error(\"useLazy loader failed\", err);\r\n try {\r\n placeholderWrapper.textContent = \"Failed to load component.\";\r\n } catch { }\r\n });\r\n } as LazyComponent;\r\n\r\n lazyFn.preload = async () => {\r\n await ensureLoaded();\r\n };\r\n\r\n return lazyFn;\r\n}\r\n","import DOMPurify from \"dompurify\";\r\nimport { tsParamsStore } from \"../../store\";\r\n\r\ntype RouteCallback = (\r\n errorElement?: HTMLElement,\r\n params?: Record<string, string>,\r\n query?: Record<string, string>\r\n) => void;\r\n\r\ninterface RouteConfig {\r\n path: string;\r\n routeto?: string;\r\n element: RouteCallback;\r\n errorElement?: RouteCallback;\r\n children?: RouteConfig[];\r\n params?: Record<string, string>;\r\n}\r\n\r\nexport class TSRouter {\r\n private routes: RouteConfig[] = [];\r\n private expectedParams: Set<string>;\r\n\r\n constructor(routes: RouteConfig[], expectedParams: string[]) {\r\n this.routes = routes;\r\n this.expectedParams = new Set(expectedParams);\r\n window.addEventListener(\"popstate\", this.handlePopState.bind(this));\r\n this.handlePopState(); // Initial load\r\n }\r\n\r\n private handlePopState() {\r\n const currentPath = window.location.pathname;\r\n const currentSearch = window.location.search;\r\n const queryParams = this.parseQueryParams(currentSearch);\r\n\r\n const matchingRoute = this.findMatchingRoute(currentPath, this.routes);\r\n\r\n if (matchingRoute) {\r\n if (matchingRoute.routeto) {\r\n this.navigate(matchingRoute.routeto);\r\n return;\r\n }\r\n\r\n const sanitizedParams = this.filterAndSanitizeParams(matchingRoute.params);\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n\r\n matchingRoute.element?.(errorElement, sanitizedParams, queryParams);\r\n\r\n if (matchingRoute.children) {\r\n const nestedPath = currentPath.slice(matchingRoute.path.length);\r\n const childElement = errorElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) {\r\n this.renderChildren(\r\n matchingRoute.children,\r\n nestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n } else {\r\n const notFoundRoute = this.findMatchingRoute(\"*\", this.routes);\r\n if (notFoundRoute) {\r\n const fallbackParams = this.filterAndSanitizeParams(notFoundRoute.params);\r\n tsParamsStore.getState().setParams(fallbackParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n notFoundRoute.element?.(errorElement, fallbackParams, queryParams);\r\n }\r\n }\r\n }\r\n\r\n private renderChildren(\r\n children: RouteConfig[] | undefined,\r\n nestedPath: string,\r\n parentElement: HTMLElement,\r\n parentParams: Record<string, string>,\r\n queryParams: Record<string, string>\r\n ) {\r\n if (!children || children.length === 0) {\r\n const childElement = parentElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) childElement.remove();\r\n return;\r\n }\r\n\r\n const matchingChild = this.findMatchingRoute(nestedPath, children);\r\n if (matchingChild) {\r\n const childElement = document.createElement(\"div\");\r\n childElement.id = \"child\";\r\n const mergedParams = { ...parentParams, ...matchingChild.params };\r\n const sanitizedParams = this.filterAndSanitizeParams(mergedParams);\r\n\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n matchingChild.element?.(childElement, sanitizedParams, queryParams);\r\n parentElement.appendChild(childElement);\r\n\r\n if (matchingChild.children) {\r\n const nextNestedPath = nestedPath.slice(matchingChild.path.length);\r\n this.renderChildren(\r\n matchingChild.children,\r\n nextNestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n }\r\n\r\n private parseQueryParams(search: string): Record<string, string> {\r\n const queryParams: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n if (this.expectedParams.has(key)) {\r\n queryParams[key] = DOMPurify.sanitize(value);\r\n }\r\n }\r\n\r\n return queryParams;\r\n }\r\n\r\n private findMatchingRoute(\r\n path: string,\r\n routes: RouteConfig[],\r\n inheritedParams: Record<string, string> = {}\r\n ): RouteConfig | undefined {\r\n for (const route of routes) {\r\n const routePath = route.path;\r\n const isDefaultRoute = routePath === \"*\";\r\n\r\n if (!isDefaultRoute) {\r\n const paramNames: string[] = [];\r\n const regexPattern = routePath.replace(/:[^\\s/]+/g, match => {\r\n paramNames.push(match.substring(1));\r\n return \"([^\\\\s/]+)\";\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}(?:/|$)`);\r\n const match = path.match(regex);\r\n\r\n if (match) {\r\n const params: Record<string, string> = { ...inheritedParams };\r\n paramNames.forEach((name, index) => {\r\n params[name] = match[index + 1] ?? \"\";\r\n });\r\n\r\n if (route.children) {\r\n const nestedPath = path.slice(match[0].length);\r\n const matchingChild = this.findMatchingRoute(\r\n nestedPath,\r\n route.children,\r\n params\r\n );\r\n if (matchingChild) return matchingChild;\r\n }\r\n\r\n return { ...route, params };\r\n }\r\n } else {\r\n return route;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private filterAndSanitizeParams(\r\n params?: Record<string, string>\r\n ): Record<string, string> {\r\n if (!params) return {};\r\n const sanitizedParams: Record<string, string> = {};\r\n for (const key in params) {\r\n if (this.expectedParams.has(key)) {\r\n sanitizedParams[key] = DOMPurify.sanitize(params[key] ?? \"\");\r\n }\r\n }\r\n return sanitizedParams;\r\n }\r\n\r\n navigate(path: string) {\r\n history.pushState(null, \"\", path);\r\n this.handlePopState();\r\n }\r\n\r\n addRoute(route: RouteConfig) {\r\n this.routes.push(route);\r\n }\r\n}\r\n","import { createStore } from \"zustand/vanilla\";\r\nimport DOMPurify from \"dompurify\";\r\n\r\ninterface TSParamsState {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setParams: (params: Record<string, string>) => void;\r\n setQuery: (query: Record<string, string>) => void;\r\n}\r\n\r\nexport const tsParamsStore = createStore<TSParamsState>((set) => ({\r\n params: {},\r\n query: {},\r\n setParams: (params) =>\r\n set(() => ({\r\n params: sanitize(params),\r\n })),\r\n setQuery: (query) =>\r\n set(() => ({\r\n query: sanitize(query),\r\n })),\r\n}));\r\n\r\nfunction sanitize(obj: Record<string, string>): Record<string, string> {\r\n const output: Record<string, string> = {};\r\n for (const key in obj) {\r\n output[key] = DOMPurify.sanitize(obj[key]);\r\n }\r\n return output;\r\n}\r\n"],"mappings":"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","names":["index_exports","__export","TSRouter","createEffect","createSignal","html","loadPyFiles","renderChildRoutes","useAnchorSingle","useInitialDOM","useTSAnchorMount","useTSAuth","useTSCollection","useTSComponent","useTSElementEach","useTSElements","useTSEvent","useTSEventAll","useTSExtractParams","useTSLazy","useTSMetaData","useTSNavigate","useTSOutlet","useTSParams","useTSPurifier","useTSSelect","useTSloadBrython","__toCommonJS","html","strings","values","result","str","i","autoRegister","allTags","el","tagName","tag","import_dompurify","useTSPurifier","input","config","mergedConfig","DOMPurify","useTSEvent","id","eventType","handler","element","import_vanilla","import_dompurify","extractPatternParams","pattern","path","paramNames","regexPattern","match","regex","result","name","i","DOMPurify","extractQueryParams","search","urlSearchParams","key","value","useTSParams","set","get","params","query","useTSExtractParams","pattern","store","useTSParams","params","query","useTSEventAll","selector","eventType","handler","elements","element","import_dompurify","useTSElements","htmlElement","element","config","defaultConfig","DOMPurify","node","data","tagName","sanitizedContent","import_dompurify","previousHTML","useInitialDOM","id","mount","targetElement","currentHTML","sanitizedHTML","DOMPurify","fallbackEl","import_dompurify","e","state","useAnchorSingle","element","href","ariaLabel","className","childElement","sanitizedHref","DOMPurify","sanitizedAriaLabel","hrefAttr","scrollPosition","import_dompurify","useTSCSP","scriptSrc","styleSrc","objectSrc","fontSrc","imgSrc","connectSrc","frameSrc","baseUri","reportUri","reportOnly","addOrUpdateCSPMeta","metaElement","reportUriDirective","error","useTSMetaData","config","cspConfig","metaData","DOMPurify","setName","name","updateMetaTag","setDescription","description","setAuthor","author","getName","getDescription","getAuthor","getAllMetaData","createMetaTag","content","metaTag","appendMetaTagsToHead","useTSCSP","import_dompurify","useTSComponent","id","parent","element","params","params2","selector","matches","target","DOMPurify","useTSCollection","collections","DOM","elements","params","seenIds","id","index","matches","elementFn","param","useTSComponent","useTSSelect","selector","elements","import_jwt_decode","useTSAuth","_Component","loginUrl","token","decodedToken","currentTime","error","useTSElementEach","elements","events","callback","element","eventType","event","useTSNavigate","useTSOutlet","selector","outlets","outletDOM","currentPath","outlet","base","renderChildRoutes","DOM","router","pathname","route","child","childPath","import_vanilla","createSignal","initialValue","store","listeners","newValue","listener","createEffect","effectFn","cleanup","useTSHashAnchor","links","useTSElementEach","element","e","targetId","targetElement","import_lodash_es","sanitizeInput","input","element","_enhanceAnchors","anchors","anchor","originalHref","sanitizedHref","originalClassName","ariaLabel","child","href","e","url","err","useAnchor","useTSNoReload","a","useAnchor","useTSAnchorMount","useTSNoReload","useTSHashAnchor","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","loader","placeholder","loaded","loadingPromise","ensureLoaded","mod","lazyFn","mountOrProps","maybeProps","mount","props","placeholderWrapper","err","html","import_dompurify","import_vanilla","import_dompurify","tsParamsStore","set","params","sanitize","query","obj","output","key","DOMPurify","TSRouter","routes","expectedParams","currentPath","currentSearch","queryParams","matchingRoute","sanitizedParams","tsParamsStore","errorElement","nestedPath","childElement","notFoundRoute","fallbackParams","children","parentElement","parentParams","matchingChild","mergedParams","nextNestedPath","search","urlSearchParams","key","value","DOMPurify","path","inheritedParams","route","routePath","paramNames","regexPattern","match","regex","params","name","index","autoRegister"]}
1
+ {"version":3,"sources":["../index.mts","../src/define/html.ts","../src/define/auto-register.ts","../src/hooks/useTSPurifier.ts","../src/hooks/useTSEvent.ts","../src/hooks/useTSParams.ts","../src/hooks/useTSExtract.ts","../src/hooks/useTSAllElements.ts","../src/hooks/useTSElements.ts","../src/hooks/useIntialDOM.ts","../src/hooks/useTSAnchorSingle.ts","../src/hooks/useTSMetaData.ts","../src/hooks/useTSCSP.ts","../src/hooks/useTSComponent.ts","../src/hooks/useTSCollection.ts","../src/hooks/useTSSelect.ts","../src/hooks/useTSAuth.ts","../src/hooks/useTSForEach.ts","../src/hooks/useTSNavigate.ts","../src/hooks/useTSOutlet.ts","../src/hooks/useReactivity.ts","../src/hooks/useTSHashAnchor.ts","../src/hooks/useTSAnchor.ts","../src/hooks/useTSNoReload.ts","../src/hooks/useTSAnchorMount.ts","../src/hooks/useTSInitializedBrython.ts","../src/hooks/useTSLazy.ts","../src/routes/class/Router.class.ts","../src/store/useTSParam.store.ts"],"sourcesContent":["import { autoRegister } from './src/define';\r\n\r\nexport { html } from './src/define';\r\nexport { createEffect, createSignal, renderChildRoutes, useTSLazy, useTSOutlet, useTSloadBrython, loadPyFiles, useTSNavigate, useTSMetaData, useTSSelect, useTSCollection, useTSComponent, useTSAuth, useTSElementEach, useInitialDOM, useAnchorSingle, useTSPurifier, useTSEvent, useTSExtractParams, useTSParams, useTSEventAll, useTSElements, useTSAnchorMount } from \"./src/hooks\"\r\nexport { TSRouter } from \"./src/routes/class/Router.class\";\r\n\r\nif (typeof window !== 'undefined') {\r\n window.addEventListener('popstate', () => {\r\n autoRegister();\r\n });\r\n document.addEventListener('DOMContentLoaded', autoRegister);\r\n}\r\n\r\n","export function html(strings: TemplateStringsArray, ...values: any[]): string {\r\n return strings.reduce((result, str, i) => {\r\n return result + str + (values[i] || '');\r\n }, '');\r\n}","// auto-register-runtime.ts\r\nfunction autoRegister() {\r\n const allTags = new Set<string>();\r\n document.querySelectorAll('*').forEach((el) => {\r\n const tagName = el.tagName.toLowerCase();\r\n if (!tagName.includes('-')) return; // Only register custom tags with a dash\r\n allTags.add(tagName);\r\n });\r\n\r\n allTags.forEach(tag => {\r\n if (!customElements.get(tag)) {\r\n customElements.define(tag, class extends HTMLElement {\r\n connectedCallback() {\r\n this.innerHTML = `<div style=\"padding:10px;background:#eee;\">${tag} (Auto)</div>`;\r\n }\r\n });\r\n }\r\n });\r\n}\r\n\r\n\r\nexport { autoRegister };","import DOMPurify from \"dompurify\";\r\nimport type { Config } from \"dompurify\";\r\n\r\ntype TSPurifier = (input: string | HTMLElement, config?: Config) => string;\r\n\r\nexport const useTSPurifier: TSPurifier = (\r\n input,\r\n config?\r\n) => {\r\n const defaultConfig: Config = {\r\n ADD_TAGS: [\"my-custom-tag\"],\r\n };\r\n\r\n const mergedConfig: Config = { ...defaultConfig, ...config };\r\n\r\n if (typeof input === \"string\") {\r\n return DOMPurify.sanitize(input, mergedConfig);\r\n } else {\r\n return DOMPurify.sanitize(input.innerHTML, mergedConfig);\r\n }\r\n};\r\n","type TSEvent = (\r\n id: string | Document,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: HTMLElementEventMap[keyof HTMLElementEventMap]) => void\r\n) => void;\r\n\r\nexport const useTSEvent: TSEvent = (\r\n id,\r\n eventType,\r\n handler\r\n) => {\r\n if (typeof id === 'string') {\r\n const element = document.getElementById(id);\r\n if (element) {\r\n element.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Element with id '${id}' not found.`);\r\n }\r\n } else if (id === document) {\r\n document.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Invalid id parameter provided.`);\r\n }\r\n};\r\n","// utils/hooks/useTSParams.ts\r\nimport { createStore } from 'zustand/vanilla';\r\nimport DOMPurify from 'dompurify';\r\n\r\ntype ParamStore = {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setFromPattern: (pattern: MustURL) => void;\r\n getParam: (key: string) => string | undefined;\r\n getQuery: (key: string) => string | undefined;\r\n};\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nfunction extractPatternParams(pattern: MustURL, path: string): Record<string, string> {\r\n const paramNames: string[] = [];\r\n const regexPattern = pattern.replace(/:[^/]+/g, (match) => {\r\n paramNames.push(match.slice(1));\r\n return '([^/]+)';\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}$`);\r\n const match = path.match(regex);\r\n const result: Record<string, string> = {};\r\n\r\n if (match) {\r\n paramNames.forEach((name, i) => {\r\n result[name] = DOMPurify.sanitize(match[i + 1] ?? '');\r\n });\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction extractQueryParams(search: MustURL): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n result[key] = DOMPurify.sanitize(value);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport const useTSParams = createStore<ParamStore>((set, get) => ({\r\n params: {},\r\n query: {},\r\n setFromPattern: (pattern: MustURL) => {\r\n const path = window.location.pathname;\r\n const params = extractPatternParams(pattern, path);\r\n const query = extractQueryParams(window.location.search as MustURL);\r\n set({ params, query });\r\n },\r\n getParam: (key: string) => get().params[key],\r\n getQuery: (key: string) => get().query[key],\r\n}));\r\n","import { useTSParams } from './useTSParams';\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nexport function useTSExtractParams(pattern: MustURL) {\r\n const store = useTSParams.getState();\r\n\r\n // Populate internal param/query store\r\n store.setFromPattern(pattern);\r\n\r\n const params = store.params;\r\n const query = store.query;\r\n\r\n return { ...params, ...query };\r\n}\r\n","export const useTSEventAll = <T extends Event>(\r\n selector: string,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n\r\n return () => {\r\n elements.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n };\r\n};\r\n\r\nexport const useTSEventSelectAll = <T extends Event>(\r\n selectors: string[],\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements: NodeListOf<HTMLElement>[] = [];\r\n\r\n selectors.forEach(selector => {\r\n const selectedElements = document.querySelectorAll(\r\n selector\r\n ) as NodeListOf<HTMLElement>;\r\n selectedElements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n elements.push(selectedElements);\r\n });\r\n\r\n return () => {\r\n elements.forEach(nodeList => {\r\n nodeList.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n });\r\n };\r\n};\r\n","import DOMPurify, { Config } from \"dompurify\";\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (htmlElement, element, config) => {\r\n const defaultConfig: Config = {\r\n USE_PROFILES: { svg: true, html: true },\r\n ALLOWED_TAGS: [\r\n \"svg\", \"path\", \"circle\", \"rect\", \"line\", \"polyline\", \"polygon\", \"g\",\r\n \"main\", \"div\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"p\", \"button\", \"span\", \"a\", \"img\", \"input\", \"ul\", \"li\", \"i\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"class\", \"id\", \"href\", \"src\", \"alt\", \"fill\", \"stroke\", \"stroke-width\",\r\n \"viewBox\", \"xmlns\", \"d\", \"x\", \"y\", \"cx\", \"cy\", \"r\", \"width\", \"height\"\r\n ],\r\n FORBID_TAGS: [\"script\", \"iframe\"],\r\n ALLOWED_URI_REGEXP:\r\n /^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\r\n ...config,\r\n };\r\n\r\n // ✅ Allow custom elements dynamically\r\n DOMPurify.addHook(\"uponSanitizeElement\", (node, data) => {\r\n const tagName = data.tagName.toLowerCase();\r\n if (tagName.includes(\"-\")) {\r\n data.allowedTags[tagName] = true;\r\n }\r\n });\r\n\r\n // ✅ Strip dangerous event handlers\r\n DOMPurify.addHook(\"uponSanitizeAttribute\", (node, data) => {\r\n if (data.attrName && data.attrName.toLowerCase().startsWith(\"on\")) {\r\n data.keepAttr = false;\r\n }\r\n });\r\n\r\n const sanitizedContent = DOMPurify.sanitize(element, defaultConfig);\r\n\r\n if (htmlElement.innerHTML !== sanitizedContent) {\r\n htmlElement.innerHTML = sanitizedContent;\r\n }\r\n};\r\n\r\n","import DOMPurify from \"dompurify\"\r\n\r\nlet previousHTML: string | null = null\r\n\r\ntype TSInitialDOM = (id: string, mount: (el: HTMLElement) => void) => void;\r\n\r\nexport const useInitialDOM: TSInitialDOM = (id, mount) => {\r\n // SSR guard\r\n if (typeof document === \"undefined\") return\r\n\r\n const targetElement = document.getElementById(id)\r\n if (!targetElement) return\r\n\r\n const currentHTML = targetElement.innerHTML\r\n const sanitizedHTML = DOMPurify.sanitize(currentHTML)\r\n\r\n if (previousHTML !== null && sanitizedHTML !== previousHTML) {\r\n // DOM changed externally — reset and remount in a temp container\r\n const fallbackEl = document.createElement(\"div\")\r\n mount(fallbackEl)\r\n targetElement.innerHTML = previousHTML\r\n } else {\r\n // First time or same sanitized DOM — mount to target\r\n previousHTML = sanitizedHTML\r\n mount(targetElement)\r\n }\r\n}\r\n","import DOMPurify from \"dompurify\";\r\n\r\ndeclare global {\r\n interface Window {\r\n __anchorSinglePopstateHandlerAttached?: boolean;\r\n }\r\n}\r\n\r\ntype AnchorSingle = (\r\n element: HTMLAnchorElement | null,\r\n href: string,\r\n ariaLabel: string,\r\n className?: string,\r\n childElement?: HTMLElement | null\r\n) => void;\r\n\r\n// Attach popstate listener only in the browser\r\nif (typeof window !== \"undefined\" && !window.__anchorSinglePopstateHandlerAttached) {\r\n window.addEventListener(\"popstate\", (e) => {\r\n const state = e.state as { scrollPosition?: number };\r\n if (state?.scrollPosition !== undefined) {\r\n window.scrollTo(0, state.scrollPosition);\r\n }\r\n });\r\n window.__anchorSinglePopstateHandlerAttached = true;\r\n}\r\n\r\nexport const useAnchorSingle: AnchorSingle = (\r\n element,\r\n href,\r\n ariaLabel,\r\n className = \"\",\r\n childElement = null\r\n) => {\r\n if (!element) return;\r\n\r\n // Sanitize string inputs\r\n const sanitizedHref = DOMPurify.sanitize(href, { ALLOWED_URI_REGEXP: /^(https?:|\\/)/ });\r\n const sanitizedAriaLabel = DOMPurify.sanitize(ariaLabel, { USE_PROFILES: { html: false } });\r\n\r\n element.setAttribute(\"href\", sanitizedHref);\r\n element.setAttribute(\"aria-label\", sanitizedAriaLabel);\r\n\r\n if (className) {\r\n element.className = className.trim();\r\n }\r\n\r\n if (childElement) {\r\n element.replaceChildren(childElement);\r\n }\r\n\r\n // Event binding only in browser\r\n if (typeof window !== \"undefined\") {\r\n element.addEventListener(\"click\", (e) => {\r\n e.preventDefault();\r\n const target = e.currentTarget as HTMLAnchorElement;\r\n const hrefAttr = target.getAttribute(\"href\");\r\n if (hrefAttr) {\r\n const scrollPosition = window.scrollY;\r\n window.scrollTo(0, 0);\r\n window.history.pushState({ scrollPosition }, \"\", hrefAttr);\r\n dispatchEvent(new PopStateEvent(\"popstate\"));\r\n }\r\n });\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\nimport { useTSCSP } from \"./useTSCSP\";\r\n\r\ntype SEOConfig = {\r\n name?: string;\r\n description?: string;\r\n author?: string;\r\n}\r\n\r\ntype CSPConfig = {\r\n scriptSrc?: string;\r\n styleSrc?: string;\r\n objectSrc?: string;\r\n connectSrc?: string[];\r\n reportOnly?: boolean;\r\n}\r\n\r\ntype SEOHandler = {\r\n setName: (name: string) => void;\r\n setDescription: (description: string) => void;\r\n setAuthor: (author: string) => void;\r\n getName: () => string;\r\n getDescription: () => string;\r\n getAuthor: () => string;\r\n getAllMetaData: () => SEOConfig;\r\n appendMetaTagsToHead: () => void;\r\n}\r\n\r\nexport const useTSMetaData = (\r\n config: SEOConfig,\r\n cspConfig?: CSPConfig\r\n): SEOHandler => {\r\n let metaData: SEOConfig = {\r\n name: DOMPurify.sanitize(config.name || \"\"),\r\n description: DOMPurify.sanitize(\r\n config.description || \"Default description\"\r\n ),\r\n author: DOMPurify.sanitize(config.author || \"\"),\r\n };\r\n\r\n const setName = (name: string): void => {\r\n metaData.name = DOMPurify.sanitize(name);\r\n updateMetaTag(\"name\", metaData.name);\r\n };\r\n\r\n const setDescription = (description: string): void => {\r\n metaData.description = DOMPurify.sanitize(description);\r\n updateMetaTag(\"description\", metaData.description);\r\n };\r\n\r\n const setAuthor = (author: string): void => {\r\n metaData.author = DOMPurify.sanitize(author);\r\n updateMetaTag(\"author\", metaData.author);\r\n };\r\n\r\n const getName = (): string => {\r\n return metaData.name!;\r\n };\r\n\r\n const getDescription = (): string => {\r\n return metaData.description!;\r\n };\r\n\r\n const getAuthor = (): string => {\r\n return metaData.author!;\r\n };\r\n\r\n const getAllMetaData = (): SEOConfig => {\r\n return metaData;\r\n };\r\n\r\n const createMetaTag = (name: string, content: string) => {\r\n const metaTag = document.createElement(\"meta\");\r\n metaTag.setAttribute(\"name\", name);\r\n metaTag.setAttribute(\"content\", content);\r\n document.head.appendChild(metaTag);\r\n };\r\n\r\n const updateMetaTag = (name: string, content: string) => {\r\n let metaTag = document.querySelector(`meta[name=\"${name}\"]`);\r\n if (metaTag) {\r\n metaTag.setAttribute(\"content\", content);\r\n } else {\r\n createMetaTag(name, content);\r\n }\r\n };\r\n\r\n const appendMetaTagsToHead = () => {\r\n updateMetaTag(\"name\", metaData.name!);\r\n updateMetaTag(\"description\", metaData.description!);\r\n updateMetaTag(\"author\", metaData.author!);\r\n };\r\n\r\n // Integrate with useTSCSP for CSP enforcement\r\n if (cspConfig) {\r\n useTSCSP(\r\n cspConfig.scriptSrc,\r\n cspConfig.styleSrc,\r\n cspConfig.objectSrc,\r\n Array.isArray(cspConfig.connectSrc) ? cspConfig.connectSrc.join(\" \") : cspConfig.connectSrc,\r\n cspConfig.reportOnly !== undefined ? String(cspConfig.reportOnly) : undefined\r\n );\r\n }\r\n\r\n appendMetaTagsToHead();\r\n\r\n return {\r\n setName,\r\n setDescription,\r\n setAuthor,\r\n getName,\r\n getDescription,\r\n getAuthor,\r\n getAllMetaData,\r\n appendMetaTagsToHead,\r\n };\r\n};\r\n","export const useTSCSP = (\r\n scriptSrc = `'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'`,\r\n styleSrc = \"'self' 'nonce-rAnd0m123'\", // Use nonce for inline styles\r\n objectSrc = \"'none'\",\r\n fontSrc = \"'self' https://fonts.googleapis.com https://fonts.gstatic.com\",\r\n imgSrc = \"'self' https://blogger.googleusercontent.com\",\r\n connectSrc = [\r\n \"'self'\",\r\n \"https://fonts.googleapis.com\",\r\n \"https://fonts.gstatic.com\",\r\n \"https://www.google.com/maps/\",\r\n ],\r\n frameSrc = \"'self' https://www.youtube.com\", // Add frame-src for embedding\r\n baseUri = \"'self'\",\r\n reportUri = \"/csp-report\",\r\n reportOnly = false\r\n) => {\r\n const addOrUpdateCSPMeta = () => {\r\n try {\r\n let metaElement = document.querySelector(\r\n 'meta[http-equiv=\"Content-Security-Policy\"]'\r\n );\r\n if (!metaElement) {\r\n metaElement = document.createElement(\"meta\");\r\n metaElement.setAttribute(\"http-equiv\", \"Content-Security-Policy\");\r\n document.head.appendChild(metaElement);\r\n }\r\n\r\n const reportUriDirective = reportOnly ? `report-uri ${reportUri};` : \"\";\r\n metaElement.setAttribute(\r\n \"content\",\r\n `default-src 'self'; script-src ${scriptSrc}; style-src ${styleSrc}; object-src ${objectSrc}; font-src ${fontSrc}; img-src ${imgSrc}; connect-src ${connectSrc.join(\r\n \" \"\r\n )}; frame-src ${frameSrc}; base-uri ${baseUri}; ${reportUriDirective}`\r\n );\r\n } catch (error) {\r\n console.error(\"Error adding CSP meta element:\", error);\r\n }\r\n };\r\n\r\n if (document.readyState === \"loading\") {\r\n document.addEventListener(\"DOMContentLoaded\", addOrUpdateCSPMeta);\r\n } else {\r\n addOrUpdateCSPMeta();\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\n\r\ntype TSComponent = (\r\n id: string,\r\n parent: HTMLElement,\r\n element: Function,\r\n params?: any,\r\n params2?: any\r\n) => void;\r\n\r\nexport const useTSComponent: TSComponent = (\r\n id,\r\n parent,\r\n element,\r\n params,\r\n params2\r\n) => {\r\n const selector = `#${id}`;\r\n const matches = parent.querySelectorAll<HTMLElement>(selector);\r\n\r\n // 1. Missing element check\r\n if (matches.length === 0) {\r\n throw new Error(`[useTSComponent] No element found with id '${id}' in the given parent.`);\r\n }\r\n\r\n // 2. Duplicate ID check\r\n if (matches.length > 1) {\r\n throw new Error(`[useTSComponent] Duplicate id '${id}' detected. Found ${matches.length} elements.`);\r\n }\r\n\r\n const target = matches[0];\r\n\r\n // 3. Sanitize the target’s existing HTML content\r\n target.innerHTML = DOMPurify.sanitize(target.innerHTML, { USE_PROFILES: { html: true } });\r\n\r\n // 4. Call the component function with the target\r\n element(target, params, params2);\r\n};\r\n","import { useTSComponent } from \"./useTSComponent\";\r\n\r\ntype TSCollection = (\r\n collections: string[],\r\n DOM: HTMLElement,\r\n elements: Function[],\r\n params?: any[]\r\n) => void;\r\n\r\nexport const useTSCollection: TSCollection = (\r\n collections,\r\n DOM,\r\n elements,\r\n params = []\r\n) => {\r\n const seenIds = new Set<string>();\r\n\r\n collections.forEach((id, index) => {\r\n // Check for duplicate IDs in the collection list itself\r\n if (seenIds.has(id)) {\r\n console.warn(`[useTSCollection] Duplicate ID in collection array: \"${id}\" — skipping.`);\r\n return;\r\n }\r\n seenIds.add(id);\r\n\r\n // Check for duplicates already in DOM\r\n const matches = DOM.querySelectorAll(`#${id}`);\r\n if (matches.length > 1) {\r\n console.warn(\r\n `[useTSCollection] Duplicate ID in DOM: \"${id}\" (${matches.length} elements found) — skipping component mount.`\r\n );\r\n return;\r\n }\r\n\r\n const elementFn = elements[index];\r\n const param = Array.isArray(params) ? params[index] : undefined;\r\n\r\n if (typeof elementFn === \"function\") {\r\n useTSComponent(id, DOM, elementFn, param);\r\n } else {\r\n console.warn(`[useTSCollection] No valid component function found for ID: \"${id}\"`);\r\n }\r\n });\r\n};\r\n","type TSSelect = <T extends Element = HTMLElement>(selector: string) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(selector: string): T | null => {\r\n const elements = document.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n throw new Error(\r\n `[useTSSelect] Duplicate ID detected: '${selector}'. Found ${elements.length} elements with this ID.`\r\n );\r\n }\r\n\r\n if (elements.length > 1) {\r\n console.warn(\r\n `[useTSSelect] Multiple elements found for selector: '${selector}'. Returning the first one.`\r\n );\r\n }\r\n\r\n return elements[0];\r\n};\r\n\r\nexport { useTSSelect };\r\n","import { jwtDecode } from \"jwt-decode\";\r\n\r\nexport const useTSAuth = (_Component: HTMLElement | void, loginUrl: string) => {\r\n const token = localStorage.getItem(\"token\");\r\n\r\n if (!token) {\r\n // Redirect to login page if token is missing\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n try {\r\n const decodedToken: any = jwtDecode(token);\r\n\r\n // Example: Check if the token has expired\r\n const currentTime = Date.now() / 1000;\r\n if (decodedToken.exp && decodedToken.exp < currentTime) {\r\n console.error(\"Token has expired\");\r\n window.localStorage.removeItem(\"token\");\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n // If the user is authenticated, return the component\r\n return null;\r\n } catch (error) {\r\n console.error(\"Invalid token:\", error);\r\n // Redirect to login page if token decoding fails\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n};\r\n","\r\ntype TSElementEach = (\r\n elements: NodeListOf<HTMLElement> | HTMLElement[],\r\n events: (keyof HTMLElementEventMap)[],\r\n callback: (element: HTMLElement, event: Event) => void\r\n) => void;\r\n\r\nexport const useTSElementEach: TSElementEach = (\r\n elements,\r\n events,\r\n callback\r\n) => {\r\n elements.forEach(element => {\r\n events.forEach(eventType => {\r\n element.addEventListener(eventType, event => {\r\n callback(element, event);\r\n });\r\n });\r\n });\r\n};\r\n","export const useTSNavigate = () => {\r\n const back = () => window.history.back();\r\n const forward = () => window.history.forward();\r\n\r\n return {\r\n back,\r\n forward,\r\n };\r\n};\r\n","// types.ts\r\nexport type OutletComponent = (DOM: HTMLElement) => void;\r\n\r\nexport type ChildRoute = {\r\n path: string;\r\n outlet: string;\r\n element: OutletComponent;\r\n};\r\n\r\nexport type Route = {\r\n path: string;\r\n element: (DOM: HTMLElement) => void;\r\n children?: ChildRoute[];\r\n};\r\n\r\n// You don't actually need to import the class TSRouter type.\r\n// Instead, export a cleaner interface with routes.\r\nexport interface RouterInstance {\r\n routes: Route[];\r\n}\r\n\r\n\r\ntype OutletOptions = {\r\n path: string;\r\n component: OutletComponent;\r\n};\r\n\r\nexport const useTSOutlet = (\r\n selector: string,\r\n outlets: OutletOptions[]\r\n): void => {\r\n const outletDOM = document.querySelector<HTMLElement>(`#${selector}`)\r\n || document.querySelector<HTMLElement>(`.${selector}`);\r\n\r\n if (!outletDOM) return;\r\n\r\n const currentPath = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n for (const outlet of outlets) {\r\n const base = outlet.path.replace(/\\/$/, \"\");\r\n\r\n // Match exact or nested path (e.g., /openai/child/1)\r\n if (currentPath === base || currentPath.startsWith(`${base}/`)) {\r\n outlet.component(outletDOM);\r\n break;\r\n }\r\n }\r\n};\r\n\r\n\r\nexport function renderChildRoutes(DOM: HTMLElement, router: RouterInstance): void {\r\n const pathname = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n router.routes.forEach((route) => {\r\n if (!route.children?.length) return;\r\n\r\n route.children.forEach((child) => {\r\n const childPath = child.path.replace(/\\/$/, \"\");\r\n\r\n if (pathname === childPath || pathname.startsWith(`${childPath}/`)) {\r\n const outlet = DOM.querySelector(`#${child.outlet}`)\r\n || DOM.querySelector(`.${child.outlet}`);\r\n if (outlet instanceof HTMLElement && child.element) {\r\n child.element(outlet);\r\n }\r\n }\r\n });\r\n });\r\n}","// useTSReactivity.ts\r\nimport { createStore } from 'zustand/vanilla';\r\n\r\ntype Listener<T> = (value: T) => void;\r\n\r\ninterface Signal<T> {\r\n get: () => T;\r\n set: (newValue: T) => void;\r\n subscribe: (listener: Listener<T>) => () => void;\r\n}\r\n\r\nexport function createSignal<T>(initialValue: T): Signal<T> {\r\n const store = createStore<{ value: T }>(() => ({ value: initialValue }));\r\n const listeners = new Set<Listener<T>>();\r\n\r\n return {\r\n get: () => store.getState().value,\r\n set: (newValue: T) => {\r\n store.setState({ value: newValue });\r\n listeners.forEach((listener) => listener(newValue));\r\n },\r\n subscribe: (listener: Listener<T>) => {\r\n listeners.add(listener);\r\n listener(store.getState().value); // Trigger immediately\r\n return () => listeners.delete(listener);\r\n },\r\n };\r\n}\r\n\r\ntype CleanupFn = () => void;\r\n\r\nexport function createEffect(effectFn: () => void | CleanupFn): void {\r\n const cleanup = effectFn();\r\n\r\n // Optional: return a way to dispose the effect manually\r\n if (typeof cleanup === 'function') {\r\n // You may store this and call it later if needed\r\n cleanup();\r\n }\r\n}\r\n","import { useTSElementEach } from './useTSForEach';\r\n\r\n\r\nconst useTSHashAnchor = () => {\r\n const links = document.querySelectorAll<HTMLAnchorElement>('a[href^=\"#\"]');\r\n\r\n useTSElementEach(\r\n links,\r\n ['click'],\r\n (element, e) => {\r\n e.preventDefault();\r\n const targetId = element.getAttribute('href')?.substring(1);\r\n const targetElement = targetId ? document.getElementById(targetId) : null;\r\n\r\n if (targetElement) {\r\n targetElement.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'start'\r\n });\r\n }\r\n }\r\n );\r\n}\r\n\r\nexport { useTSHashAnchor }","import { debounce } from 'lodash-es';\r\n\r\nlet sanitizeInput = (input: string): string => input;\r\n\r\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\r\n sanitizeInput = (input: string): string => {\r\n const element = document.createElement(\"div\");\r\n element.innerText = input;\r\n return element.innerHTML;\r\n };\r\n}\r\n\r\ntype AnchorInput =\r\n | NodeListOf<HTMLAnchorElement>\r\n | HTMLAnchorElement[]\r\n | HTMLAnchorElement\r\n | null\r\n | undefined;\r\n\r\nconst _enhanceAnchors = debounce((anchors: AnchorInput) => {\r\n const resolvedAnchors: HTMLAnchorElement[] = (() => {\r\n if (!anchors) return Array.from(document.querySelectorAll(\"a\"));\r\n if (Array.isArray(anchors)) return anchors;\r\n if (anchors instanceof HTMLAnchorElement) return [anchors];\r\n return Array.from(anchors);\r\n })();\r\n\r\n resolvedAnchors.forEach(anchor => {\r\n if (!anchor || anchor.dataset.anchorEnhanced === 'true') return;\r\n anchor.dataset.anchorEnhanced = 'true';\r\n\r\n // Sanitize attributes\r\n const originalHref = anchor.getAttribute(\"href\") || \"#\";\r\n const sanitizedHref = sanitizeInput(originalHref);\r\n anchor.setAttribute(\"href\", sanitizedHref);\r\n\r\n const originalClassName = anchor.getAttribute(\"class\") || \"\";\r\n anchor.setAttribute(\"class\", sanitizeInput(originalClassName));\r\n\r\n const ariaLabel = anchor.getAttribute(\"aria-label\");\r\n if (ariaLabel) {\r\n anchor.setAttribute(\"aria-label\", sanitizeInput(ariaLabel));\r\n }\r\n\r\n // Keep child elements safe (optional — you can remove this block if not needed)\r\n const child = anchor.querySelector(\":scope > *\") as HTMLElement;\r\n if (child) {\r\n anchor.innerHTML = \"\";\r\n anchor.appendChild(child);\r\n }\r\n\r\n // Skip attaching click listener if:\r\n // - It's a hash link (in-page navigation)\r\n // - It's an external link\r\n const href = anchor.getAttribute(\"href\") || \"\";\r\n if (href.startsWith(\"#\")) return; // Let browser handle hash scrolling normally\r\n\r\n try {\r\n const url = new URL(href, window.location.href);\r\n if (url.origin !== window.location.origin) return; // external link\r\n } catch {\r\n return; // invalid URL — skip\r\n }\r\n\r\n // Intercept same-origin navigation for SPA\r\n anchor.addEventListener(\"click\", (e: MouseEvent) => {\r\n e.preventDefault();\r\n try {\r\n const url = new URL(href, window.location.href);\r\n window.history.pushState({}, \"\", url.pathname + url.search + url.hash);\r\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\r\n } catch (err) {\r\n console.error(\"Invalid URL in anchor:\", href, err);\r\n }\r\n });\r\n });\r\n}, 50);\r\n\r\nexport const useAnchor = (anchors?: AnchorInput): void => {\r\n _enhanceAnchors(anchors);\r\n};\r\n","import { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = () => {\r\n const a = document.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n return useAnchor(a);\r\n}\r\n\r\nexport { useTSNoReload };","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = () => {\r\n useTSNoReload();\r\n useTSHashAnchor();\r\n};\r\n\r\nexport { useTSAnchorMount };","// src/loadBrython.ts\r\ntype LoadBrython = (src: string) => Promise<void>;\r\n\r\ndeclare global {\r\n interface Window {\r\n brython: Function;\r\n }\r\n}\r\n\r\nconst useTSloadBrython = async () => {\r\n const brythonJS = \"https://cdn.jsdelivr.net/npm/brython@3/brython.min.js\";\r\n const brythonStdlib = \"https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js\";\r\n\r\n // Utility function to load a script\r\n const loadScript: LoadBrython = (src) => {\r\n return new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.src = src;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.head.appendChild(script);\r\n });\r\n };\r\n\r\n // Load both scripts sequentially\r\n await loadScript(brythonJS);\r\n await loadScript(brythonStdlib);\r\n\r\n // Call brython() after scripts are loaded\r\n if (typeof window.brython === \"function\") {\r\n window.brython();\r\n } else {\r\n console.error(\"Brython did not load correctly.\");\r\n }\r\n};\r\n\r\ntype RequirePy = `${string}.py`;\r\n\r\ntype LoadPy = (src: RequirePy) => Promise<void>;\r\n\r\nconst loadPyFiles: LoadPy = (src) =>\r\n new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.type = \"text/python\";\r\n script.src = `/src/python/${src}`;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.body.appendChild(script);\r\n });\r\n\r\nexport { useTSloadBrython, loadPyFiles };\r\n","export function useTSLazy(factory: () => Promise<any>) {\r\n let cached: any | null = null;\r\n\r\n return async (el: HTMLElement, props?: any) => {\r\n try {\r\n if (!cached) {\r\n const mod = await factory();\r\n cached = mod.default || mod;\r\n }\r\n\r\n // If it's a component function (Vanilla TS style)\r\n if (typeof cached === \"function\") {\r\n return cached(el, props);\r\n }\r\n\r\n // If it's already an HTMLElement\r\n if (cached instanceof HTMLElement) {\r\n el.appendChild(cached);\r\n return;\r\n }\r\n\r\n // If it's a plain object with render()\r\n if (cached && typeof cached.render === \"function\") {\r\n return cached.render(el, props);\r\n }\r\n\r\n console.warn(\"useTSLazy: Unsupported module type\", cached);\r\n } catch (err) {\r\n console.error(\"useTSLazy failed:\", err);\r\n }\r\n };\r\n}\r\n","import DOMPurify from \"dompurify\";\r\nimport { tsParamsStore } from \"../../store\";\r\n\r\ntype RouteCallback = (\r\n errorElement?: HTMLElement,\r\n params?: Record<string, string>,\r\n query?: Record<string, string>\r\n) => void;\r\n\r\ninterface RouteConfig {\r\n path: string;\r\n routeto?: string;\r\n element: RouteCallback;\r\n errorElement?: RouteCallback;\r\n children?: RouteConfig[];\r\n params?: Record<string, string>;\r\n}\r\n\r\nexport class TSRouter {\r\n private routes: RouteConfig[] = [];\r\n private expectedParams: Set<string>;\r\n\r\n constructor(routes: RouteConfig[], expectedParams: string[]) {\r\n this.routes = routes;\r\n this.expectedParams = new Set(expectedParams);\r\n window.addEventListener(\"popstate\", this.handlePopState.bind(this));\r\n this.handlePopState(); // Initial load\r\n }\r\n\r\n private handlePopState() {\r\n const currentPath = window.location.pathname;\r\n const currentSearch = window.location.search;\r\n const queryParams = this.parseQueryParams(currentSearch);\r\n\r\n const matchingRoute = this.findMatchingRoute(currentPath, this.routes);\r\n\r\n if (matchingRoute) {\r\n if (matchingRoute.routeto) {\r\n this.navigate(matchingRoute.routeto);\r\n return;\r\n }\r\n\r\n const sanitizedParams = this.filterAndSanitizeParams(matchingRoute.params);\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n\r\n matchingRoute.element?.(errorElement, sanitizedParams, queryParams);\r\n\r\n if (matchingRoute.children) {\r\n const nestedPath = currentPath.slice(matchingRoute.path.length);\r\n const childElement = errorElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) {\r\n this.renderChildren(\r\n matchingRoute.children,\r\n nestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n } else {\r\n const notFoundRoute = this.findMatchingRoute(\"*\", this.routes);\r\n if (notFoundRoute) {\r\n const fallbackParams = this.filterAndSanitizeParams(notFoundRoute.params);\r\n tsParamsStore.getState().setParams(fallbackParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n notFoundRoute.element?.(errorElement, fallbackParams, queryParams);\r\n }\r\n }\r\n }\r\n\r\n private renderChildren(\r\n children: RouteConfig[] | undefined,\r\n nestedPath: string,\r\n parentElement: HTMLElement,\r\n parentParams: Record<string, string>,\r\n queryParams: Record<string, string>\r\n ) {\r\n if (!children || children.length === 0) {\r\n const childElement = parentElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) childElement.remove();\r\n return;\r\n }\r\n\r\n const matchingChild = this.findMatchingRoute(nestedPath, children);\r\n if (matchingChild) {\r\n const childElement = document.createElement(\"div\");\r\n childElement.id = \"child\";\r\n const mergedParams = { ...parentParams, ...matchingChild.params };\r\n const sanitizedParams = this.filterAndSanitizeParams(mergedParams);\r\n\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n matchingChild.element?.(childElement, sanitizedParams, queryParams);\r\n parentElement.appendChild(childElement);\r\n\r\n if (matchingChild.children) {\r\n const nextNestedPath = nestedPath.slice(matchingChild.path.length);\r\n this.renderChildren(\r\n matchingChild.children,\r\n nextNestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n }\r\n\r\n private parseQueryParams(search: string): Record<string, string> {\r\n const queryParams: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n if (this.expectedParams.has(key)) {\r\n queryParams[key] = DOMPurify.sanitize(value);\r\n }\r\n }\r\n\r\n return queryParams;\r\n }\r\n\r\n private findMatchingRoute(\r\n path: string,\r\n routes: RouteConfig[],\r\n inheritedParams: Record<string, string> = {}\r\n ): RouteConfig | undefined {\r\n for (const route of routes) {\r\n const routePath = route.path;\r\n const isDefaultRoute = routePath === \"*\";\r\n\r\n if (!isDefaultRoute) {\r\n const paramNames: string[] = [];\r\n const regexPattern = routePath.replace(/:[^\\s/]+/g, match => {\r\n paramNames.push(match.substring(1));\r\n return \"([^\\\\s/]+)\";\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}(?:/|$)`);\r\n const match = path.match(regex);\r\n\r\n if (match) {\r\n const params: Record<string, string> = { ...inheritedParams };\r\n paramNames.forEach((name, index) => {\r\n params[name] = match[index + 1] ?? \"\";\r\n });\r\n\r\n if (route.children) {\r\n const nestedPath = path.slice(match[0].length);\r\n const matchingChild = this.findMatchingRoute(\r\n nestedPath,\r\n route.children,\r\n params\r\n );\r\n if (matchingChild) return matchingChild;\r\n }\r\n\r\n return { ...route, params };\r\n }\r\n } else {\r\n return route;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private filterAndSanitizeParams(\r\n params?: Record<string, string>\r\n ): Record<string, string> {\r\n if (!params) return {};\r\n const sanitizedParams: Record<string, string> = {};\r\n for (const key in params) {\r\n if (this.expectedParams.has(key)) {\r\n sanitizedParams[key] = DOMPurify.sanitize(params[key] ?? \"\");\r\n }\r\n }\r\n return sanitizedParams;\r\n }\r\n\r\n navigate(path: string) {\r\n history.pushState(null, \"\", path);\r\n this.handlePopState();\r\n }\r\n\r\n addRoute(route: RouteConfig) {\r\n this.routes.push(route);\r\n }\r\n}\r\n","import { createStore } from \"zustand/vanilla\";\r\nimport DOMPurify from \"dompurify\";\r\n\r\ninterface TSParamsState {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setParams: (params: Record<string, string>) => void;\r\n setQuery: (query: Record<string, string>) => void;\r\n}\r\n\r\nexport const tsParamsStore = createStore<TSParamsState>((set) => ({\r\n params: {},\r\n query: {},\r\n setParams: (params) =>\r\n set(() => ({\r\n params: sanitize(params),\r\n })),\r\n setQuery: (query) =>\r\n set(() => ({\r\n query: sanitize(query),\r\n })),\r\n}));\r\n\r\nfunction sanitize(obj: Record<string, string>): Record<string, string> {\r\n const output: Record<string, string> = {};\r\n for (const key in obj) {\r\n output[key] = DOMPurify.sanitize(obj[key]);\r\n }\r\n return output;\r\n}\r\n"],"mappings":"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","names":["index_exports","__export","TSRouter","createEffect","createSignal","html","loadPyFiles","renderChildRoutes","useAnchorSingle","useInitialDOM","useTSAnchorMount","useTSAuth","useTSCollection","useTSComponent","useTSElementEach","useTSElements","useTSEvent","useTSEventAll","useTSExtractParams","useTSLazy","useTSMetaData","useTSNavigate","useTSOutlet","useTSParams","useTSPurifier","useTSSelect","useTSloadBrython","__toCommonJS","html","strings","values","result","str","i","autoRegister","allTags","el","tagName","tag","import_dompurify","useTSPurifier","input","config","mergedConfig","DOMPurify","useTSEvent","id","eventType","handler","element","import_vanilla","import_dompurify","extractPatternParams","pattern","path","paramNames","regexPattern","match","regex","result","name","i","DOMPurify","extractQueryParams","search","urlSearchParams","key","value","useTSParams","set","get","params","query","useTSExtractParams","pattern","store","useTSParams","params","query","useTSEventAll","selector","eventType","handler","elements","element","import_dompurify","useTSElements","htmlElement","element","config","defaultConfig","DOMPurify","node","data","tagName","sanitizedContent","import_dompurify","previousHTML","useInitialDOM","id","mount","targetElement","currentHTML","sanitizedHTML","DOMPurify","fallbackEl","import_dompurify","e","state","useAnchorSingle","element","href","ariaLabel","className","childElement","sanitizedHref","DOMPurify","sanitizedAriaLabel","hrefAttr","scrollPosition","import_dompurify","useTSCSP","scriptSrc","styleSrc","objectSrc","fontSrc","imgSrc","connectSrc","frameSrc","baseUri","reportUri","reportOnly","addOrUpdateCSPMeta","metaElement","reportUriDirective","error","useTSMetaData","config","cspConfig","metaData","DOMPurify","setName","name","updateMetaTag","setDescription","description","setAuthor","author","getName","getDescription","getAuthor","getAllMetaData","createMetaTag","content","metaTag","appendMetaTagsToHead","useTSCSP","import_dompurify","useTSComponent","id","parent","element","params","params2","selector","matches","target","DOMPurify","useTSCollection","collections","DOM","elements","params","seenIds","id","index","matches","elementFn","param","useTSComponent","useTSSelect","selector","elements","import_jwt_decode","useTSAuth","_Component","loginUrl","token","decodedToken","currentTime","error","useTSElementEach","elements","events","callback","element","eventType","event","useTSNavigate","useTSOutlet","selector","outlets","outletDOM","currentPath","outlet","base","renderChildRoutes","DOM","router","pathname","route","child","childPath","import_vanilla","createSignal","initialValue","store","listeners","newValue","listener","createEffect","effectFn","cleanup","useTSHashAnchor","links","useTSElementEach","element","e","targetId","targetElement","import_lodash_es","sanitizeInput","input","element","_enhanceAnchors","anchors","anchor","originalHref","sanitizedHref","originalClassName","ariaLabel","child","href","e","url","err","useAnchor","useTSNoReload","a","useAnchor","useTSAnchorMount","useTSNoReload","useTSHashAnchor","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","factory","cached","el","props","mod","err","import_dompurify","import_vanilla","import_dompurify","tsParamsStore","set","params","sanitize","query","obj","output","key","DOMPurify","TSRouter","routes","expectedParams","currentPath","currentSearch","queryParams","matchingRoute","sanitizedParams","tsParamsStore","errorElement","nestedPath","childElement","notFoundRoute","fallbackParams","children","parentElement","parentParams","matchingChild","mergedParams","nextNestedPath","search","urlSearchParams","key","value","DOMPurify","path","inheritedParams","route","routePath","paramNames","regexPattern","match","regex","params","name","index","autoRegister"]}
package/dist/index.d.cts CHANGED
@@ -126,15 +126,7 @@ type RequirePy = `${string}.py`;
126
126
  type LoadPy = (src: RequirePy) => Promise<void>;
127
127
  declare const loadPyFiles: LoadPy;
128
128
 
129
- type VComponent<P = any> = (mount: HTMLElement, props?: P) => any;
130
- type Loader<P = any> = () => Promise<{
131
- default: VComponent<P>;
132
- }>;
133
- interface LazyComponent<P = any> {
134
- (mount: HTMLElement, props?: P): void;
135
- preload?: () => Promise<void>;
136
- }
137
- declare function useTSLazy(loader: Loader, placeholder?: (mount: HTMLElement) => void): LazyComponent;
129
+ declare function useTSLazy(factory: () => Promise<any>): (el: HTMLElement, props?: any) => Promise<any>;
138
130
 
139
131
  type RouteCallback = (errorElement?: HTMLElement, params?: Record<string, string>, query?: Record<string, string>) => void;
140
132
  interface RouteConfig {
package/dist/index.d.ts CHANGED
@@ -126,15 +126,7 @@ type RequirePy = `${string}.py`;
126
126
  type LoadPy = (src: RequirePy) => Promise<void>;
127
127
  declare const loadPyFiles: LoadPy;
128
128
 
129
- type VComponent<P = any> = (mount: HTMLElement, props?: P) => any;
130
- type Loader<P = any> = () => Promise<{
131
- default: VComponent<P>;
132
- }>;
133
- interface LazyComponent<P = any> {
134
- (mount: HTMLElement, props?: P): void;
135
- preload?: () => Promise<void>;
136
- }
137
- declare function useTSLazy(loader: Loader, placeholder?: (mount: HTMLElement) => void): LazyComponent;
129
+ declare function useTSLazy(factory: () => Promise<any>): (el: HTMLElement, props?: any) => Promise<any>;
138
130
 
139
131
  type RouteCallback = (errorElement?: HTMLElement, params?: Record<string, string>, query?: Record<string, string>) => void;
140
132
  interface RouteConfig {
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- function A(n,...e){return n.reduce((t,r,o)=>t+r+(e[o]||""),"")}function T(){let n=new Set;document.querySelectorAll("*").forEach(e=>{let t=e.tagName.toLowerCase();t.includes("-")&&n.add(t)}),n.forEach(e=>{customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=`<div style="padding:10px;background:#eee;">${e} (Auto)</div>`}})})}import x from"dompurify";var R=(n,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof n=="string"?x.sanitize(n,r):x.sanitize(n.innerHTML,r)};var C=(n,e,t)=>{if(typeof n=="string"){let r=document.getElementById(n);r?r.addEventListener(e,t):console.warn(`Element with id '${n}' not found.`)}else n===document?document.addEventListener(e,t):console.warn("Invalid id parameter provided.")};import{createStore as ne}from"zustand/vanilla";import H from"dompurify";function re(n,e){let t=[],r=n.replace(/:[^/]+/g,a=>(t.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&t.forEach((a,l)=>{i[a]=H.sanitize(s[l+1]??"")}),i}function oe(n){let e={},t=new URLSearchParams(n);for(let[r,o]of t.entries())e[r]=H.sanitize(o);return e}var y=ne((n,e)=>({params:{},query:{},setFromPattern:t=>{let r=window.location.pathname,o=re(t,r),s=oe(window.location.search);n({params:o,query:s})},getParam:t=>e().params[t],getQuery:t=>e().query[t]}));function b(n){let e=y.getState();e.setFromPattern(n);let t=e.params,r=e.query;return{...t,...r}}var D=(n,e,t)=>{let r=document.querySelectorAll(n);return r.forEach(o=>{o.addEventListener(e,t)}),()=>{r.forEach(o=>{o.removeEventListener(e,t)})}};import M from"dompurify";var O=(n,e,t)=>{let r={USE_PROFILES:{svg:!0,html:!0},ALLOWED_TAGS:["svg","path","circle","rect","line","polyline","polygon","g","main","div","h1","h2","h3","h4","h5","h6","p","button","span","a","img","input","ul","li","i"],ALLOWED_ATTR:["class","id","href","src","alt","fill","stroke","stroke-width","viewBox","xmlns","d","x","y","cx","cy","r","width","height"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...t};M.addHook("uponSanitizeElement",(s,i)=>{let a=i.tagName.toLowerCase();a.includes("-")&&(i.allowedTags[a]=!0)}),M.addHook("uponSanitizeAttribute",(s,i)=>{i.attrName&&i.attrName.toLowerCase().startsWith("on")&&(i.keepAttr=!1)});let o=M.sanitize(e,r);n.innerHTML!==o&&(n.innerHTML=o)};import se from"dompurify";var E=null,z=(n,e)=>{if(typeof document>"u")return;let t=document.getElementById(n);if(!t)return;let r=t.innerHTML,o=se.sanitize(r);if(E!==null&&o!==E){let s=document.createElement("div");e(s),t.innerHTML=E}else E=o,e(t)};import $ from"dompurify";typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",n=>{let e=n.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var k=(n,e,t,r="",o=null)=>{if(!n)return;let s=$.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=$.sanitize(t,{USE_PROFILES:{html:!1}});n.setAttribute("href",s),n.setAttribute("aria-label",i),r&&(n.className=r.trim()),o&&n.replaceChildren(o),typeof window<"u"&&n.addEventListener("click",a=>{a.preventDefault();let d=a.currentTarget.getAttribute("href");if(d){let u=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:u},"",d),dispatchEvent(new PopStateEvent("popstate"))}})};import g from"dompurify";var I=(n="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",t="'none'",r="'self' https://fonts.googleapis.com https://fonts.gstatic.com",o="'self' https://blogger.googleusercontent.com",s=["'self'","https://fonts.googleapis.com","https://fonts.gstatic.com","https://www.google.com/maps/"],i="'self' https://www.youtube.com",a="'self'",l="/csp-report",d=!1)=>{let u=()=>{try{let c=document.querySelector('meta[http-equiv="Content-Security-Policy"]');c||(c=document.createElement("meta"),c.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(c));let p=d?`report-uri ${l};`:"";c.setAttribute("content",`default-src 'self'; script-src ${n}; style-src ${e}; object-src ${t}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${p}`)}catch(c){console.error("Error adding CSP meta element:",c)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u):u()};var q=(n,e)=>{let t={name:g.sanitize(n.name||""),description:g.sanitize(n.description||"Default description"),author:g.sanitize(n.author||"")},r=m=>{t.name=g.sanitize(m),c("name",t.name)},o=m=>{t.description=g.sanitize(m),c("description",t.description)},s=m=>{t.author=g.sanitize(m),c("author",t.author)},i=()=>t.name,a=()=>t.description,l=()=>t.author,d=()=>t,u=(m,S)=>{let h=document.createElement("meta");h.setAttribute("name",m),h.setAttribute("content",S),document.head.appendChild(h)},c=(m,S)=>{let h=document.querySelector(`meta[name="${m}"]`);h?h.setAttribute("content",S):u(m,S)},p=()=>{c("name",t.name),c("description",t.description),c("author",t.author)};return e&&I(e.scriptSrc,e.styleSrc,e.objectSrc,Array.isArray(e.connectSrc)?e.connectSrc.join(" "):e.connectSrc,e.reportOnly!==void 0?String(e.reportOnly):void 0),p(),{setName:r,setDescription:o,setAuthor:s,getName:i,getDescription:a,getAuthor:l,getAllMetaData:d,appendMetaTagsToHead:p}};import ie from"dompurify";var v=(n,e,t,r,o)=>{let s=`#${n}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${n}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${n}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=ie.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),t(a,r,o)};var F=(n,e,t,r=[])=>{let o=new Set;n.forEach((s,i)=>{if(o.has(s)){console.warn(`[useTSCollection] Duplicate ID in collection array: "${s}" \u2014 skipping.`);return}o.add(s);let a=e.querySelectorAll(`#${s}`);if(a.length>1){console.warn(`[useTSCollection] Duplicate ID in DOM: "${s}" (${a.length} elements found) \u2014 skipping component mount.`);return}let l=t[i],d=Array.isArray(r)?r[i]:void 0;typeof l=="function"?v(s,e,l,d):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var N=n=>{let e=document.querySelectorAll(n);if(e.length===0)return console.warn(`[useTSSelect] No element found for selector: '${n}'`),null;if(n.startsWith("#")&&e.length>1)throw new Error(`[useTSSelect] Duplicate ID detected: '${n}'. Found ${e.length} elements with this ID.`);return e.length>1&&console.warn(`[useTSSelect] Multiple elements found for selector: '${n}'. Returning the first one.`),e[0]};import{jwtDecode as ae}from"jwt-decode";var _=(n,e)=>{let t=localStorage.getItem("token");if(!t)return window.location.href=e,null;try{let r=ae(t),o=Date.now()/1e3;return r.exp&&r.exp<o&&(console.error("Token has expired"),window.localStorage.removeItem("token"),window.location.href=e),null}catch(r){return console.error("Invalid token:",r),window.location.href=e,null}};var L=(n,e,t)=>{n.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{t(r,s)})})})};var U=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var B=(n,e)=>{let t=document.querySelector(`#${n}`)||document.querySelector(`.${n}`);if(!t)return;let r=window.location.pathname.replace(/\/$/,"");for(let o of e){let s=o.path.replace(/\/$/,"");if(r===s||r.startsWith(`${s}/`)){o.component(t);break}}};function W(n,e){let t=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(t===s||t.startsWith(`${s}/`)){let i=n.querySelector(`#${o.outlet}`)||n.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}import{createStore as ce}from"zustand/vanilla";function j(n){let e=ce(()=>({value:n})),t=new Set;return{get:()=>e.getState().value,set:r=>{e.setState({value:r}),t.forEach(o=>o(r))},subscribe:r=>(t.add(r),r(e.getState().value),()=>t.delete(r))}}function Q(n){let e=n();typeof e=="function"&&e()}var G=()=>{let n=document.querySelectorAll('a[href^="#"]');L(n,["click"],(e,t)=>{t.preventDefault();let r=e.getAttribute("href")?.substring(1),o=r?document.getElementById(r):null;o&&o.scrollIntoView({behavior:"smooth",block:"start"})})};import{debounce as le}from"lodash-es";var w=n=>n;typeof window<"u"&&typeof document<"u"&&(w=n=>{let e=document.createElement("div");return e.innerText=n,e.innerHTML});var ue=le(n=>{(n?Array.isArray(n)?n:n instanceof HTMLAnchorElement?[n]:Array.from(n):Array.from(document.querySelectorAll("a"))).forEach(t=>{if(!t||t.dataset.anchorEnhanced==="true")return;t.dataset.anchorEnhanced="true";let r=t.getAttribute("href")||"#",o=w(r);t.setAttribute("href",o);let s=t.getAttribute("class")||"";t.setAttribute("class",w(s));let i=t.getAttribute("aria-label");i&&t.setAttribute("aria-label",w(i));let a=t.querySelector(":scope > *");a&&(t.innerHTML="",t.appendChild(a));let l=t.getAttribute("href")||"";if(!l.startsWith("#")){try{if(new URL(l,window.location.href).origin!==window.location.origin)return}catch{return}t.addEventListener("click",d=>{d.preventDefault();try{let u=new URL(l,window.location.href);window.history.pushState({},"",u.pathname+u.search+u.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(u){console.error("Invalid URL in anchor:",l,u)}})}})},50),V=n=>{ue(n)};var X=()=>{let n=document.querySelectorAll("a");return V(n)};var J=()=>{X(),G()};var Y=async()=>{let n="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",t=r=>new Promise((o,s)=>{let i=document.createElement("script");i.src=r,i.onload=()=>o(),i.onerror=()=>s(new Error(`Failed to load ${r}`)),document.head.appendChild(i)});await t(n),await t(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},K=n=>new Promise((e,t)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${n}`,r.onload=()=>e(),r.onerror=()=>t(new Error(`Failed to load ${n}`)),document.body.appendChild(r)});function Z(n,e){let t=null,r=null;async function o(){t||(r||(r=n().then(i=>{t=i.default})),await r)}let s=function(i,a){if(!(i instanceof HTMLElement)){if(typeof window>"u")return typeof t=="function"&&t.length===0?t(i):"";console.warn("useTSLazy: Expected HTMLElement as first arg, got",i);return}let l=i,d=a;if(typeof window>"u"||typeof document>"u")return;let u=document.createElement("div");u.setAttribute("data-lazy-placeholder",""),l.appendChild(u);try{e?.(u)}catch(c){console.error("useLazy placeholder render failed",c)}o().then(()=>{if(t){try{u.remove()}catch{}try{if(t.length>=1)t(l,d);else{let c=t(d);l.innerHTML=c}}catch(c){console.error("useLazy loaded component render failed",c)}}}).catch(c=>{console.error("useLazy loader failed",c);try{u.textContent="Failed to load component."}catch{}})};return s.preload=async()=>{await o()},s}import te from"dompurify";import{createStore as de}from"zustand/vanilla";import me from"dompurify";var f=de(n=>({params:{},query:{},setParams:e=>n(()=>({params:ee(e)})),setQuery:e=>n(()=>({query:ee(e)}))}));function ee(n){let e={};for(let t in n)e[t]=me.sanitize(n[t]);return e}var P=class{constructor(e,t){this.routes=[];this.routes=e,this.expectedParams=new Set(t),window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,t=window.location.search,r=this.parseQueryParams(t),o=this.findMatchingRoute(e,this.routes);if(o){if(o.routeto){this.navigate(o.routeto);return}let s=this.filterAndSanitizeParams(o.params);f.getState().setParams(s),f.getState().setQuery(r);let i=document.createElement("div");if(o.element?.(i,s,r),o.children){let a=e.slice(o.path.length),l=i.querySelector("#child");l&&this.renderChildren(o.children,a,l,s,r)}}else{let s=this.findMatchingRoute("*",this.routes);if(s){let i=this.filterAndSanitizeParams(s.params);f.getState().setParams(i),f.getState().setQuery(r);let a=document.createElement("div");s.element?.(a,i,r)}}}renderChildren(e,t,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(t,e);if(i){let a=document.createElement("div");a.id="child";let l={...o,...i.params},d=this.filterAndSanitizeParams(l);if(f.getState().setParams(d),f.getState().setQuery(s),i.element?.(a,d,s),r.appendChild(a),i.children){let u=t.slice(i.path.length);this.renderChildren(i.children,u,a,d,s)}}}parseQueryParams(e){let t={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(t[o]=te.sanitize(s));return t}findMatchingRoute(e,t,r={}){for(let o of t){let s=o.path;if(s==="*")return o;{let a=[],l=s.replace(/:[^\s/]+/g,c=>(a.push(c.substring(1)),"([^\\s/]+)")),d=new RegExp(`^${l}(?:/|$)`),u=e.match(d);if(u){let c={...r};if(a.forEach((p,m)=>{c[p]=u[m+1]??""}),o.children){let p=e.slice(u[0].length),m=this.findMatchingRoute(p,o.children,c);if(m)return m}return{...o,params:c}}}}}filterAndSanitizeParams(e){if(!e)return{};let t={};for(let r in e)this.expectedParams.has(r)&&(t[r]=te.sanitize(e[r]??""));return t}navigate(e){history.pushState(null,"",e),this.handlePopState()}addRoute(e){this.routes.push(e)}};typeof window<"u"&&(window.addEventListener("popstate",()=>{T()}),document.addEventListener("DOMContentLoaded",T));export{P as TSRouter,Q as createEffect,j as createSignal,A as html,K as loadPyFiles,W as renderChildRoutes,k as useAnchorSingle,z as useInitialDOM,J as useTSAnchorMount,_ as useTSAuth,F as useTSCollection,v as useTSComponent,L as useTSElementEach,O as useTSElements,C as useTSEvent,D as useTSEventAll,b as useTSExtractParams,Z as useTSLazy,q as useTSMetaData,U as useTSNavigate,B as useTSOutlet,y as useTSParams,R as useTSPurifier,N as useTSSelect,Y as useTSloadBrython};
1
+ function A(n,...e){return n.reduce((t,r,o)=>t+r+(e[o]||""),"")}function T(){let n=new Set;document.querySelectorAll("*").forEach(e=>{let t=e.tagName.toLowerCase();t.includes("-")&&n.add(t)}),n.forEach(e=>{customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=`<div style="padding:10px;background:#eee;">${e} (Auto)</div>`}})})}import x from"dompurify";var R=(n,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof n=="string"?x.sanitize(n,r):x.sanitize(n.innerHTML,r)};var C=(n,e,t)=>{if(typeof n=="string"){let r=document.getElementById(n);r?r.addEventListener(e,t):console.warn(`Element with id '${n}' not found.`)}else n===document?document.addEventListener(e,t):console.warn("Invalid id parameter provided.")};import{createStore as ne}from"zustand/vanilla";import b from"dompurify";function re(n,e){let t=[],r=n.replace(/:[^/]+/g,a=>(t.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&t.forEach((a,c)=>{i[a]=b.sanitize(s[c+1]??"")}),i}function oe(n){let e={},t=new URLSearchParams(n);for(let[r,o]of t.entries())e[r]=b.sanitize(o);return e}var E=ne((n,e)=>({params:{},query:{},setFromPattern:t=>{let r=window.location.pathname,o=re(t,r),s=oe(window.location.search);n({params:o,query:s})},getParam:t=>e().params[t],getQuery:t=>e().query[t]}));function H(n){let e=E.getState();e.setFromPattern(n);let t=e.params,r=e.query;return{...t,...r}}var D=(n,e,t)=>{let r=document.querySelectorAll(n);return r.forEach(o=>{o.addEventListener(e,t)}),()=>{r.forEach(o=>{o.removeEventListener(e,t)})}};import M from"dompurify";var O=(n,e,t)=>{let r={USE_PROFILES:{svg:!0,html:!0},ALLOWED_TAGS:["svg","path","circle","rect","line","polyline","polygon","g","main","div","h1","h2","h3","h4","h5","h6","p","button","span","a","img","input","ul","li","i"],ALLOWED_ATTR:["class","id","href","src","alt","fill","stroke","stroke-width","viewBox","xmlns","d","x","y","cx","cy","r","width","height"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...t};M.addHook("uponSanitizeElement",(s,i)=>{let a=i.tagName.toLowerCase();a.includes("-")&&(i.allowedTags[a]=!0)}),M.addHook("uponSanitizeAttribute",(s,i)=>{i.attrName&&i.attrName.toLowerCase().startsWith("on")&&(i.keepAttr=!1)});let o=M.sanitize(e,r);n.innerHTML!==o&&(n.innerHTML=o)};import se from"dompurify";var y=null,$=(n,e)=>{if(typeof document>"u")return;let t=document.getElementById(n);if(!t)return;let r=t.innerHTML,o=se.sanitize(r);if(y!==null&&o!==y){let s=document.createElement("div");e(s),t.innerHTML=y}else y=o,e(t)};import z from"dompurify";typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",n=>{let e=n.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var k=(n,e,t,r="",o=null)=>{if(!n)return;let s=z.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=z.sanitize(t,{USE_PROFILES:{html:!1}});n.setAttribute("href",s),n.setAttribute("aria-label",i),r&&(n.className=r.trim()),o&&n.replaceChildren(o),typeof window<"u"&&n.addEventListener("click",a=>{a.preventDefault();let d=a.currentTarget.getAttribute("href");if(d){let u=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:u},"",d),dispatchEvent(new PopStateEvent("popstate"))}})};import g from"dompurify";var I=(n="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",t="'none'",r="'self' https://fonts.googleapis.com https://fonts.gstatic.com",o="'self' https://blogger.googleusercontent.com",s=["'self'","https://fonts.googleapis.com","https://fonts.gstatic.com","https://www.google.com/maps/"],i="'self' https://www.youtube.com",a="'self'",c="/csp-report",d=!1)=>{let u=()=>{try{let l=document.querySelector('meta[http-equiv="Content-Security-Policy"]');l||(l=document.createElement("meta"),l.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(l));let p=d?`report-uri ${c};`:"";l.setAttribute("content",`default-src 'self'; script-src ${n}; style-src ${e}; object-src ${t}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${p}`)}catch(l){console.error("Error adding CSP meta element:",l)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",u):u()};var q=(n,e)=>{let t={name:g.sanitize(n.name||""),description:g.sanitize(n.description||"Default description"),author:g.sanitize(n.author||"")},r=m=>{t.name=g.sanitize(m),l("name",t.name)},o=m=>{t.description=g.sanitize(m),l("description",t.description)},s=m=>{t.author=g.sanitize(m),l("author",t.author)},i=()=>t.name,a=()=>t.description,c=()=>t.author,d=()=>t,u=(m,S)=>{let h=document.createElement("meta");h.setAttribute("name",m),h.setAttribute("content",S),document.head.appendChild(h)},l=(m,S)=>{let h=document.querySelector(`meta[name="${m}"]`);h?h.setAttribute("content",S):u(m,S)},p=()=>{l("name",t.name),l("description",t.description),l("author",t.author)};return e&&I(e.scriptSrc,e.styleSrc,e.objectSrc,Array.isArray(e.connectSrc)?e.connectSrc.join(" "):e.connectSrc,e.reportOnly!==void 0?String(e.reportOnly):void 0),p(),{setName:r,setDescription:o,setAuthor:s,getName:i,getDescription:a,getAuthor:c,getAllMetaData:d,appendMetaTagsToHead:p}};import ie from"dompurify";var v=(n,e,t,r,o)=>{let s=`#${n}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${n}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${n}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=ie.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),t(a,r,o)};var F=(n,e,t,r=[])=>{let o=new Set;n.forEach((s,i)=>{if(o.has(s)){console.warn(`[useTSCollection] Duplicate ID in collection array: "${s}" \u2014 skipping.`);return}o.add(s);let a=e.querySelectorAll(`#${s}`);if(a.length>1){console.warn(`[useTSCollection] Duplicate ID in DOM: "${s}" (${a.length} elements found) \u2014 skipping component mount.`);return}let c=t[i],d=Array.isArray(r)?r[i]:void 0;typeof c=="function"?v(s,e,c,d):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var N=n=>{let e=document.querySelectorAll(n);if(e.length===0)return console.warn(`[useTSSelect] No element found for selector: '${n}'`),null;if(n.startsWith("#")&&e.length>1)throw new Error(`[useTSSelect] Duplicate ID detected: '${n}'. Found ${e.length} elements with this ID.`);return e.length>1&&console.warn(`[useTSSelect] Multiple elements found for selector: '${n}'. Returning the first one.`),e[0]};import{jwtDecode as ae}from"jwt-decode";var _=(n,e)=>{let t=localStorage.getItem("token");if(!t)return window.location.href=e,null;try{let r=ae(t),o=Date.now()/1e3;return r.exp&&r.exp<o&&(console.error("Token has expired"),window.localStorage.removeItem("token"),window.location.href=e),null}catch(r){return console.error("Invalid token:",r),window.location.href=e,null}};var L=(n,e,t)=>{n.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{t(r,s)})})})};var U=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var B=(n,e)=>{let t=document.querySelector(`#${n}`)||document.querySelector(`.${n}`);if(!t)return;let r=window.location.pathname.replace(/\/$/,"");for(let o of e){let s=o.path.replace(/\/$/,"");if(r===s||r.startsWith(`${s}/`)){o.component(t);break}}};function j(n,e){let t=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(t===s||t.startsWith(`${s}/`)){let i=n.querySelector(`#${o.outlet}`)||n.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}import{createStore as ce}from"zustand/vanilla";function W(n){let e=ce(()=>({value:n})),t=new Set;return{get:()=>e.getState().value,set:r=>{e.setState({value:r}),t.forEach(o=>o(r))},subscribe:r=>(t.add(r),r(e.getState().value),()=>t.delete(r))}}function Q(n){let e=n();typeof e=="function"&&e()}var G=()=>{let n=document.querySelectorAll('a[href^="#"]');L(n,["click"],(e,t)=>{t.preventDefault();let r=e.getAttribute("href")?.substring(1),o=r?document.getElementById(r):null;o&&o.scrollIntoView({behavior:"smooth",block:"start"})})};import{debounce as le}from"lodash-es";var w=n=>n;typeof window<"u"&&typeof document<"u"&&(w=n=>{let e=document.createElement("div");return e.innerText=n,e.innerHTML});var ue=le(n=>{(n?Array.isArray(n)?n:n instanceof HTMLAnchorElement?[n]:Array.from(n):Array.from(document.querySelectorAll("a"))).forEach(t=>{if(!t||t.dataset.anchorEnhanced==="true")return;t.dataset.anchorEnhanced="true";let r=t.getAttribute("href")||"#",o=w(r);t.setAttribute("href",o);let s=t.getAttribute("class")||"";t.setAttribute("class",w(s));let i=t.getAttribute("aria-label");i&&t.setAttribute("aria-label",w(i));let a=t.querySelector(":scope > *");a&&(t.innerHTML="",t.appendChild(a));let c=t.getAttribute("href")||"";if(!c.startsWith("#")){try{if(new URL(c,window.location.href).origin!==window.location.origin)return}catch{return}t.addEventListener("click",d=>{d.preventDefault();try{let u=new URL(c,window.location.href);window.history.pushState({},"",u.pathname+u.search+u.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(u){console.error("Invalid URL in anchor:",c,u)}})}})},50),X=n=>{ue(n)};var J=()=>{let n=document.querySelectorAll("a");return X(n)};var V=()=>{J(),G()};var Y=async()=>{let n="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",t=r=>new Promise((o,s)=>{let i=document.createElement("script");i.src=r,i.onload=()=>o(),i.onerror=()=>s(new Error(`Failed to load ${r}`)),document.head.appendChild(i)});await t(n),await t(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},K=n=>new Promise((e,t)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${n}`,r.onload=()=>e(),r.onerror=()=>t(new Error(`Failed to load ${n}`)),document.body.appendChild(r)});function Z(n){let e=null;return async(t,r)=>{try{if(!e){let o=await n();e=o.default||o}if(typeof e=="function")return e(t,r);if(e instanceof HTMLElement){t.appendChild(e);return}if(e&&typeof e.render=="function")return e.render(t,r);console.warn("useTSLazy: Unsupported module type",e)}catch(o){console.error("useTSLazy failed:",o)}}}import te from"dompurify";import{createStore as de}from"zustand/vanilla";import me from"dompurify";var f=de(n=>({params:{},query:{},setParams:e=>n(()=>({params:ee(e)})),setQuery:e=>n(()=>({query:ee(e)}))}));function ee(n){let e={};for(let t in n)e[t]=me.sanitize(n[t]);return e}var P=class{constructor(e,t){this.routes=[];this.routes=e,this.expectedParams=new Set(t),window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,t=window.location.search,r=this.parseQueryParams(t),o=this.findMatchingRoute(e,this.routes);if(o){if(o.routeto){this.navigate(o.routeto);return}let s=this.filterAndSanitizeParams(o.params);f.getState().setParams(s),f.getState().setQuery(r);let i=document.createElement("div");if(o.element?.(i,s,r),o.children){let a=e.slice(o.path.length),c=i.querySelector("#child");c&&this.renderChildren(o.children,a,c,s,r)}}else{let s=this.findMatchingRoute("*",this.routes);if(s){let i=this.filterAndSanitizeParams(s.params);f.getState().setParams(i),f.getState().setQuery(r);let a=document.createElement("div");s.element?.(a,i,r)}}}renderChildren(e,t,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(t,e);if(i){let a=document.createElement("div");a.id="child";let c={...o,...i.params},d=this.filterAndSanitizeParams(c);if(f.getState().setParams(d),f.getState().setQuery(s),i.element?.(a,d,s),r.appendChild(a),i.children){let u=t.slice(i.path.length);this.renderChildren(i.children,u,a,d,s)}}}parseQueryParams(e){let t={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(t[o]=te.sanitize(s));return t}findMatchingRoute(e,t,r={}){for(let o of t){let s=o.path;if(s==="*")return o;{let a=[],c=s.replace(/:[^\s/]+/g,l=>(a.push(l.substring(1)),"([^\\s/]+)")),d=new RegExp(`^${c}(?:/|$)`),u=e.match(d);if(u){let l={...r};if(a.forEach((p,m)=>{l[p]=u[m+1]??""}),o.children){let p=e.slice(u[0].length),m=this.findMatchingRoute(p,o.children,l);if(m)return m}return{...o,params:l}}}}}filterAndSanitizeParams(e){if(!e)return{};let t={};for(let r in e)this.expectedParams.has(r)&&(t[r]=te.sanitize(e[r]??""));return t}navigate(e){history.pushState(null,"",e),this.handlePopState()}addRoute(e){this.routes.push(e)}};typeof window<"u"&&(window.addEventListener("popstate",()=>{T()}),document.addEventListener("DOMContentLoaded",T));export{P as TSRouter,Q as createEffect,W as createSignal,A as html,K as loadPyFiles,j as renderChildRoutes,k as useAnchorSingle,$ as useInitialDOM,V as useTSAnchorMount,_ as useTSAuth,F as useTSCollection,v as useTSComponent,L as useTSElementEach,O as useTSElements,C as useTSEvent,D as useTSEventAll,H as useTSExtractParams,Z as useTSLazy,q as useTSMetaData,U as useTSNavigate,B as useTSOutlet,E as useTSParams,R as useTSPurifier,N as useTSSelect,Y as useTSloadBrython};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/define/html.ts","../src/define/auto-register.ts","../src/hooks/useTSPurifier.ts","../src/hooks/useTSEvent.ts","../src/hooks/useTSParams.ts","../src/hooks/useTSExtract.ts","../src/hooks/useTSAllElements.ts","../src/hooks/useTSElements.ts","../src/hooks/useIntialDOM.ts","../src/hooks/useTSAnchorSingle.ts","../src/hooks/useTSMetaData.ts","../src/hooks/useTSCSP.ts","../src/hooks/useTSComponent.ts","../src/hooks/useTSCollection.ts","../src/hooks/useTSSelect.ts","../src/hooks/useTSAuth.ts","../src/hooks/useTSForEach.ts","../src/hooks/useTSNavigate.ts","../src/hooks/useTSOutlet.ts","../src/hooks/useReactivity.ts","../src/hooks/useTSHashAnchor.ts","../src/hooks/useTSAnchor.ts","../src/hooks/useTSNoReload.ts","../src/hooks/useTSAnchorMount.ts","../src/hooks/useTSInitializedBrython.ts","../src/hooks/useTSLazy.ts","../src/routes/class/Router.class.ts","../src/store/useTSParam.store.ts","../index.mts"],"sourcesContent":["export function html(strings: TemplateStringsArray, ...values: any[]): string {\r\n return strings.reduce((result, str, i) => {\r\n return result + str + (values[i] || '');\r\n }, '');\r\n}","// auto-register-runtime.ts\r\nfunction autoRegister() {\r\n const allTags = new Set<string>();\r\n document.querySelectorAll('*').forEach((el) => {\r\n const tagName = el.tagName.toLowerCase();\r\n if (!tagName.includes('-')) return; // Only register custom tags with a dash\r\n allTags.add(tagName);\r\n });\r\n\r\n allTags.forEach(tag => {\r\n if (!customElements.get(tag)) {\r\n customElements.define(tag, class extends HTMLElement {\r\n connectedCallback() {\r\n this.innerHTML = `<div style=\"padding:10px;background:#eee;\">${tag} (Auto)</div>`;\r\n }\r\n });\r\n }\r\n });\r\n}\r\n\r\n\r\nexport { autoRegister };","import DOMPurify from \"dompurify\";\r\nimport type { Config } from \"dompurify\";\r\n\r\ntype TSPurifier = (input: string | HTMLElement, config?: Config) => string;\r\n\r\nexport const useTSPurifier: TSPurifier = (\r\n input,\r\n config?\r\n) => {\r\n const defaultConfig: Config = {\r\n ADD_TAGS: [\"my-custom-tag\"],\r\n };\r\n\r\n const mergedConfig: Config = { ...defaultConfig, ...config };\r\n\r\n if (typeof input === \"string\") {\r\n return DOMPurify.sanitize(input, mergedConfig);\r\n } else {\r\n return DOMPurify.sanitize(input.innerHTML, mergedConfig);\r\n }\r\n};\r\n","type TSEvent = (\r\n id: string | Document,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: HTMLElementEventMap[keyof HTMLElementEventMap]) => void\r\n) => void;\r\n\r\nexport const useTSEvent: TSEvent = (\r\n id,\r\n eventType,\r\n handler\r\n) => {\r\n if (typeof id === 'string') {\r\n const element = document.getElementById(id);\r\n if (element) {\r\n element.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Element with id '${id}' not found.`);\r\n }\r\n } else if (id === document) {\r\n document.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Invalid id parameter provided.`);\r\n }\r\n};\r\n","// utils/hooks/useTSParams.ts\r\nimport { createStore } from 'zustand/vanilla';\r\nimport DOMPurify from 'dompurify';\r\n\r\ntype ParamStore = {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setFromPattern: (pattern: MustURL) => void;\r\n getParam: (key: string) => string | undefined;\r\n getQuery: (key: string) => string | undefined;\r\n};\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nfunction extractPatternParams(pattern: MustURL, path: string): Record<string, string> {\r\n const paramNames: string[] = [];\r\n const regexPattern = pattern.replace(/:[^/]+/g, (match) => {\r\n paramNames.push(match.slice(1));\r\n return '([^/]+)';\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}$`);\r\n const match = path.match(regex);\r\n const result: Record<string, string> = {};\r\n\r\n if (match) {\r\n paramNames.forEach((name, i) => {\r\n result[name] = DOMPurify.sanitize(match[i + 1] ?? '');\r\n });\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction extractQueryParams(search: MustURL): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n result[key] = DOMPurify.sanitize(value);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport const useTSParams = createStore<ParamStore>((set, get) => ({\r\n params: {},\r\n query: {},\r\n setFromPattern: (pattern: MustURL) => {\r\n const path = window.location.pathname;\r\n const params = extractPatternParams(pattern, path);\r\n const query = extractQueryParams(window.location.search as MustURL);\r\n set({ params, query });\r\n },\r\n getParam: (key: string) => get().params[key],\r\n getQuery: (key: string) => get().query[key],\r\n}));\r\n","import { useTSParams } from './useTSParams';\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nexport function useTSExtractParams(pattern: MustURL) {\r\n const store = useTSParams.getState();\r\n\r\n // Populate internal param/query store\r\n store.setFromPattern(pattern);\r\n\r\n const params = store.params;\r\n const query = store.query;\r\n\r\n return { ...params, ...query };\r\n}\r\n","export const useTSEventAll = <T extends Event>(\r\n selector: string,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n\r\n return () => {\r\n elements.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n };\r\n};\r\n\r\nexport const useTSEventSelectAll = <T extends Event>(\r\n selectors: string[],\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements: NodeListOf<HTMLElement>[] = [];\r\n\r\n selectors.forEach(selector => {\r\n const selectedElements = document.querySelectorAll(\r\n selector\r\n ) as NodeListOf<HTMLElement>;\r\n selectedElements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n elements.push(selectedElements);\r\n });\r\n\r\n return () => {\r\n elements.forEach(nodeList => {\r\n nodeList.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n });\r\n };\r\n};\r\n","import DOMPurify, { Config } from \"dompurify\";\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (htmlElement, element, config) => {\r\n const defaultConfig: Config = {\r\n USE_PROFILES: { svg: true, html: true },\r\n ALLOWED_TAGS: [\r\n \"svg\", \"path\", \"circle\", \"rect\", \"line\", \"polyline\", \"polygon\", \"g\",\r\n \"main\", \"div\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"p\", \"button\", \"span\", \"a\", \"img\", \"input\", \"ul\", \"li\", \"i\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"class\", \"id\", \"href\", \"src\", \"alt\", \"fill\", \"stroke\", \"stroke-width\",\r\n \"viewBox\", \"xmlns\", \"d\", \"x\", \"y\", \"cx\", \"cy\", \"r\", \"width\", \"height\"\r\n ],\r\n FORBID_TAGS: [\"script\", \"iframe\"],\r\n ALLOWED_URI_REGEXP:\r\n /^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\r\n ...config,\r\n };\r\n\r\n // ✅ Allow custom elements dynamically\r\n DOMPurify.addHook(\"uponSanitizeElement\", (node, data) => {\r\n const tagName = data.tagName.toLowerCase();\r\n if (tagName.includes(\"-\")) {\r\n data.allowedTags[tagName] = true;\r\n }\r\n });\r\n\r\n // ✅ Strip dangerous event handlers\r\n DOMPurify.addHook(\"uponSanitizeAttribute\", (node, data) => {\r\n if (data.attrName && data.attrName.toLowerCase().startsWith(\"on\")) {\r\n data.keepAttr = false;\r\n }\r\n });\r\n\r\n const sanitizedContent = DOMPurify.sanitize(element, defaultConfig);\r\n\r\n if (htmlElement.innerHTML !== sanitizedContent) {\r\n htmlElement.innerHTML = sanitizedContent;\r\n }\r\n};\r\n\r\n","import DOMPurify from \"dompurify\"\r\n\r\nlet previousHTML: string | null = null\r\n\r\ntype TSInitialDOM = (id: string, mount: (el: HTMLElement) => void) => void;\r\n\r\nexport const useInitialDOM: TSInitialDOM = (id, mount) => {\r\n // SSR guard\r\n if (typeof document === \"undefined\") return\r\n\r\n const targetElement = document.getElementById(id)\r\n if (!targetElement) return\r\n\r\n const currentHTML = targetElement.innerHTML\r\n const sanitizedHTML = DOMPurify.sanitize(currentHTML)\r\n\r\n if (previousHTML !== null && sanitizedHTML !== previousHTML) {\r\n // DOM changed externally — reset and remount in a temp container\r\n const fallbackEl = document.createElement(\"div\")\r\n mount(fallbackEl)\r\n targetElement.innerHTML = previousHTML\r\n } else {\r\n // First time or same sanitized DOM — mount to target\r\n previousHTML = sanitizedHTML\r\n mount(targetElement)\r\n }\r\n}\r\n","import DOMPurify from \"dompurify\";\r\n\r\ndeclare global {\r\n interface Window {\r\n __anchorSinglePopstateHandlerAttached?: boolean;\r\n }\r\n}\r\n\r\ntype AnchorSingle = (\r\n element: HTMLAnchorElement | null,\r\n href: string,\r\n ariaLabel: string,\r\n className?: string,\r\n childElement?: HTMLElement | null\r\n) => void;\r\n\r\n// Attach popstate listener only in the browser\r\nif (typeof window !== \"undefined\" && !window.__anchorSinglePopstateHandlerAttached) {\r\n window.addEventListener(\"popstate\", (e) => {\r\n const state = e.state as { scrollPosition?: number };\r\n if (state?.scrollPosition !== undefined) {\r\n window.scrollTo(0, state.scrollPosition);\r\n }\r\n });\r\n window.__anchorSinglePopstateHandlerAttached = true;\r\n}\r\n\r\nexport const useAnchorSingle: AnchorSingle = (\r\n element,\r\n href,\r\n ariaLabel,\r\n className = \"\",\r\n childElement = null\r\n) => {\r\n if (!element) return;\r\n\r\n // Sanitize string inputs\r\n const sanitizedHref = DOMPurify.sanitize(href, { ALLOWED_URI_REGEXP: /^(https?:|\\/)/ });\r\n const sanitizedAriaLabel = DOMPurify.sanitize(ariaLabel, { USE_PROFILES: { html: false } });\r\n\r\n element.setAttribute(\"href\", sanitizedHref);\r\n element.setAttribute(\"aria-label\", sanitizedAriaLabel);\r\n\r\n if (className) {\r\n element.className = className.trim();\r\n }\r\n\r\n if (childElement) {\r\n element.replaceChildren(childElement);\r\n }\r\n\r\n // Event binding only in browser\r\n if (typeof window !== \"undefined\") {\r\n element.addEventListener(\"click\", (e) => {\r\n e.preventDefault();\r\n const target = e.currentTarget as HTMLAnchorElement;\r\n const hrefAttr = target.getAttribute(\"href\");\r\n if (hrefAttr) {\r\n const scrollPosition = window.scrollY;\r\n window.scrollTo(0, 0);\r\n window.history.pushState({ scrollPosition }, \"\", hrefAttr);\r\n dispatchEvent(new PopStateEvent(\"popstate\"));\r\n }\r\n });\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\nimport { useTSCSP } from \"./useTSCSP\";\r\n\r\ntype SEOConfig = {\r\n name?: string;\r\n description?: string;\r\n author?: string;\r\n}\r\n\r\ntype CSPConfig = {\r\n scriptSrc?: string;\r\n styleSrc?: string;\r\n objectSrc?: string;\r\n connectSrc?: string[];\r\n reportOnly?: boolean;\r\n}\r\n\r\ntype SEOHandler = {\r\n setName: (name: string) => void;\r\n setDescription: (description: string) => void;\r\n setAuthor: (author: string) => void;\r\n getName: () => string;\r\n getDescription: () => string;\r\n getAuthor: () => string;\r\n getAllMetaData: () => SEOConfig;\r\n appendMetaTagsToHead: () => void;\r\n}\r\n\r\nexport const useTSMetaData = (\r\n config: SEOConfig,\r\n cspConfig?: CSPConfig\r\n): SEOHandler => {\r\n let metaData: SEOConfig = {\r\n name: DOMPurify.sanitize(config.name || \"\"),\r\n description: DOMPurify.sanitize(\r\n config.description || \"Default description\"\r\n ),\r\n author: DOMPurify.sanitize(config.author || \"\"),\r\n };\r\n\r\n const setName = (name: string): void => {\r\n metaData.name = DOMPurify.sanitize(name);\r\n updateMetaTag(\"name\", metaData.name);\r\n };\r\n\r\n const setDescription = (description: string): void => {\r\n metaData.description = DOMPurify.sanitize(description);\r\n updateMetaTag(\"description\", metaData.description);\r\n };\r\n\r\n const setAuthor = (author: string): void => {\r\n metaData.author = DOMPurify.sanitize(author);\r\n updateMetaTag(\"author\", metaData.author);\r\n };\r\n\r\n const getName = (): string => {\r\n return metaData.name!;\r\n };\r\n\r\n const getDescription = (): string => {\r\n return metaData.description!;\r\n };\r\n\r\n const getAuthor = (): string => {\r\n return metaData.author!;\r\n };\r\n\r\n const getAllMetaData = (): SEOConfig => {\r\n return metaData;\r\n };\r\n\r\n const createMetaTag = (name: string, content: string) => {\r\n const metaTag = document.createElement(\"meta\");\r\n metaTag.setAttribute(\"name\", name);\r\n metaTag.setAttribute(\"content\", content);\r\n document.head.appendChild(metaTag);\r\n };\r\n\r\n const updateMetaTag = (name: string, content: string) => {\r\n let metaTag = document.querySelector(`meta[name=\"${name}\"]`);\r\n if (metaTag) {\r\n metaTag.setAttribute(\"content\", content);\r\n } else {\r\n createMetaTag(name, content);\r\n }\r\n };\r\n\r\n const appendMetaTagsToHead = () => {\r\n updateMetaTag(\"name\", metaData.name!);\r\n updateMetaTag(\"description\", metaData.description!);\r\n updateMetaTag(\"author\", metaData.author!);\r\n };\r\n\r\n // Integrate with useTSCSP for CSP enforcement\r\n if (cspConfig) {\r\n useTSCSP(\r\n cspConfig.scriptSrc,\r\n cspConfig.styleSrc,\r\n cspConfig.objectSrc,\r\n Array.isArray(cspConfig.connectSrc) ? cspConfig.connectSrc.join(\" \") : cspConfig.connectSrc,\r\n cspConfig.reportOnly !== undefined ? String(cspConfig.reportOnly) : undefined\r\n );\r\n }\r\n\r\n appendMetaTagsToHead();\r\n\r\n return {\r\n setName,\r\n setDescription,\r\n setAuthor,\r\n getName,\r\n getDescription,\r\n getAuthor,\r\n getAllMetaData,\r\n appendMetaTagsToHead,\r\n };\r\n};\r\n","export const useTSCSP = (\r\n scriptSrc = `'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'`,\r\n styleSrc = \"'self' 'nonce-rAnd0m123'\", // Use nonce for inline styles\r\n objectSrc = \"'none'\",\r\n fontSrc = \"'self' https://fonts.googleapis.com https://fonts.gstatic.com\",\r\n imgSrc = \"'self' https://blogger.googleusercontent.com\",\r\n connectSrc = [\r\n \"'self'\",\r\n \"https://fonts.googleapis.com\",\r\n \"https://fonts.gstatic.com\",\r\n \"https://www.google.com/maps/\",\r\n ],\r\n frameSrc = \"'self' https://www.youtube.com\", // Add frame-src for embedding\r\n baseUri = \"'self'\",\r\n reportUri = \"/csp-report\",\r\n reportOnly = false\r\n) => {\r\n const addOrUpdateCSPMeta = () => {\r\n try {\r\n let metaElement = document.querySelector(\r\n 'meta[http-equiv=\"Content-Security-Policy\"]'\r\n );\r\n if (!metaElement) {\r\n metaElement = document.createElement(\"meta\");\r\n metaElement.setAttribute(\"http-equiv\", \"Content-Security-Policy\");\r\n document.head.appendChild(metaElement);\r\n }\r\n\r\n const reportUriDirective = reportOnly ? `report-uri ${reportUri};` : \"\";\r\n metaElement.setAttribute(\r\n \"content\",\r\n `default-src 'self'; script-src ${scriptSrc}; style-src ${styleSrc}; object-src ${objectSrc}; font-src ${fontSrc}; img-src ${imgSrc}; connect-src ${connectSrc.join(\r\n \" \"\r\n )}; frame-src ${frameSrc}; base-uri ${baseUri}; ${reportUriDirective}`\r\n );\r\n } catch (error) {\r\n console.error(\"Error adding CSP meta element:\", error);\r\n }\r\n };\r\n\r\n if (document.readyState === \"loading\") {\r\n document.addEventListener(\"DOMContentLoaded\", addOrUpdateCSPMeta);\r\n } else {\r\n addOrUpdateCSPMeta();\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\n\r\ntype TSComponent = (\r\n id: string,\r\n parent: HTMLElement,\r\n element: Function,\r\n params?: any,\r\n params2?: any\r\n) => void;\r\n\r\nexport const useTSComponent: TSComponent = (\r\n id,\r\n parent,\r\n element,\r\n params,\r\n params2\r\n) => {\r\n const selector = `#${id}`;\r\n const matches = parent.querySelectorAll<HTMLElement>(selector);\r\n\r\n // 1. Missing element check\r\n if (matches.length === 0) {\r\n throw new Error(`[useTSComponent] No element found with id '${id}' in the given parent.`);\r\n }\r\n\r\n // 2. Duplicate ID check\r\n if (matches.length > 1) {\r\n throw new Error(`[useTSComponent] Duplicate id '${id}' detected. Found ${matches.length} elements.`);\r\n }\r\n\r\n const target = matches[0];\r\n\r\n // 3. Sanitize the target’s existing HTML content\r\n target.innerHTML = DOMPurify.sanitize(target.innerHTML, { USE_PROFILES: { html: true } });\r\n\r\n // 4. Call the component function with the target\r\n element(target, params, params2);\r\n};\r\n","import { useTSComponent } from \"./useTSComponent\";\r\n\r\ntype TSCollection = (\r\n collections: string[],\r\n DOM: HTMLElement,\r\n elements: Function[],\r\n params?: any[]\r\n) => void;\r\n\r\nexport const useTSCollection: TSCollection = (\r\n collections,\r\n DOM,\r\n elements,\r\n params = []\r\n) => {\r\n const seenIds = new Set<string>();\r\n\r\n collections.forEach((id, index) => {\r\n // Check for duplicate IDs in the collection list itself\r\n if (seenIds.has(id)) {\r\n console.warn(`[useTSCollection] Duplicate ID in collection array: \"${id}\" — skipping.`);\r\n return;\r\n }\r\n seenIds.add(id);\r\n\r\n // Check for duplicates already in DOM\r\n const matches = DOM.querySelectorAll(`#${id}`);\r\n if (matches.length > 1) {\r\n console.warn(\r\n `[useTSCollection] Duplicate ID in DOM: \"${id}\" (${matches.length} elements found) — skipping component mount.`\r\n );\r\n return;\r\n }\r\n\r\n const elementFn = elements[index];\r\n const param = Array.isArray(params) ? params[index] : undefined;\r\n\r\n if (typeof elementFn === \"function\") {\r\n useTSComponent(id, DOM, elementFn, param);\r\n } else {\r\n console.warn(`[useTSCollection] No valid component function found for ID: \"${id}\"`);\r\n }\r\n });\r\n};\r\n","type TSSelect = <T extends Element = HTMLElement>(selector: string) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(selector: string): T | null => {\r\n const elements = document.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n throw new Error(\r\n `[useTSSelect] Duplicate ID detected: '${selector}'. Found ${elements.length} elements with this ID.`\r\n );\r\n }\r\n\r\n if (elements.length > 1) {\r\n console.warn(\r\n `[useTSSelect] Multiple elements found for selector: '${selector}'. Returning the first one.`\r\n );\r\n }\r\n\r\n return elements[0];\r\n};\r\n\r\nexport { useTSSelect };\r\n","import { jwtDecode } from \"jwt-decode\";\r\n\r\nexport const useTSAuth = (_Component: HTMLElement | void, loginUrl: string) => {\r\n const token = localStorage.getItem(\"token\");\r\n\r\n if (!token) {\r\n // Redirect to login page if token is missing\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n try {\r\n const decodedToken: any = jwtDecode(token);\r\n\r\n // Example: Check if the token has expired\r\n const currentTime = Date.now() / 1000;\r\n if (decodedToken.exp && decodedToken.exp < currentTime) {\r\n console.error(\"Token has expired\");\r\n window.localStorage.removeItem(\"token\");\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n // If the user is authenticated, return the component\r\n return null;\r\n } catch (error) {\r\n console.error(\"Invalid token:\", error);\r\n // Redirect to login page if token decoding fails\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n};\r\n","\r\ntype TSElementEach = (\r\n elements: NodeListOf<HTMLElement> | HTMLElement[],\r\n events: (keyof HTMLElementEventMap)[],\r\n callback: (element: HTMLElement, event: Event) => void\r\n) => void;\r\n\r\nexport const useTSElementEach: TSElementEach = (\r\n elements,\r\n events,\r\n callback\r\n) => {\r\n elements.forEach(element => {\r\n events.forEach(eventType => {\r\n element.addEventListener(eventType, event => {\r\n callback(element, event);\r\n });\r\n });\r\n });\r\n};\r\n","export const useTSNavigate = () => {\r\n const back = () => window.history.back();\r\n const forward = () => window.history.forward();\r\n\r\n return {\r\n back,\r\n forward,\r\n };\r\n};\r\n","// types.ts\r\nexport type OutletComponent = (DOM: HTMLElement) => void;\r\n\r\nexport type ChildRoute = {\r\n path: string;\r\n outlet: string;\r\n element: OutletComponent;\r\n};\r\n\r\nexport type Route = {\r\n path: string;\r\n element: (DOM: HTMLElement) => void;\r\n children?: ChildRoute[];\r\n};\r\n\r\n// You don't actually need to import the class TSRouter type.\r\n// Instead, export a cleaner interface with routes.\r\nexport interface RouterInstance {\r\n routes: Route[];\r\n}\r\n\r\n\r\ntype OutletOptions = {\r\n path: string;\r\n component: OutletComponent;\r\n};\r\n\r\nexport const useTSOutlet = (\r\n selector: string,\r\n outlets: OutletOptions[]\r\n): void => {\r\n const outletDOM = document.querySelector<HTMLElement>(`#${selector}`)\r\n || document.querySelector<HTMLElement>(`.${selector}`);\r\n\r\n if (!outletDOM) return;\r\n\r\n const currentPath = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n for (const outlet of outlets) {\r\n const base = outlet.path.replace(/\\/$/, \"\");\r\n\r\n // Match exact or nested path (e.g., /openai/child/1)\r\n if (currentPath === base || currentPath.startsWith(`${base}/`)) {\r\n outlet.component(outletDOM);\r\n break;\r\n }\r\n }\r\n};\r\n\r\n\r\nexport function renderChildRoutes(DOM: HTMLElement, router: RouterInstance): void {\r\n const pathname = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n router.routes.forEach((route) => {\r\n if (!route.children?.length) return;\r\n\r\n route.children.forEach((child) => {\r\n const childPath = child.path.replace(/\\/$/, \"\");\r\n\r\n if (pathname === childPath || pathname.startsWith(`${childPath}/`)) {\r\n const outlet = DOM.querySelector(`#${child.outlet}`)\r\n || DOM.querySelector(`.${child.outlet}`);\r\n if (outlet instanceof HTMLElement && child.element) {\r\n child.element(outlet);\r\n }\r\n }\r\n });\r\n });\r\n}","// useTSReactivity.ts\r\nimport { createStore } from 'zustand/vanilla';\r\n\r\ntype Listener<T> = (value: T) => void;\r\n\r\ninterface Signal<T> {\r\n get: () => T;\r\n set: (newValue: T) => void;\r\n subscribe: (listener: Listener<T>) => () => void;\r\n}\r\n\r\nexport function createSignal<T>(initialValue: T): Signal<T> {\r\n const store = createStore<{ value: T }>(() => ({ value: initialValue }));\r\n const listeners = new Set<Listener<T>>();\r\n\r\n return {\r\n get: () => store.getState().value,\r\n set: (newValue: T) => {\r\n store.setState({ value: newValue });\r\n listeners.forEach((listener) => listener(newValue));\r\n },\r\n subscribe: (listener: Listener<T>) => {\r\n listeners.add(listener);\r\n listener(store.getState().value); // Trigger immediately\r\n return () => listeners.delete(listener);\r\n },\r\n };\r\n}\r\n\r\ntype CleanupFn = () => void;\r\n\r\nexport function createEffect(effectFn: () => void | CleanupFn): void {\r\n const cleanup = effectFn();\r\n\r\n // Optional: return a way to dispose the effect manually\r\n if (typeof cleanup === 'function') {\r\n // You may store this and call it later if needed\r\n cleanup();\r\n }\r\n}\r\n","import { useTSElementEach } from './useTSForEach';\r\n\r\n\r\nconst useTSHashAnchor = () => {\r\n const links = document.querySelectorAll<HTMLAnchorElement>('a[href^=\"#\"]');\r\n\r\n useTSElementEach(\r\n links,\r\n ['click'],\r\n (element, e) => {\r\n e.preventDefault();\r\n const targetId = element.getAttribute('href')?.substring(1);\r\n const targetElement = targetId ? document.getElementById(targetId) : null;\r\n\r\n if (targetElement) {\r\n targetElement.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'start'\r\n });\r\n }\r\n }\r\n );\r\n}\r\n\r\nexport { useTSHashAnchor }","import { debounce } from 'lodash-es';\r\n\r\nlet sanitizeInput = (input: string): string => input;\r\n\r\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\r\n sanitizeInput = (input: string): string => {\r\n const element = document.createElement(\"div\");\r\n element.innerText = input;\r\n return element.innerHTML;\r\n };\r\n}\r\n\r\ntype AnchorInput =\r\n | NodeListOf<HTMLAnchorElement>\r\n | HTMLAnchorElement[]\r\n | HTMLAnchorElement\r\n | null\r\n | undefined;\r\n\r\nconst _enhanceAnchors = debounce((anchors: AnchorInput) => {\r\n const resolvedAnchors: HTMLAnchorElement[] = (() => {\r\n if (!anchors) return Array.from(document.querySelectorAll(\"a\"));\r\n if (Array.isArray(anchors)) return anchors;\r\n if (anchors instanceof HTMLAnchorElement) return [anchors];\r\n return Array.from(anchors);\r\n })();\r\n\r\n resolvedAnchors.forEach(anchor => {\r\n if (!anchor || anchor.dataset.anchorEnhanced === 'true') return;\r\n anchor.dataset.anchorEnhanced = 'true';\r\n\r\n // Sanitize attributes\r\n const originalHref = anchor.getAttribute(\"href\") || \"#\";\r\n const sanitizedHref = sanitizeInput(originalHref);\r\n anchor.setAttribute(\"href\", sanitizedHref);\r\n\r\n const originalClassName = anchor.getAttribute(\"class\") || \"\";\r\n anchor.setAttribute(\"class\", sanitizeInput(originalClassName));\r\n\r\n const ariaLabel = anchor.getAttribute(\"aria-label\");\r\n if (ariaLabel) {\r\n anchor.setAttribute(\"aria-label\", sanitizeInput(ariaLabel));\r\n }\r\n\r\n // Keep child elements safe (optional — you can remove this block if not needed)\r\n const child = anchor.querySelector(\":scope > *\") as HTMLElement;\r\n if (child) {\r\n anchor.innerHTML = \"\";\r\n anchor.appendChild(child);\r\n }\r\n\r\n // Skip attaching click listener if:\r\n // - It's a hash link (in-page navigation)\r\n // - It's an external link\r\n const href = anchor.getAttribute(\"href\") || \"\";\r\n if (href.startsWith(\"#\")) return; // Let browser handle hash scrolling normally\r\n\r\n try {\r\n const url = new URL(href, window.location.href);\r\n if (url.origin !== window.location.origin) return; // external link\r\n } catch {\r\n return; // invalid URL — skip\r\n }\r\n\r\n // Intercept same-origin navigation for SPA\r\n anchor.addEventListener(\"click\", (e: MouseEvent) => {\r\n e.preventDefault();\r\n try {\r\n const url = new URL(href, window.location.href);\r\n window.history.pushState({}, \"\", url.pathname + url.search + url.hash);\r\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\r\n } catch (err) {\r\n console.error(\"Invalid URL in anchor:\", href, err);\r\n }\r\n });\r\n });\r\n}, 50);\r\n\r\nexport const useAnchor = (anchors?: AnchorInput): void => {\r\n _enhanceAnchors(anchors);\r\n};\r\n","import { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = () => {\r\n const a = document.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n return useAnchor(a);\r\n}\r\n\r\nexport { useTSNoReload };","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = () => {\r\n useTSNoReload();\r\n useTSHashAnchor();\r\n};\r\n\r\nexport { useTSAnchorMount };","// src/loadBrython.ts\r\ntype LoadBrython = (src: string) => Promise<void>;\r\n\r\ndeclare global {\r\n interface Window {\r\n brython: Function;\r\n }\r\n}\r\n\r\nconst useTSloadBrython = async () => {\r\n const brythonJS = \"https://cdn.jsdelivr.net/npm/brython@3/brython.min.js\";\r\n const brythonStdlib = \"https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js\";\r\n\r\n // Utility function to load a script\r\n const loadScript: LoadBrython = (src) => {\r\n return new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.src = src;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.head.appendChild(script);\r\n });\r\n };\r\n\r\n // Load both scripts sequentially\r\n await loadScript(brythonJS);\r\n await loadScript(brythonStdlib);\r\n\r\n // Call brython() after scripts are loaded\r\n if (typeof window.brython === \"function\") {\r\n window.brython();\r\n } else {\r\n console.error(\"Brython did not load correctly.\");\r\n }\r\n};\r\n\r\ntype RequirePy = `${string}.py`;\r\n\r\ntype LoadPy = (src: RequirePy) => Promise<void>;\r\n\r\nconst loadPyFiles: LoadPy = (src) =>\r\n new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.type = \"text/python\";\r\n script.src = `/src/python/${src}`;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.body.appendChild(script);\r\n });\r\n\r\nexport { useTSloadBrython, loadPyFiles };\r\n","// lazy code spitter\r\n\r\nexport type VComponent<P = any> = (mount: HTMLElement, props?: P) => any;\r\nexport type Loader<P = any> = () => Promise<{ default: VComponent<P> }>;\r\n\r\nexport interface LazyComponent<P = any> {\r\n (mount: HTMLElement, props?: P): void;\r\n preload?: () => Promise<void>;\r\n}\r\n\r\nexport function useTSLazy(loader: Loader, placeholder?: (mount: HTMLElement) => void): LazyComponent {\r\n let loaded: VComponent | null = null;\r\n let loadingPromise: Promise<void> | null = null;\r\n\r\n async function ensureLoaded() {\r\n if (loaded) return;\r\n if (!loadingPromise) {\r\n loadingPromise = loader().then((mod) => {\r\n loaded = mod.default;\r\n });\r\n }\r\n await loadingPromise;\r\n }\r\n\r\n const lazyFn = function (mountOrProps?: any, maybeProps?: any) {\r\n // Case 1: SSR or string-returning usage (no HTMLElement)\r\n if (!(mountOrProps instanceof HTMLElement)) {\r\n // we’re being called like LazyPillar(props)\r\n if (typeof window === \"undefined\") {\r\n // server-side: return string directly if loaded\r\n if (typeof loaded === \"function\" && loaded.length === 0) {\r\n return (loaded as (props?: any) => string)(mountOrProps);\r\n }\r\n return \"\";\r\n }\r\n console.warn(\"useTSLazy: Expected HTMLElement as first arg, got\", mountOrProps);\r\n return;\r\n }\r\n\r\n // Case 2: Normal DOM mounting\r\n const mount = mountOrProps as HTMLElement;\r\n const props = maybeProps;\r\n\r\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\r\n return;\r\n }\r\n\r\n const placeholderWrapper = document.createElement(\"div\");\r\n placeholderWrapper.setAttribute(\"data-lazy-placeholder\", \"\");\r\n mount.appendChild(placeholderWrapper);\r\n\r\n try {\r\n placeholder?.(placeholderWrapper);\r\n } catch (err) {\r\n console.error(\"useLazy placeholder render failed\", err);\r\n }\r\n\r\n ensureLoaded()\r\n .then(() => {\r\n if (!loaded) return;\r\n\r\n try {\r\n placeholderWrapper.remove();\r\n } catch { }\r\n\r\n try {\r\n if (loaded.length >= 1) {\r\n // (mount, props) style\r\n (loaded as (mount: HTMLElement, props?: any) => any)(mount, props);\r\n } else {\r\n // (props) => string style\r\n const html = (loaded as (props?: any) => string)(props);\r\n mount.innerHTML = html;\r\n }\r\n } catch (err) {\r\n console.error(\"useLazy loaded component render failed\", err);\r\n }\r\n })\r\n .catch((err) => {\r\n console.error(\"useLazy loader failed\", err);\r\n try {\r\n placeholderWrapper.textContent = \"Failed to load component.\";\r\n } catch { }\r\n });\r\n } as LazyComponent;\r\n\r\n lazyFn.preload = async () => {\r\n await ensureLoaded();\r\n };\r\n\r\n return lazyFn;\r\n}\r\n","import DOMPurify from \"dompurify\";\r\nimport { tsParamsStore } from \"../../store\";\r\n\r\ntype RouteCallback = (\r\n errorElement?: HTMLElement,\r\n params?: Record<string, string>,\r\n query?: Record<string, string>\r\n) => void;\r\n\r\ninterface RouteConfig {\r\n path: string;\r\n routeto?: string;\r\n element: RouteCallback;\r\n errorElement?: RouteCallback;\r\n children?: RouteConfig[];\r\n params?: Record<string, string>;\r\n}\r\n\r\nexport class TSRouter {\r\n private routes: RouteConfig[] = [];\r\n private expectedParams: Set<string>;\r\n\r\n constructor(routes: RouteConfig[], expectedParams: string[]) {\r\n this.routes = routes;\r\n this.expectedParams = new Set(expectedParams);\r\n window.addEventListener(\"popstate\", this.handlePopState.bind(this));\r\n this.handlePopState(); // Initial load\r\n }\r\n\r\n private handlePopState() {\r\n const currentPath = window.location.pathname;\r\n const currentSearch = window.location.search;\r\n const queryParams = this.parseQueryParams(currentSearch);\r\n\r\n const matchingRoute = this.findMatchingRoute(currentPath, this.routes);\r\n\r\n if (matchingRoute) {\r\n if (matchingRoute.routeto) {\r\n this.navigate(matchingRoute.routeto);\r\n return;\r\n }\r\n\r\n const sanitizedParams = this.filterAndSanitizeParams(matchingRoute.params);\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n\r\n matchingRoute.element?.(errorElement, sanitizedParams, queryParams);\r\n\r\n if (matchingRoute.children) {\r\n const nestedPath = currentPath.slice(matchingRoute.path.length);\r\n const childElement = errorElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) {\r\n this.renderChildren(\r\n matchingRoute.children,\r\n nestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n } else {\r\n const notFoundRoute = this.findMatchingRoute(\"*\", this.routes);\r\n if (notFoundRoute) {\r\n const fallbackParams = this.filterAndSanitizeParams(notFoundRoute.params);\r\n tsParamsStore.getState().setParams(fallbackParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n notFoundRoute.element?.(errorElement, fallbackParams, queryParams);\r\n }\r\n }\r\n }\r\n\r\n private renderChildren(\r\n children: RouteConfig[] | undefined,\r\n nestedPath: string,\r\n parentElement: HTMLElement,\r\n parentParams: Record<string, string>,\r\n queryParams: Record<string, string>\r\n ) {\r\n if (!children || children.length === 0) {\r\n const childElement = parentElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) childElement.remove();\r\n return;\r\n }\r\n\r\n const matchingChild = this.findMatchingRoute(nestedPath, children);\r\n if (matchingChild) {\r\n const childElement = document.createElement(\"div\");\r\n childElement.id = \"child\";\r\n const mergedParams = { ...parentParams, ...matchingChild.params };\r\n const sanitizedParams = this.filterAndSanitizeParams(mergedParams);\r\n\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n matchingChild.element?.(childElement, sanitizedParams, queryParams);\r\n parentElement.appendChild(childElement);\r\n\r\n if (matchingChild.children) {\r\n const nextNestedPath = nestedPath.slice(matchingChild.path.length);\r\n this.renderChildren(\r\n matchingChild.children,\r\n nextNestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n }\r\n\r\n private parseQueryParams(search: string): Record<string, string> {\r\n const queryParams: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n if (this.expectedParams.has(key)) {\r\n queryParams[key] = DOMPurify.sanitize(value);\r\n }\r\n }\r\n\r\n return queryParams;\r\n }\r\n\r\n private findMatchingRoute(\r\n path: string,\r\n routes: RouteConfig[],\r\n inheritedParams: Record<string, string> = {}\r\n ): RouteConfig | undefined {\r\n for (const route of routes) {\r\n const routePath = route.path;\r\n const isDefaultRoute = routePath === \"*\";\r\n\r\n if (!isDefaultRoute) {\r\n const paramNames: string[] = [];\r\n const regexPattern = routePath.replace(/:[^\\s/]+/g, match => {\r\n paramNames.push(match.substring(1));\r\n return \"([^\\\\s/]+)\";\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}(?:/|$)`);\r\n const match = path.match(regex);\r\n\r\n if (match) {\r\n const params: Record<string, string> = { ...inheritedParams };\r\n paramNames.forEach((name, index) => {\r\n params[name] = match[index + 1] ?? \"\";\r\n });\r\n\r\n if (route.children) {\r\n const nestedPath = path.slice(match[0].length);\r\n const matchingChild = this.findMatchingRoute(\r\n nestedPath,\r\n route.children,\r\n params\r\n );\r\n if (matchingChild) return matchingChild;\r\n }\r\n\r\n return { ...route, params };\r\n }\r\n } else {\r\n return route;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private filterAndSanitizeParams(\r\n params?: Record<string, string>\r\n ): Record<string, string> {\r\n if (!params) return {};\r\n const sanitizedParams: Record<string, string> = {};\r\n for (const key in params) {\r\n if (this.expectedParams.has(key)) {\r\n sanitizedParams[key] = DOMPurify.sanitize(params[key] ?? \"\");\r\n }\r\n }\r\n return sanitizedParams;\r\n }\r\n\r\n navigate(path: string) {\r\n history.pushState(null, \"\", path);\r\n this.handlePopState();\r\n }\r\n\r\n addRoute(route: RouteConfig) {\r\n this.routes.push(route);\r\n }\r\n}\r\n","import { createStore } from \"zustand/vanilla\";\r\nimport DOMPurify from \"dompurify\";\r\n\r\ninterface TSParamsState {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setParams: (params: Record<string, string>) => void;\r\n setQuery: (query: Record<string, string>) => void;\r\n}\r\n\r\nexport const tsParamsStore = createStore<TSParamsState>((set) => ({\r\n params: {},\r\n query: {},\r\n setParams: (params) =>\r\n set(() => ({\r\n params: sanitize(params),\r\n })),\r\n setQuery: (query) =>\r\n set(() => ({\r\n query: sanitize(query),\r\n })),\r\n}));\r\n\r\nfunction sanitize(obj: Record<string, string>): Record<string, string> {\r\n const output: Record<string, string> = {};\r\n for (const key in obj) {\r\n output[key] = DOMPurify.sanitize(obj[key]);\r\n }\r\n return output;\r\n}\r\n","import { autoRegister } from './src/define';\r\n\r\nexport { html } from './src/define';\r\nexport { createEffect, createSignal, renderChildRoutes, useTSLazy, useTSOutlet, useTSloadBrython, loadPyFiles, useTSNavigate, useTSMetaData, useTSSelect, useTSCollection, useTSComponent, useTSAuth, useTSElementEach, useInitialDOM, useAnchorSingle, useTSPurifier, useTSEvent, useTSExtractParams, useTSParams, useTSEventAll, useTSElements, useTSAnchorMount } from \"./src/hooks\"\r\nexport { TSRouter } from \"./src/routes/class/Router.class\";\r\n\r\nif (typeof window !== 'undefined') {\r\n window.addEventListener('popstate', () => {\r\n autoRegister();\r\n });\r\n document.addEventListener('DOMContentLoaded', autoRegister);\r\n}\r\n\r\n"],"mappings":"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","names":["html","strings","values","result","str","i","autoRegister","allTags","el","tagName","tag","DOMPurify","useTSPurifier","input","config","mergedConfig","useTSEvent","id","eventType","handler","element","createStore","DOMPurify","extractPatternParams","pattern","path","paramNames","regexPattern","match","regex","result","name","i","extractQueryParams","search","urlSearchParams","key","value","useTSParams","set","get","params","query","useTSExtractParams","pattern","store","useTSParams","params","query","useTSEventAll","selector","eventType","handler","elements","element","DOMPurify","useTSElements","htmlElement","element","config","defaultConfig","node","data","tagName","sanitizedContent","DOMPurify","previousHTML","useInitialDOM","id","mount","targetElement","currentHTML","sanitizedHTML","fallbackEl","DOMPurify","e","state","useAnchorSingle","element","href","ariaLabel","className","childElement","sanitizedHref","sanitizedAriaLabel","hrefAttr","scrollPosition","DOMPurify","useTSCSP","scriptSrc","styleSrc","objectSrc","fontSrc","imgSrc","connectSrc","frameSrc","baseUri","reportUri","reportOnly","addOrUpdateCSPMeta","metaElement","reportUriDirective","error","useTSMetaData","config","cspConfig","metaData","DOMPurify","setName","name","updateMetaTag","setDescription","description","setAuthor","author","getName","getDescription","getAuthor","getAllMetaData","createMetaTag","content","metaTag","appendMetaTagsToHead","useTSCSP","DOMPurify","useTSComponent","id","parent","element","params","params2","selector","matches","target","useTSCollection","collections","DOM","elements","params","seenIds","id","index","matches","elementFn","param","useTSComponent","useTSSelect","selector","elements","jwtDecode","useTSAuth","_Component","loginUrl","token","decodedToken","currentTime","error","useTSElementEach","elements","events","callback","element","eventType","event","useTSNavigate","useTSOutlet","selector","outlets","outletDOM","currentPath","outlet","base","renderChildRoutes","DOM","router","pathname","route","child","childPath","createStore","createSignal","initialValue","store","listeners","newValue","listener","createEffect","effectFn","cleanup","useTSHashAnchor","links","useTSElementEach","element","e","targetId","targetElement","debounce","sanitizeInput","input","element","_enhanceAnchors","anchors","anchor","originalHref","sanitizedHref","originalClassName","ariaLabel","child","href","e","url","err","useAnchor","useTSNoReload","a","useAnchor","useTSAnchorMount","useTSNoReload","useTSHashAnchor","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","loader","placeholder","loaded","loadingPromise","ensureLoaded","mod","lazyFn","mountOrProps","maybeProps","mount","props","placeholderWrapper","err","html","DOMPurify","createStore","DOMPurify","tsParamsStore","set","params","sanitize","query","obj","output","key","TSRouter","routes","expectedParams","currentPath","currentSearch","queryParams","matchingRoute","sanitizedParams","tsParamsStore","errorElement","nestedPath","childElement","notFoundRoute","fallbackParams","children","parentElement","parentParams","matchingChild","mergedParams","nextNestedPath","search","urlSearchParams","key","value","DOMPurify","path","inheritedParams","route","routePath","paramNames","regexPattern","match","regex","params","name","index","autoRegister"]}
1
+ {"version":3,"sources":["../src/define/html.ts","../src/define/auto-register.ts","../src/hooks/useTSPurifier.ts","../src/hooks/useTSEvent.ts","../src/hooks/useTSParams.ts","../src/hooks/useTSExtract.ts","../src/hooks/useTSAllElements.ts","../src/hooks/useTSElements.ts","../src/hooks/useIntialDOM.ts","../src/hooks/useTSAnchorSingle.ts","../src/hooks/useTSMetaData.ts","../src/hooks/useTSCSP.ts","../src/hooks/useTSComponent.ts","../src/hooks/useTSCollection.ts","../src/hooks/useTSSelect.ts","../src/hooks/useTSAuth.ts","../src/hooks/useTSForEach.ts","../src/hooks/useTSNavigate.ts","../src/hooks/useTSOutlet.ts","../src/hooks/useReactivity.ts","../src/hooks/useTSHashAnchor.ts","../src/hooks/useTSAnchor.ts","../src/hooks/useTSNoReload.ts","../src/hooks/useTSAnchorMount.ts","../src/hooks/useTSInitializedBrython.ts","../src/hooks/useTSLazy.ts","../src/routes/class/Router.class.ts","../src/store/useTSParam.store.ts","../index.mts"],"sourcesContent":["export function html(strings: TemplateStringsArray, ...values: any[]): string {\r\n return strings.reduce((result, str, i) => {\r\n return result + str + (values[i] || '');\r\n }, '');\r\n}","// auto-register-runtime.ts\r\nfunction autoRegister() {\r\n const allTags = new Set<string>();\r\n document.querySelectorAll('*').forEach((el) => {\r\n const tagName = el.tagName.toLowerCase();\r\n if (!tagName.includes('-')) return; // Only register custom tags with a dash\r\n allTags.add(tagName);\r\n });\r\n\r\n allTags.forEach(tag => {\r\n if (!customElements.get(tag)) {\r\n customElements.define(tag, class extends HTMLElement {\r\n connectedCallback() {\r\n this.innerHTML = `<div style=\"padding:10px;background:#eee;\">${tag} (Auto)</div>`;\r\n }\r\n });\r\n }\r\n });\r\n}\r\n\r\n\r\nexport { autoRegister };","import DOMPurify from \"dompurify\";\r\nimport type { Config } from \"dompurify\";\r\n\r\ntype TSPurifier = (input: string | HTMLElement, config?: Config) => string;\r\n\r\nexport const useTSPurifier: TSPurifier = (\r\n input,\r\n config?\r\n) => {\r\n const defaultConfig: Config = {\r\n ADD_TAGS: [\"my-custom-tag\"],\r\n };\r\n\r\n const mergedConfig: Config = { ...defaultConfig, ...config };\r\n\r\n if (typeof input === \"string\") {\r\n return DOMPurify.sanitize(input, mergedConfig);\r\n } else {\r\n return DOMPurify.sanitize(input.innerHTML, mergedConfig);\r\n }\r\n};\r\n","type TSEvent = (\r\n id: string | Document,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: HTMLElementEventMap[keyof HTMLElementEventMap]) => void\r\n) => void;\r\n\r\nexport const useTSEvent: TSEvent = (\r\n id,\r\n eventType,\r\n handler\r\n) => {\r\n if (typeof id === 'string') {\r\n const element = document.getElementById(id);\r\n if (element) {\r\n element.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Element with id '${id}' not found.`);\r\n }\r\n } else if (id === document) {\r\n document.addEventListener(\r\n eventType,\r\n handler as EventListenerOrEventListenerObject\r\n );\r\n } else {\r\n console.warn(`Invalid id parameter provided.`);\r\n }\r\n};\r\n","// utils/hooks/useTSParams.ts\r\nimport { createStore } from 'zustand/vanilla';\r\nimport DOMPurify from 'dompurify';\r\n\r\ntype ParamStore = {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setFromPattern: (pattern: MustURL) => void;\r\n getParam: (key: string) => string | undefined;\r\n getQuery: (key: string) => string | undefined;\r\n};\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nfunction extractPatternParams(pattern: MustURL, path: string): Record<string, string> {\r\n const paramNames: string[] = [];\r\n const regexPattern = pattern.replace(/:[^/]+/g, (match) => {\r\n paramNames.push(match.slice(1));\r\n return '([^/]+)';\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}$`);\r\n const match = path.match(regex);\r\n const result: Record<string, string> = {};\r\n\r\n if (match) {\r\n paramNames.forEach((name, i) => {\r\n result[name] = DOMPurify.sanitize(match[i + 1] ?? '');\r\n });\r\n }\r\n\r\n return result;\r\n}\r\n\r\nfunction extractQueryParams(search: MustURL): Record<string, string> {\r\n const result: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n result[key] = DOMPurify.sanitize(value);\r\n }\r\n\r\n return result;\r\n}\r\n\r\nexport const useTSParams = createStore<ParamStore>((set, get) => ({\r\n params: {},\r\n query: {},\r\n setFromPattern: (pattern: MustURL) => {\r\n const path = window.location.pathname;\r\n const params = extractPatternParams(pattern, path);\r\n const query = extractQueryParams(window.location.search as MustURL);\r\n set({ params, query });\r\n },\r\n getParam: (key: string) => get().params[key],\r\n getQuery: (key: string) => get().query[key],\r\n}));\r\n","import { useTSParams } from './useTSParams';\r\n\r\ntype MustURL = `/${string}`;\r\n\r\nexport function useTSExtractParams(pattern: MustURL) {\r\n const store = useTSParams.getState();\r\n\r\n // Populate internal param/query store\r\n store.setFromPattern(pattern);\r\n\r\n const params = store.params;\r\n const query = store.query;\r\n\r\n return { ...params, ...query };\r\n}\r\n","export const useTSEventAll = <T extends Event>(\r\n selector: string,\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements = document.querySelectorAll(selector);\r\n elements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n\r\n return () => {\r\n elements.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n };\r\n};\r\n\r\nexport const useTSEventSelectAll = <T extends Event>(\r\n selectors: string[],\r\n eventType: keyof HTMLElementEventMap,\r\n handler: (event: T) => void\r\n) => {\r\n const elements: NodeListOf<HTMLElement>[] = [];\r\n\r\n selectors.forEach(selector => {\r\n const selectedElements = document.querySelectorAll(\r\n selector\r\n ) as NodeListOf<HTMLElement>;\r\n selectedElements.forEach(element => {\r\n element.addEventListener(eventType, handler as EventListener);\r\n });\r\n elements.push(selectedElements);\r\n });\r\n\r\n return () => {\r\n elements.forEach(nodeList => {\r\n nodeList.forEach(element => {\r\n element.removeEventListener(eventType, handler as EventListener);\r\n });\r\n });\r\n };\r\n};\r\n","import DOMPurify, { Config } from \"dompurify\";\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (htmlElement, element, config) => {\r\n const defaultConfig: Config = {\r\n USE_PROFILES: { svg: true, html: true },\r\n ALLOWED_TAGS: [\r\n \"svg\", \"path\", \"circle\", \"rect\", \"line\", \"polyline\", \"polygon\", \"g\",\r\n \"main\", \"div\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"p\", \"button\", \"span\", \"a\", \"img\", \"input\", \"ul\", \"li\", \"i\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"class\", \"id\", \"href\", \"src\", \"alt\", \"fill\", \"stroke\", \"stroke-width\",\r\n \"viewBox\", \"xmlns\", \"d\", \"x\", \"y\", \"cx\", \"cy\", \"r\", \"width\", \"height\"\r\n ],\r\n FORBID_TAGS: [\"script\", \"iframe\"],\r\n ALLOWED_URI_REGEXP:\r\n /^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\\-]+(?:[^a-z+.\\-:]|$))/i,\r\n ...config,\r\n };\r\n\r\n // ✅ Allow custom elements dynamically\r\n DOMPurify.addHook(\"uponSanitizeElement\", (node, data) => {\r\n const tagName = data.tagName.toLowerCase();\r\n if (tagName.includes(\"-\")) {\r\n data.allowedTags[tagName] = true;\r\n }\r\n });\r\n\r\n // ✅ Strip dangerous event handlers\r\n DOMPurify.addHook(\"uponSanitizeAttribute\", (node, data) => {\r\n if (data.attrName && data.attrName.toLowerCase().startsWith(\"on\")) {\r\n data.keepAttr = false;\r\n }\r\n });\r\n\r\n const sanitizedContent = DOMPurify.sanitize(element, defaultConfig);\r\n\r\n if (htmlElement.innerHTML !== sanitizedContent) {\r\n htmlElement.innerHTML = sanitizedContent;\r\n }\r\n};\r\n\r\n","import DOMPurify from \"dompurify\"\r\n\r\nlet previousHTML: string | null = null\r\n\r\ntype TSInitialDOM = (id: string, mount: (el: HTMLElement) => void) => void;\r\n\r\nexport const useInitialDOM: TSInitialDOM = (id, mount) => {\r\n // SSR guard\r\n if (typeof document === \"undefined\") return\r\n\r\n const targetElement = document.getElementById(id)\r\n if (!targetElement) return\r\n\r\n const currentHTML = targetElement.innerHTML\r\n const sanitizedHTML = DOMPurify.sanitize(currentHTML)\r\n\r\n if (previousHTML !== null && sanitizedHTML !== previousHTML) {\r\n // DOM changed externally — reset and remount in a temp container\r\n const fallbackEl = document.createElement(\"div\")\r\n mount(fallbackEl)\r\n targetElement.innerHTML = previousHTML\r\n } else {\r\n // First time or same sanitized DOM — mount to target\r\n previousHTML = sanitizedHTML\r\n mount(targetElement)\r\n }\r\n}\r\n","import DOMPurify from \"dompurify\";\r\n\r\ndeclare global {\r\n interface Window {\r\n __anchorSinglePopstateHandlerAttached?: boolean;\r\n }\r\n}\r\n\r\ntype AnchorSingle = (\r\n element: HTMLAnchorElement | null,\r\n href: string,\r\n ariaLabel: string,\r\n className?: string,\r\n childElement?: HTMLElement | null\r\n) => void;\r\n\r\n// Attach popstate listener only in the browser\r\nif (typeof window !== \"undefined\" && !window.__anchorSinglePopstateHandlerAttached) {\r\n window.addEventListener(\"popstate\", (e) => {\r\n const state = e.state as { scrollPosition?: number };\r\n if (state?.scrollPosition !== undefined) {\r\n window.scrollTo(0, state.scrollPosition);\r\n }\r\n });\r\n window.__anchorSinglePopstateHandlerAttached = true;\r\n}\r\n\r\nexport const useAnchorSingle: AnchorSingle = (\r\n element,\r\n href,\r\n ariaLabel,\r\n className = \"\",\r\n childElement = null\r\n) => {\r\n if (!element) return;\r\n\r\n // Sanitize string inputs\r\n const sanitizedHref = DOMPurify.sanitize(href, { ALLOWED_URI_REGEXP: /^(https?:|\\/)/ });\r\n const sanitizedAriaLabel = DOMPurify.sanitize(ariaLabel, { USE_PROFILES: { html: false } });\r\n\r\n element.setAttribute(\"href\", sanitizedHref);\r\n element.setAttribute(\"aria-label\", sanitizedAriaLabel);\r\n\r\n if (className) {\r\n element.className = className.trim();\r\n }\r\n\r\n if (childElement) {\r\n element.replaceChildren(childElement);\r\n }\r\n\r\n // Event binding only in browser\r\n if (typeof window !== \"undefined\") {\r\n element.addEventListener(\"click\", (e) => {\r\n e.preventDefault();\r\n const target = e.currentTarget as HTMLAnchorElement;\r\n const hrefAttr = target.getAttribute(\"href\");\r\n if (hrefAttr) {\r\n const scrollPosition = window.scrollY;\r\n window.scrollTo(0, 0);\r\n window.history.pushState({ scrollPosition }, \"\", hrefAttr);\r\n dispatchEvent(new PopStateEvent(\"popstate\"));\r\n }\r\n });\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\nimport { useTSCSP } from \"./useTSCSP\";\r\n\r\ntype SEOConfig = {\r\n name?: string;\r\n description?: string;\r\n author?: string;\r\n}\r\n\r\ntype CSPConfig = {\r\n scriptSrc?: string;\r\n styleSrc?: string;\r\n objectSrc?: string;\r\n connectSrc?: string[];\r\n reportOnly?: boolean;\r\n}\r\n\r\ntype SEOHandler = {\r\n setName: (name: string) => void;\r\n setDescription: (description: string) => void;\r\n setAuthor: (author: string) => void;\r\n getName: () => string;\r\n getDescription: () => string;\r\n getAuthor: () => string;\r\n getAllMetaData: () => SEOConfig;\r\n appendMetaTagsToHead: () => void;\r\n}\r\n\r\nexport const useTSMetaData = (\r\n config: SEOConfig,\r\n cspConfig?: CSPConfig\r\n): SEOHandler => {\r\n let metaData: SEOConfig = {\r\n name: DOMPurify.sanitize(config.name || \"\"),\r\n description: DOMPurify.sanitize(\r\n config.description || \"Default description\"\r\n ),\r\n author: DOMPurify.sanitize(config.author || \"\"),\r\n };\r\n\r\n const setName = (name: string): void => {\r\n metaData.name = DOMPurify.sanitize(name);\r\n updateMetaTag(\"name\", metaData.name);\r\n };\r\n\r\n const setDescription = (description: string): void => {\r\n metaData.description = DOMPurify.sanitize(description);\r\n updateMetaTag(\"description\", metaData.description);\r\n };\r\n\r\n const setAuthor = (author: string): void => {\r\n metaData.author = DOMPurify.sanitize(author);\r\n updateMetaTag(\"author\", metaData.author);\r\n };\r\n\r\n const getName = (): string => {\r\n return metaData.name!;\r\n };\r\n\r\n const getDescription = (): string => {\r\n return metaData.description!;\r\n };\r\n\r\n const getAuthor = (): string => {\r\n return metaData.author!;\r\n };\r\n\r\n const getAllMetaData = (): SEOConfig => {\r\n return metaData;\r\n };\r\n\r\n const createMetaTag = (name: string, content: string) => {\r\n const metaTag = document.createElement(\"meta\");\r\n metaTag.setAttribute(\"name\", name);\r\n metaTag.setAttribute(\"content\", content);\r\n document.head.appendChild(metaTag);\r\n };\r\n\r\n const updateMetaTag = (name: string, content: string) => {\r\n let metaTag = document.querySelector(`meta[name=\"${name}\"]`);\r\n if (metaTag) {\r\n metaTag.setAttribute(\"content\", content);\r\n } else {\r\n createMetaTag(name, content);\r\n }\r\n };\r\n\r\n const appendMetaTagsToHead = () => {\r\n updateMetaTag(\"name\", metaData.name!);\r\n updateMetaTag(\"description\", metaData.description!);\r\n updateMetaTag(\"author\", metaData.author!);\r\n };\r\n\r\n // Integrate with useTSCSP for CSP enforcement\r\n if (cspConfig) {\r\n useTSCSP(\r\n cspConfig.scriptSrc,\r\n cspConfig.styleSrc,\r\n cspConfig.objectSrc,\r\n Array.isArray(cspConfig.connectSrc) ? cspConfig.connectSrc.join(\" \") : cspConfig.connectSrc,\r\n cspConfig.reportOnly !== undefined ? String(cspConfig.reportOnly) : undefined\r\n );\r\n }\r\n\r\n appendMetaTagsToHead();\r\n\r\n return {\r\n setName,\r\n setDescription,\r\n setAuthor,\r\n getName,\r\n getDescription,\r\n getAuthor,\r\n getAllMetaData,\r\n appendMetaTagsToHead,\r\n };\r\n};\r\n","export const useTSCSP = (\r\n scriptSrc = `'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'`,\r\n styleSrc = \"'self' 'nonce-rAnd0m123'\", // Use nonce for inline styles\r\n objectSrc = \"'none'\",\r\n fontSrc = \"'self' https://fonts.googleapis.com https://fonts.gstatic.com\",\r\n imgSrc = \"'self' https://blogger.googleusercontent.com\",\r\n connectSrc = [\r\n \"'self'\",\r\n \"https://fonts.googleapis.com\",\r\n \"https://fonts.gstatic.com\",\r\n \"https://www.google.com/maps/\",\r\n ],\r\n frameSrc = \"'self' https://www.youtube.com\", // Add frame-src for embedding\r\n baseUri = \"'self'\",\r\n reportUri = \"/csp-report\",\r\n reportOnly = false\r\n) => {\r\n const addOrUpdateCSPMeta = () => {\r\n try {\r\n let metaElement = document.querySelector(\r\n 'meta[http-equiv=\"Content-Security-Policy\"]'\r\n );\r\n if (!metaElement) {\r\n metaElement = document.createElement(\"meta\");\r\n metaElement.setAttribute(\"http-equiv\", \"Content-Security-Policy\");\r\n document.head.appendChild(metaElement);\r\n }\r\n\r\n const reportUriDirective = reportOnly ? `report-uri ${reportUri};` : \"\";\r\n metaElement.setAttribute(\r\n \"content\",\r\n `default-src 'self'; script-src ${scriptSrc}; style-src ${styleSrc}; object-src ${objectSrc}; font-src ${fontSrc}; img-src ${imgSrc}; connect-src ${connectSrc.join(\r\n \" \"\r\n )}; frame-src ${frameSrc}; base-uri ${baseUri}; ${reportUriDirective}`\r\n );\r\n } catch (error) {\r\n console.error(\"Error adding CSP meta element:\", error);\r\n }\r\n };\r\n\r\n if (document.readyState === \"loading\") {\r\n document.addEventListener(\"DOMContentLoaded\", addOrUpdateCSPMeta);\r\n } else {\r\n addOrUpdateCSPMeta();\r\n }\r\n};\r\n","import DOMPurify from \"dompurify\";\r\n\r\ntype TSComponent = (\r\n id: string,\r\n parent: HTMLElement,\r\n element: Function,\r\n params?: any,\r\n params2?: any\r\n) => void;\r\n\r\nexport const useTSComponent: TSComponent = (\r\n id,\r\n parent,\r\n element,\r\n params,\r\n params2\r\n) => {\r\n const selector = `#${id}`;\r\n const matches = parent.querySelectorAll<HTMLElement>(selector);\r\n\r\n // 1. Missing element check\r\n if (matches.length === 0) {\r\n throw new Error(`[useTSComponent] No element found with id '${id}' in the given parent.`);\r\n }\r\n\r\n // 2. Duplicate ID check\r\n if (matches.length > 1) {\r\n throw new Error(`[useTSComponent] Duplicate id '${id}' detected. Found ${matches.length} elements.`);\r\n }\r\n\r\n const target = matches[0];\r\n\r\n // 3. Sanitize the target’s existing HTML content\r\n target.innerHTML = DOMPurify.sanitize(target.innerHTML, { USE_PROFILES: { html: true } });\r\n\r\n // 4. Call the component function with the target\r\n element(target, params, params2);\r\n};\r\n","import { useTSComponent } from \"./useTSComponent\";\r\n\r\ntype TSCollection = (\r\n collections: string[],\r\n DOM: HTMLElement,\r\n elements: Function[],\r\n params?: any[]\r\n) => void;\r\n\r\nexport const useTSCollection: TSCollection = (\r\n collections,\r\n DOM,\r\n elements,\r\n params = []\r\n) => {\r\n const seenIds = new Set<string>();\r\n\r\n collections.forEach((id, index) => {\r\n // Check for duplicate IDs in the collection list itself\r\n if (seenIds.has(id)) {\r\n console.warn(`[useTSCollection] Duplicate ID in collection array: \"${id}\" — skipping.`);\r\n return;\r\n }\r\n seenIds.add(id);\r\n\r\n // Check for duplicates already in DOM\r\n const matches = DOM.querySelectorAll(`#${id}`);\r\n if (matches.length > 1) {\r\n console.warn(\r\n `[useTSCollection] Duplicate ID in DOM: \"${id}\" (${matches.length} elements found) — skipping component mount.`\r\n );\r\n return;\r\n }\r\n\r\n const elementFn = elements[index];\r\n const param = Array.isArray(params) ? params[index] : undefined;\r\n\r\n if (typeof elementFn === \"function\") {\r\n useTSComponent(id, DOM, elementFn, param);\r\n } else {\r\n console.warn(`[useTSCollection] No valid component function found for ID: \"${id}\"`);\r\n }\r\n });\r\n};\r\n","type TSSelect = <T extends Element = HTMLElement>(selector: string) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(selector: string): T | null => {\r\n const elements = document.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n throw new Error(\r\n `[useTSSelect] Duplicate ID detected: '${selector}'. Found ${elements.length} elements with this ID.`\r\n );\r\n }\r\n\r\n if (elements.length > 1) {\r\n console.warn(\r\n `[useTSSelect] Multiple elements found for selector: '${selector}'. Returning the first one.`\r\n );\r\n }\r\n\r\n return elements[0];\r\n};\r\n\r\nexport { useTSSelect };\r\n","import { jwtDecode } from \"jwt-decode\";\r\n\r\nexport const useTSAuth = (_Component: HTMLElement | void, loginUrl: string) => {\r\n const token = localStorage.getItem(\"token\");\r\n\r\n if (!token) {\r\n // Redirect to login page if token is missing\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n try {\r\n const decodedToken: any = jwtDecode(token);\r\n\r\n // Example: Check if the token has expired\r\n const currentTime = Date.now() / 1000;\r\n if (decodedToken.exp && decodedToken.exp < currentTime) {\r\n console.error(\"Token has expired\");\r\n window.localStorage.removeItem(\"token\");\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n\r\n // If the user is authenticated, return the component\r\n return null;\r\n } catch (error) {\r\n console.error(\"Invalid token:\", error);\r\n // Redirect to login page if token decoding fails\r\n window.location.href = loginUrl;\r\n return null; // Return null when redirecting\r\n }\r\n};\r\n","\r\ntype TSElementEach = (\r\n elements: NodeListOf<HTMLElement> | HTMLElement[],\r\n events: (keyof HTMLElementEventMap)[],\r\n callback: (element: HTMLElement, event: Event) => void\r\n) => void;\r\n\r\nexport const useTSElementEach: TSElementEach = (\r\n elements,\r\n events,\r\n callback\r\n) => {\r\n elements.forEach(element => {\r\n events.forEach(eventType => {\r\n element.addEventListener(eventType, event => {\r\n callback(element, event);\r\n });\r\n });\r\n });\r\n};\r\n","export const useTSNavigate = () => {\r\n const back = () => window.history.back();\r\n const forward = () => window.history.forward();\r\n\r\n return {\r\n back,\r\n forward,\r\n };\r\n};\r\n","// types.ts\r\nexport type OutletComponent = (DOM: HTMLElement) => void;\r\n\r\nexport type ChildRoute = {\r\n path: string;\r\n outlet: string;\r\n element: OutletComponent;\r\n};\r\n\r\nexport type Route = {\r\n path: string;\r\n element: (DOM: HTMLElement) => void;\r\n children?: ChildRoute[];\r\n};\r\n\r\n// You don't actually need to import the class TSRouter type.\r\n// Instead, export a cleaner interface with routes.\r\nexport interface RouterInstance {\r\n routes: Route[];\r\n}\r\n\r\n\r\ntype OutletOptions = {\r\n path: string;\r\n component: OutletComponent;\r\n};\r\n\r\nexport const useTSOutlet = (\r\n selector: string,\r\n outlets: OutletOptions[]\r\n): void => {\r\n const outletDOM = document.querySelector<HTMLElement>(`#${selector}`)\r\n || document.querySelector<HTMLElement>(`.${selector}`);\r\n\r\n if (!outletDOM) return;\r\n\r\n const currentPath = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n for (const outlet of outlets) {\r\n const base = outlet.path.replace(/\\/$/, \"\");\r\n\r\n // Match exact or nested path (e.g., /openai/child/1)\r\n if (currentPath === base || currentPath.startsWith(`${base}/`)) {\r\n outlet.component(outletDOM);\r\n break;\r\n }\r\n }\r\n};\r\n\r\n\r\nexport function renderChildRoutes(DOM: HTMLElement, router: RouterInstance): void {\r\n const pathname = window.location.pathname.replace(/\\/$/, \"\");\r\n\r\n router.routes.forEach((route) => {\r\n if (!route.children?.length) return;\r\n\r\n route.children.forEach((child) => {\r\n const childPath = child.path.replace(/\\/$/, \"\");\r\n\r\n if (pathname === childPath || pathname.startsWith(`${childPath}/`)) {\r\n const outlet = DOM.querySelector(`#${child.outlet}`)\r\n || DOM.querySelector(`.${child.outlet}`);\r\n if (outlet instanceof HTMLElement && child.element) {\r\n child.element(outlet);\r\n }\r\n }\r\n });\r\n });\r\n}","// useTSReactivity.ts\r\nimport { createStore } from 'zustand/vanilla';\r\n\r\ntype Listener<T> = (value: T) => void;\r\n\r\ninterface Signal<T> {\r\n get: () => T;\r\n set: (newValue: T) => void;\r\n subscribe: (listener: Listener<T>) => () => void;\r\n}\r\n\r\nexport function createSignal<T>(initialValue: T): Signal<T> {\r\n const store = createStore<{ value: T }>(() => ({ value: initialValue }));\r\n const listeners = new Set<Listener<T>>();\r\n\r\n return {\r\n get: () => store.getState().value,\r\n set: (newValue: T) => {\r\n store.setState({ value: newValue });\r\n listeners.forEach((listener) => listener(newValue));\r\n },\r\n subscribe: (listener: Listener<T>) => {\r\n listeners.add(listener);\r\n listener(store.getState().value); // Trigger immediately\r\n return () => listeners.delete(listener);\r\n },\r\n };\r\n}\r\n\r\ntype CleanupFn = () => void;\r\n\r\nexport function createEffect(effectFn: () => void | CleanupFn): void {\r\n const cleanup = effectFn();\r\n\r\n // Optional: return a way to dispose the effect manually\r\n if (typeof cleanup === 'function') {\r\n // You may store this and call it later if needed\r\n cleanup();\r\n }\r\n}\r\n","import { useTSElementEach } from './useTSForEach';\r\n\r\n\r\nconst useTSHashAnchor = () => {\r\n const links = document.querySelectorAll<HTMLAnchorElement>('a[href^=\"#\"]');\r\n\r\n useTSElementEach(\r\n links,\r\n ['click'],\r\n (element, e) => {\r\n e.preventDefault();\r\n const targetId = element.getAttribute('href')?.substring(1);\r\n const targetElement = targetId ? document.getElementById(targetId) : null;\r\n\r\n if (targetElement) {\r\n targetElement.scrollIntoView({\r\n behavior: 'smooth',\r\n block: 'start'\r\n });\r\n }\r\n }\r\n );\r\n}\r\n\r\nexport { useTSHashAnchor }","import { debounce } from 'lodash-es';\r\n\r\nlet sanitizeInput = (input: string): string => input;\r\n\r\nif (typeof window !== 'undefined' && typeof document !== 'undefined') {\r\n sanitizeInput = (input: string): string => {\r\n const element = document.createElement(\"div\");\r\n element.innerText = input;\r\n return element.innerHTML;\r\n };\r\n}\r\n\r\ntype AnchorInput =\r\n | NodeListOf<HTMLAnchorElement>\r\n | HTMLAnchorElement[]\r\n | HTMLAnchorElement\r\n | null\r\n | undefined;\r\n\r\nconst _enhanceAnchors = debounce((anchors: AnchorInput) => {\r\n const resolvedAnchors: HTMLAnchorElement[] = (() => {\r\n if (!anchors) return Array.from(document.querySelectorAll(\"a\"));\r\n if (Array.isArray(anchors)) return anchors;\r\n if (anchors instanceof HTMLAnchorElement) return [anchors];\r\n return Array.from(anchors);\r\n })();\r\n\r\n resolvedAnchors.forEach(anchor => {\r\n if (!anchor || anchor.dataset.anchorEnhanced === 'true') return;\r\n anchor.dataset.anchorEnhanced = 'true';\r\n\r\n // Sanitize attributes\r\n const originalHref = anchor.getAttribute(\"href\") || \"#\";\r\n const sanitizedHref = sanitizeInput(originalHref);\r\n anchor.setAttribute(\"href\", sanitizedHref);\r\n\r\n const originalClassName = anchor.getAttribute(\"class\") || \"\";\r\n anchor.setAttribute(\"class\", sanitizeInput(originalClassName));\r\n\r\n const ariaLabel = anchor.getAttribute(\"aria-label\");\r\n if (ariaLabel) {\r\n anchor.setAttribute(\"aria-label\", sanitizeInput(ariaLabel));\r\n }\r\n\r\n // Keep child elements safe (optional — you can remove this block if not needed)\r\n const child = anchor.querySelector(\":scope > *\") as HTMLElement;\r\n if (child) {\r\n anchor.innerHTML = \"\";\r\n anchor.appendChild(child);\r\n }\r\n\r\n // Skip attaching click listener if:\r\n // - It's a hash link (in-page navigation)\r\n // - It's an external link\r\n const href = anchor.getAttribute(\"href\") || \"\";\r\n if (href.startsWith(\"#\")) return; // Let browser handle hash scrolling normally\r\n\r\n try {\r\n const url = new URL(href, window.location.href);\r\n if (url.origin !== window.location.origin) return; // external link\r\n } catch {\r\n return; // invalid URL — skip\r\n }\r\n\r\n // Intercept same-origin navigation for SPA\r\n anchor.addEventListener(\"click\", (e: MouseEvent) => {\r\n e.preventDefault();\r\n try {\r\n const url = new URL(href, window.location.href);\r\n window.history.pushState({}, \"\", url.pathname + url.search + url.hash);\r\n window.dispatchEvent(new PopStateEvent(\"popstate\"));\r\n } catch (err) {\r\n console.error(\"Invalid URL in anchor:\", href, err);\r\n }\r\n });\r\n });\r\n}, 50);\r\n\r\nexport const useAnchor = (anchors?: AnchorInput): void => {\r\n _enhanceAnchors(anchors);\r\n};\r\n","import { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = () => {\r\n const a = document.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n return useAnchor(a);\r\n}\r\n\r\nexport { useTSNoReload };","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = () => {\r\n useTSNoReload();\r\n useTSHashAnchor();\r\n};\r\n\r\nexport { useTSAnchorMount };","// src/loadBrython.ts\r\ntype LoadBrython = (src: string) => Promise<void>;\r\n\r\ndeclare global {\r\n interface Window {\r\n brython: Function;\r\n }\r\n}\r\n\r\nconst useTSloadBrython = async () => {\r\n const brythonJS = \"https://cdn.jsdelivr.net/npm/brython@3/brython.min.js\";\r\n const brythonStdlib = \"https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js\";\r\n\r\n // Utility function to load a script\r\n const loadScript: LoadBrython = (src) => {\r\n return new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.src = src;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.head.appendChild(script);\r\n });\r\n };\r\n\r\n // Load both scripts sequentially\r\n await loadScript(brythonJS);\r\n await loadScript(brythonStdlib);\r\n\r\n // Call brython() after scripts are loaded\r\n if (typeof window.brython === \"function\") {\r\n window.brython();\r\n } else {\r\n console.error(\"Brython did not load correctly.\");\r\n }\r\n};\r\n\r\ntype RequirePy = `${string}.py`;\r\n\r\ntype LoadPy = (src: RequirePy) => Promise<void>;\r\n\r\nconst loadPyFiles: LoadPy = (src) =>\r\n new Promise((resolve, reject) => {\r\n const script = document.createElement(\"script\");\r\n script.type = \"text/python\";\r\n script.src = `/src/python/${src}`;\r\n script.onload = () => resolve();\r\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\r\n document.body.appendChild(script);\r\n });\r\n\r\nexport { useTSloadBrython, loadPyFiles };\r\n","export function useTSLazy(factory: () => Promise<any>) {\r\n let cached: any | null = null;\r\n\r\n return async (el: HTMLElement, props?: any) => {\r\n try {\r\n if (!cached) {\r\n const mod = await factory();\r\n cached = mod.default || mod;\r\n }\r\n\r\n // If it's a component function (Vanilla TS style)\r\n if (typeof cached === \"function\") {\r\n return cached(el, props);\r\n }\r\n\r\n // If it's already an HTMLElement\r\n if (cached instanceof HTMLElement) {\r\n el.appendChild(cached);\r\n return;\r\n }\r\n\r\n // If it's a plain object with render()\r\n if (cached && typeof cached.render === \"function\") {\r\n return cached.render(el, props);\r\n }\r\n\r\n console.warn(\"useTSLazy: Unsupported module type\", cached);\r\n } catch (err) {\r\n console.error(\"useTSLazy failed:\", err);\r\n }\r\n };\r\n}\r\n","import DOMPurify from \"dompurify\";\r\nimport { tsParamsStore } from \"../../store\";\r\n\r\ntype RouteCallback = (\r\n errorElement?: HTMLElement,\r\n params?: Record<string, string>,\r\n query?: Record<string, string>\r\n) => void;\r\n\r\ninterface RouteConfig {\r\n path: string;\r\n routeto?: string;\r\n element: RouteCallback;\r\n errorElement?: RouteCallback;\r\n children?: RouteConfig[];\r\n params?: Record<string, string>;\r\n}\r\n\r\nexport class TSRouter {\r\n private routes: RouteConfig[] = [];\r\n private expectedParams: Set<string>;\r\n\r\n constructor(routes: RouteConfig[], expectedParams: string[]) {\r\n this.routes = routes;\r\n this.expectedParams = new Set(expectedParams);\r\n window.addEventListener(\"popstate\", this.handlePopState.bind(this));\r\n this.handlePopState(); // Initial load\r\n }\r\n\r\n private handlePopState() {\r\n const currentPath = window.location.pathname;\r\n const currentSearch = window.location.search;\r\n const queryParams = this.parseQueryParams(currentSearch);\r\n\r\n const matchingRoute = this.findMatchingRoute(currentPath, this.routes);\r\n\r\n if (matchingRoute) {\r\n if (matchingRoute.routeto) {\r\n this.navigate(matchingRoute.routeto);\r\n return;\r\n }\r\n\r\n const sanitizedParams = this.filterAndSanitizeParams(matchingRoute.params);\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n\r\n matchingRoute.element?.(errorElement, sanitizedParams, queryParams);\r\n\r\n if (matchingRoute.children) {\r\n const nestedPath = currentPath.slice(matchingRoute.path.length);\r\n const childElement = errorElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) {\r\n this.renderChildren(\r\n matchingRoute.children,\r\n nestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n } else {\r\n const notFoundRoute = this.findMatchingRoute(\"*\", this.routes);\r\n if (notFoundRoute) {\r\n const fallbackParams = this.filterAndSanitizeParams(notFoundRoute.params);\r\n tsParamsStore.getState().setParams(fallbackParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n const errorElement = document.createElement(\"div\");\r\n notFoundRoute.element?.(errorElement, fallbackParams, queryParams);\r\n }\r\n }\r\n }\r\n\r\n private renderChildren(\r\n children: RouteConfig[] | undefined,\r\n nestedPath: string,\r\n parentElement: HTMLElement,\r\n parentParams: Record<string, string>,\r\n queryParams: Record<string, string>\r\n ) {\r\n if (!children || children.length === 0) {\r\n const childElement = parentElement.querySelector(\"#child\") as HTMLDivElement;\r\n if (childElement) childElement.remove();\r\n return;\r\n }\r\n\r\n const matchingChild = this.findMatchingRoute(nestedPath, children);\r\n if (matchingChild) {\r\n const childElement = document.createElement(\"div\");\r\n childElement.id = \"child\";\r\n const mergedParams = { ...parentParams, ...matchingChild.params };\r\n const sanitizedParams = this.filterAndSanitizeParams(mergedParams);\r\n\r\n tsParamsStore.getState().setParams(sanitizedParams);\r\n tsParamsStore.getState().setQuery(queryParams);\r\n\r\n matchingChild.element?.(childElement, sanitizedParams, queryParams);\r\n parentElement.appendChild(childElement);\r\n\r\n if (matchingChild.children) {\r\n const nextNestedPath = nestedPath.slice(matchingChild.path.length);\r\n this.renderChildren(\r\n matchingChild.children,\r\n nextNestedPath,\r\n childElement,\r\n sanitizedParams,\r\n queryParams\r\n );\r\n }\r\n }\r\n }\r\n\r\n private parseQueryParams(search: string): Record<string, string> {\r\n const queryParams: Record<string, string> = {};\r\n const urlSearchParams = new URLSearchParams(search);\r\n\r\n for (const [key, value] of urlSearchParams.entries()) {\r\n if (this.expectedParams.has(key)) {\r\n queryParams[key] = DOMPurify.sanitize(value);\r\n }\r\n }\r\n\r\n return queryParams;\r\n }\r\n\r\n private findMatchingRoute(\r\n path: string,\r\n routes: RouteConfig[],\r\n inheritedParams: Record<string, string> = {}\r\n ): RouteConfig | undefined {\r\n for (const route of routes) {\r\n const routePath = route.path;\r\n const isDefaultRoute = routePath === \"*\";\r\n\r\n if (!isDefaultRoute) {\r\n const paramNames: string[] = [];\r\n const regexPattern = routePath.replace(/:[^\\s/]+/g, match => {\r\n paramNames.push(match.substring(1));\r\n return \"([^\\\\s/]+)\";\r\n });\r\n\r\n const regex = new RegExp(`^${regexPattern}(?:/|$)`);\r\n const match = path.match(regex);\r\n\r\n if (match) {\r\n const params: Record<string, string> = { ...inheritedParams };\r\n paramNames.forEach((name, index) => {\r\n params[name] = match[index + 1] ?? \"\";\r\n });\r\n\r\n if (route.children) {\r\n const nestedPath = path.slice(match[0].length);\r\n const matchingChild = this.findMatchingRoute(\r\n nestedPath,\r\n route.children,\r\n params\r\n );\r\n if (matchingChild) return matchingChild;\r\n }\r\n\r\n return { ...route, params };\r\n }\r\n } else {\r\n return route;\r\n }\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n private filterAndSanitizeParams(\r\n params?: Record<string, string>\r\n ): Record<string, string> {\r\n if (!params) return {};\r\n const sanitizedParams: Record<string, string> = {};\r\n for (const key in params) {\r\n if (this.expectedParams.has(key)) {\r\n sanitizedParams[key] = DOMPurify.sanitize(params[key] ?? \"\");\r\n }\r\n }\r\n return sanitizedParams;\r\n }\r\n\r\n navigate(path: string) {\r\n history.pushState(null, \"\", path);\r\n this.handlePopState();\r\n }\r\n\r\n addRoute(route: RouteConfig) {\r\n this.routes.push(route);\r\n }\r\n}\r\n","import { createStore } from \"zustand/vanilla\";\r\nimport DOMPurify from \"dompurify\";\r\n\r\ninterface TSParamsState {\r\n params: Record<string, string>;\r\n query: Record<string, string>;\r\n setParams: (params: Record<string, string>) => void;\r\n setQuery: (query: Record<string, string>) => void;\r\n}\r\n\r\nexport const tsParamsStore = createStore<TSParamsState>((set) => ({\r\n params: {},\r\n query: {},\r\n setParams: (params) =>\r\n set(() => ({\r\n params: sanitize(params),\r\n })),\r\n setQuery: (query) =>\r\n set(() => ({\r\n query: sanitize(query),\r\n })),\r\n}));\r\n\r\nfunction sanitize(obj: Record<string, string>): Record<string, string> {\r\n const output: Record<string, string> = {};\r\n for (const key in obj) {\r\n output[key] = DOMPurify.sanitize(obj[key]);\r\n }\r\n return output;\r\n}\r\n","import { autoRegister } from './src/define';\r\n\r\nexport { html } from './src/define';\r\nexport { createEffect, createSignal, renderChildRoutes, useTSLazy, useTSOutlet, useTSloadBrython, loadPyFiles, useTSNavigate, useTSMetaData, useTSSelect, useTSCollection, useTSComponent, useTSAuth, useTSElementEach, useInitialDOM, useAnchorSingle, useTSPurifier, useTSEvent, useTSExtractParams, useTSParams, useTSEventAll, useTSElements, useTSAnchorMount } from \"./src/hooks\"\r\nexport { TSRouter } from \"./src/routes/class/Router.class\";\r\n\r\nif (typeof window !== 'undefined') {\r\n window.addEventListener('popstate', () => {\r\n autoRegister();\r\n });\r\n document.addEventListener('DOMContentLoaded', autoRegister);\r\n}\r\n\r\n"],"mappings":"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","names":["html","strings","values","result","str","i","autoRegister","allTags","el","tagName","tag","DOMPurify","useTSPurifier","input","config","mergedConfig","useTSEvent","id","eventType","handler","element","createStore","DOMPurify","extractPatternParams","pattern","path","paramNames","regexPattern","match","regex","result","name","i","extractQueryParams","search","urlSearchParams","key","value","useTSParams","set","get","params","query","useTSExtractParams","pattern","store","useTSParams","params","query","useTSEventAll","selector","eventType","handler","elements","element","DOMPurify","useTSElements","htmlElement","element","config","defaultConfig","node","data","tagName","sanitizedContent","DOMPurify","previousHTML","useInitialDOM","id","mount","targetElement","currentHTML","sanitizedHTML","fallbackEl","DOMPurify","e","state","useAnchorSingle","element","href","ariaLabel","className","childElement","sanitizedHref","sanitizedAriaLabel","hrefAttr","scrollPosition","DOMPurify","useTSCSP","scriptSrc","styleSrc","objectSrc","fontSrc","imgSrc","connectSrc","frameSrc","baseUri","reportUri","reportOnly","addOrUpdateCSPMeta","metaElement","reportUriDirective","error","useTSMetaData","config","cspConfig","metaData","DOMPurify","setName","name","updateMetaTag","setDescription","description","setAuthor","author","getName","getDescription","getAuthor","getAllMetaData","createMetaTag","content","metaTag","appendMetaTagsToHead","useTSCSP","DOMPurify","useTSComponent","id","parent","element","params","params2","selector","matches","target","useTSCollection","collections","DOM","elements","params","seenIds","id","index","matches","elementFn","param","useTSComponent","useTSSelect","selector","elements","jwtDecode","useTSAuth","_Component","loginUrl","token","decodedToken","currentTime","error","useTSElementEach","elements","events","callback","element","eventType","event","useTSNavigate","useTSOutlet","selector","outlets","outletDOM","currentPath","outlet","base","renderChildRoutes","DOM","router","pathname","route","child","childPath","createStore","createSignal","initialValue","store","listeners","newValue","listener","createEffect","effectFn","cleanup","useTSHashAnchor","links","useTSElementEach","element","e","targetId","targetElement","debounce","sanitizeInput","input","element","_enhanceAnchors","anchors","anchor","originalHref","sanitizedHref","originalClassName","ariaLabel","child","href","e","url","err","useAnchor","useTSNoReload","a","useAnchor","useTSAnchorMount","useTSNoReload","useTSHashAnchor","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","factory","cached","el","props","mod","err","DOMPurify","createStore","DOMPurify","tsParamsStore","set","params","sanitize","query","obj","output","key","TSRouter","routes","expectedParams","currentPath","currentSearch","queryParams","matchingRoute","sanitizedParams","tsParamsStore","errorElement","nestedPath","childElement","notFoundRoute","fallbackParams","children","parentElement","parentParams","matchingChild","mergedParams","nextNestedPath","search","urlSearchParams","key","value","DOMPurify","path","inheritedParams","route","routePath","paramNames","regexPattern","match","regex","params","name","index","autoRegister"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devwareng/vanilla-ts",
3
- "version": "1.2.118",
3
+ "version": "1.2.120",
4
4
  "description": "Framework-less TypeScript hooks for SPA development.",
5
5
  "author": "Waren Arapoc Gador",
6
6
  "license": "MIT",
@@ -29,6 +29,7 @@
29
29
  "frontend"
30
30
  ],
31
31
  "dependencies": {
32
+ "@devwareng/vanilla-ts": "^1.2.118",
32
33
  "@types/fs-extra": "^11.0.4",
33
34
  "brython": "^3.13.2",
34
35
  "dompurify": "^3.2.6",