@devwareng/vanilla-ts 1.2.132 → 1.2.133

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 he=Object.create;var L=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var Ee=Object.getPrototypeOf,Te=Object.prototype.hasOwnProperty;var ye=(t,e)=>{for(var n in e)L(t,n,{get:e[n],enumerable:!0})},ee=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Se(e))!Te.call(t,o)&&o!==n&&L(t,o,{get:()=>e[o],enumerable:!(r=ge(e,o))||r.enumerable});return t};var p=(t,e,n)=>(n=t!=null?he(Ee(t)):{},ee(e||!t||!t.__esModule?L(n,"default",{value:t,enumerable:!0}):n,t)),ve=t=>ee(L({},"__esModule",{value:!0}),t);var Re={};ye(Re,{TSRouter:()=>R,createEffect:()=>G,createSignal:()=>Q,html:()=>x,loadPyFiles:()=>J,mapper:()=>te,renderChildRoutes:()=>B,useAnchorSingle:()=>N,useInitialDOM:()=>z,useTSAnchorMount:()=>V,useTSAuth:()=>U,useTSCollection:()=>_,useTSComponent:()=>T,useTSElementEach:()=>y,useTSElements:()=>$,useTSEvent:()=>C,useTSEventAll:()=>k,useTSExtractParams:()=>O,useTSLazy:()=>K,useTSMetaData:()=>I,useTSNavigate:()=>j,useTSOutlet:()=>W,useTSParams:()=>E,useTSPurifier:()=>b,useTSSSRHydration:()=>Y,useTSSelect:()=>F,useTSloadBrython:()=>X});module.exports=ve(Re);function Le(t){return(t==null?"":String(t)).replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\s*\/\s*\1\s*>/gi,"").replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>/gi,"").replace(/\son\w+\s*=\s*(['"]).*?\1/gi,"").replace(/\s(href|src)\s*=\s*(['"])\s*javascript:[^'"]*\2/gi,"")}function x(t,...e){return t.reduce((n,r,o)=>{let s=o<e.length?Le(e[o]):"";return n+r+s},"")}function w(){let t=new Set;document.querySelectorAll("*").forEach(e=>{let n=e.tagName.toLowerCase();n.includes("-")&&t.add(n)}),t.forEach(e=>{customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=`<div style="padding:10px;background:#eee;">${e} (Auto)</div>`}})})}var we=t=>t.replace(/<\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi,"").replace(/\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/\s+(href|src)\s*=\s*(['"]?)\s*javascript:[^'"\s>]*/gi,""),te=t=>t?.map(e=>we(e)).join("")??"";var H=p(require("dompurify"),1),b=(t,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof t=="string"?H.default.sanitize(t,r):H.default.sanitize(t.innerHTML,r)};var C=(t,e,n)=>{if(typeof t=="string"){let r=document.getElementById(t);r?r.addEventListener(e,n):console.warn(`Element with id '${t}' not found.`)}else t===document?document.addEventListener(e,n):console.warn("Invalid id parameter provided.")};var ne=require("zustand/vanilla"),D=p(require("dompurify"),1);function Me(t,e){let n=[],r=t.replace(/:[^/]+/g,a=>(n.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&n.forEach((a,c)=>{i[a]=D.default.sanitize(s[c+1]??"")}),i}function Ae(t){let e={},n=new URLSearchParams(t);for(let[r,o]of n.entries())e[r]=D.default.sanitize(o);return e}var E=(0,ne.createStore)((t,e)=>({params:{},query:{},setFromPattern:n=>{let r=window.location.pathname,o=Me(n,r),s=Ae(window.location.search);t({params:o,query:s})},getParam:n=>e().params[n],getQuery:n=>e().query[n]}));function O(t){let e=E.getState();e.setFromPattern(t);let n=e.params,r=e.query;return{...n,...r}}var k=(t,e,n)=>{let r=document.querySelectorAll(t);return r.forEach(o=>{o.addEventListener(e,n)}),()=>{r.forEach(o=>{o.removeEventListener(e,n)})}};var M=p(require("dompurify"),1),$=(t,e,n,r={})=>{let o={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","data-onclick","data-onchange","data-onselect"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...n};M.default.addHook("uponSanitizeElement",(i,a)=>{let c=a.tagName.toLowerCase();c.includes("-")&&(a.allowedTags[c]=!0)}),M.default.addHook("uponSanitizeAttribute",(i,a)=>{a.attrName&&a.attrName.toLowerCase().startsWith("on")&&(a.keepAttr=!1)});let s=M.default.sanitize(e,o);t.innerHTML=s,t.querySelectorAll("[data-onclick]").forEach(i=>{let a=i.dataset.onclick;r[a]&&i.addEventListener("click",r[a])}),t.querySelectorAll("[data-onchange]").forEach(i=>{let a=i.dataset.onchange;r[a]&&i.addEventListener("change",r[a])}),t.querySelectorAll("[data-onselect]").forEach(i=>{let a=i.dataset.onselect;r[a]&&i.addEventListener("select",r[a])})};var re=p(require("dompurify"),1),A=null,z=(t,e)=>{if(typeof document>"u")return;let n=document.getElementById(t);if(!n)return;let r=n.innerHTML,s=re.default.sanitize(r,{ALLOWED_TAGS:["div","span","p","h1","h2","h3","h4","h5","h6","ul","ol","li","strong","em","a","img","br"],ALLOWED_ATTR:["href","src","alt","title","class","id","data-onclick","data-onchange"],ALLOW_DATA_ATTR:!1,KEEP_CONTENT:!1}).replace(/\b(href|src)=["']?(?!https?:|mailto:|\/|#)/gi,'$1="#"');if(A!==null&&s!==A){let i=document.createElement("div");e(i),n.innerHTML=A}else A=s,n.innerHTML=s,e(n)};var q=p(require("dompurify"),1);typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",t=>{let e=t.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var N=(t,e,n,r="",o=null)=>{if(!t)return;let s=q.default.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=q.default.sanitize(n,{USE_PROFILES:{html:!1}});t.setAttribute("href",s),t.setAttribute("aria-label",i),r&&(t.className=r.trim()),o&&t.replaceChildren(o),typeof window<"u"&&t.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 oe=(t="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",n="'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 ${t}; style-src ${e}; object-src ${n}; 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 I=(t,e)=>{let n={name:g.default.sanitize(t.name||""),description:g.default.sanitize(t.description||"Default description"),author:g.default.sanitize(t.author||"")},r=m=>{n.name=g.default.sanitize(m),l("name",n.name)},o=m=>{n.description=g.default.sanitize(m),l("description",n.description)},s=m=>{n.author=g.default.sanitize(m),l("author",n.author)},i=()=>n.name,a=()=>n.description,c=()=>n.author,d=()=>n,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",n.name),l("description",n.description),l("author",n.author)};return e&&oe(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 se=p(require("dompurify"),1),T=(t,e,n,r,o)=>{let s=`#${t}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${t}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${t}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=se.default.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),n(a,r,o)};var _=(t,e,n,r=[])=>{let o=new Set;t.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=n[i],d=Array.isArray(r)?r[i]:void 0;typeof c=="function"?T(s,e,c,d):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var F=(t,e)=>{let r=(e??document).querySelectorAll(t);if(r.length===0)return process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] No element found for selector: '${t}'`),null;if(t.startsWith("#")&&r.length>1){if(process.env.NODE_ENV!=="production")throw new Error(`[useTSSelect] Duplicate ID detected: '${t}'. Found ${r.length} elements with this ID.`);return r[0]}return r.length>1&&process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] Multiple elements found for selector: '${t}'. Returning the first one.`),r[0]};var ie=require("jwt-decode"),U=(t,e)=>{let n=localStorage.getItem("token");if(!n)return window.location.href=e,null;try{let r=(0,ie.jwtDecode)(n),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=(t,e,n)=>{t.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{n(r,s)})})})};var j=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var W=(t,e)=>{let n=document.querySelector(`#${t}`)||document.querySelector(`.${t}`);if(!n)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(n);break}}};function B(t,e){let n=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(n===s||n.startsWith(`${s}/`)){let i=t.querySelector(`#${o.outlet}`)||t.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}var ae=require("zustand/vanilla");function Q(t){let e=(0,ae.createStore)(()=>({value:t})),n=new Set;return{get:()=>e.getState().value,set:r=>{e.setState({value:r}),n.forEach(o=>o(r))},subscribe:r=>(n.add(r),r(e.getState().value),()=>n.delete(r))}}function G(t){let e=t();typeof e=="function"&&e()}var ce=()=>{let t=document.querySelectorAll('a[href^="#"]');y(t,["click"],(e,n)=>{n.preventDefault();let r=e.getAttribute("href")?.substring(1),o=r?document.getElementById(r):null;o&&o.scrollIntoView({behavior:"smooth",block:"start"})})};var le=require("lodash-es"),P=t=>t;typeof window<"u"&&typeof document<"u"&&(P=t=>{let e=document.createElement("div");return e.innerText=t,e.innerHTML});var Pe=(0,le.debounce)(t=>{(t?Array.isArray(t)?t:t instanceof HTMLAnchorElement?[t]:Array.from(t):Array.from(document.querySelectorAll("a"))).forEach(n=>{if(!n||n.dataset.anchorEnhanced==="true")return;n.dataset.anchorEnhanced="true";let r=n.getAttribute("href")||"#",o=P(r);n.setAttribute("href",o);let s=n.getAttribute("class")||"";n.setAttribute("class",P(s));let i=n.getAttribute("aria-label");i&&n.setAttribute("aria-label",P(i));let a=n.querySelector(":scope > *");a&&(n.innerHTML="",n.appendChild(a));let c=n.getAttribute("href")||"";if(!c.startsWith("#")){try{if(new URL(c,window.location.href).origin!==window.location.origin)return}catch{return}n.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),ue=t=>{Pe(t)};var de=t=>{t.querySelectorAll("a").forEach(n=>{n.addEventListener("click",r=>{let o=n.getAttribute("href");o&&o.startsWith("/")&&(r.preventDefault(),ue(n))})})};var V=t=>{ce(),de(t)};var X=async()=>{let t="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",n=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 n(t),await n(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},J=t=>new Promise((e,n)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${t}`,r.onload=()=>e(),r.onerror=()=>n(new Error(`Failed to load ${t}`)),document.body.appendChild(r)});function K(t){let e=null;return async(n,r)=>{try{if(!e){let o=await t();e=o.default||o}if(typeof e=="function")return e(n,r);if(e instanceof HTMLElement){n?.appendChild(e);return}if(e&&typeof e.render=="function")return e.render(n,r);console.warn("useTSLazy: Unsupported module type",e)}catch(o){console.error("useTSLazy failed:",o)}}}var Y=t=>typeof window>"u"?{isDOM:null}:{isDOM:t||document.body};var Z=p(require("dompurify"),1);var pe=require("zustand/vanilla"),fe=p(require("dompurify"),1),h=(0,pe.createStore)(t=>({params:{},query:{},setParams:e=>t(()=>({params:me(e)})),setQuery:e=>t(()=>({query:me(e)}))}));function me(t){let e={};for(let n in t)e[n]=fe.default.sanitize(t[n]);return e}var R=class{constructor(e,n){this.routes=[];this.routes=e,this.expectedParams=new Set(n),window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,n=window.location.search,r=this.parseQueryParams(n),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,n,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(n,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=n.slice(i.path.length);this.renderChildren(i.children,u,a,d,s)}}}parseQueryParams(e){let n={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(n[o]=Z.default.sanitize(s));return n}findMatchingRoute(e,n,r={}){for(let o of n){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 n={};for(let r in e)this.expectedParams.has(r)&&(n[r]=Z.default.sanitize(e[r]??""));return n}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,mapper,renderChildRoutes,useAnchorSingle,useInitialDOM,useTSAnchorMount,useTSAuth,useTSCollection,useTSComponent,useTSElementEach,useTSElements,useTSEvent,useTSEventAll,useTSExtractParams,useTSLazy,useTSMetaData,useTSNavigate,useTSOutlet,useTSParams,useTSPurifier,useTSSSRHydration,useTSSelect,useTSloadBrython});
1
+ "use strict";var he=Object.create;var v=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var Te=Object.getPrototypeOf,Ee=Object.prototype.hasOwnProperty;var ye=(t,e)=>{for(var n in e)v(t,n,{get:e[n],enumerable:!0})},ee=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Se(e))!Ee.call(t,o)&&o!==n&&v(t,o,{get:()=>e[o],enumerable:!(r=ge(e,o))||r.enumerable});return t};var p=(t,e,n)=>(n=t!=null?he(Te(t)):{},ee(e||!t||!t.__esModule?v(n,"default",{value:t,enumerable:!0}):n,t)),Le=t=>ee(v({},"__esModule",{value:!0}),t);var xe={};ye(xe,{TSRouter:()=>P,createEffect:()=>Q,createSignal:()=>B,html:()=>R,loadPyFiles:()=>J,mapper:()=>te,renderChildRoutes:()=>W,useAnchorSingle:()=>q,useInitialDOM:()=>$,useTSAnchorMount:()=>V,useTSAuth:()=>F,useTSCollection:()=>I,useTSComponent:()=>E,useTSElementEach:()=>y,useTSElements:()=>k,useTSEvent:()=>b,useTSEventAll:()=>O,useTSExtractParams:()=>D,useTSLazy:()=>K,useTSMetaData:()=>N,useTSNavigate:()=>U,useTSOutlet:()=>j,useTSParams:()=>T,useTSPurifier:()=>H,useTSSSRHydration:()=>Y,useTSSelect:()=>_,useTSloadBrython:()=>X});module.exports=Le(xe);function ve(t){return(t==null?"":String(t)).replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\s*\/\s*\1\s*>/gi,"").replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>/gi,"").replace(/\son\w+\s*=\s*(['"]).*?\1/gi,"").replace(/\s(href|src)\s*=\s*(['"])\s*javascript:[^'"]*\2/gi,"")}function R(t,...e){return t.reduce((n,r,o)=>{let s=o<e.length?ve(e[o]):"";return n+r+s},"")}function w(){let t=new Set;document.querySelectorAll("*").forEach(e=>{let n=e.tagName.toLowerCase();n.includes("-")&&t.add(n)}),t.forEach(e=>{customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=`<div style="padding:10px;background:#eee;">${e} (Auto)</div>`}})})}var we=t=>t.replace(/<\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi,"").replace(/\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/\s+(href|src)\s*=\s*(['"]?)\s*javascript:[^'"\s>]*/gi,""),te=t=>t?.map(e=>we(e)).join("")??"";var x=p(require("dompurify"),1),H=(t,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof t=="string"?x.default.sanitize(t,r):x.default.sanitize(t.innerHTML,r)};var b=(t,e,n)=>{if(typeof t=="string"){let r=document.getElementById(t);r?r.addEventListener(e,n):console.warn(`Element with id '${t}' not found.`)}else t===document?document.addEventListener(e,n):console.warn("Invalid id parameter provided.")};var ne=require("zustand/vanilla"),C=p(require("dompurify"),1);function Me(t,e){let n=[],r=t.replace(/:[^/]+/g,a=>(n.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&n.forEach((a,c)=>{i[a]=C.default.sanitize(s[c+1]??"")}),i}function Ae(t){let e={},n=new URLSearchParams(t);for(let[r,o]of n.entries())e[r]=C.default.sanitize(o);return e}var T=(0,ne.createStore)((t,e)=>({params:{},query:{},setFromPattern:n=>{let r=window.location.pathname,o=Me(n,r),s=Ae(window.location.search);t({params:o,query:s})},getParam:n=>e().params[n],getQuery:n=>e().query[n]}));function D(t){let e=T.getState();e.setFromPattern(t);let n=e.params,r=e.query;return{...n,...r}}var O=(t,e,n)=>{let r=document.querySelectorAll(t);return r.forEach(o=>{o.addEventListener(e,n)}),()=>{r.forEach(o=>{o.removeEventListener(e,n)})}};var M=p(require("dompurify"),1),k=(t,e,n,r={})=>{let o={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","data-onclick","data-onchange","data-onselect"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...n};M.default.addHook("uponSanitizeElement",(i,a)=>{let c=a.tagName.toLowerCase();c.includes("-")&&(a.allowedTags[c]=!0)}),M.default.addHook("uponSanitizeAttribute",(i,a)=>{a.attrName&&a.attrName.toLowerCase().startsWith("on")&&(a.keepAttr=!1)});let s=M.default.sanitize(e,o);t.innerHTML=s,t.querySelectorAll("[data-onclick]").forEach(i=>{let a=i.dataset.onclick;r[a]&&i.addEventListener("click",r[a])}),t.querySelectorAll("[data-onchange]").forEach(i=>{let a=i.dataset.onchange;r[a]&&i.addEventListener("change",r[a])}),t.querySelectorAll("[data-onselect]").forEach(i=>{let a=i.dataset.onselect;r[a]&&i.addEventListener("select",r[a])})};var re=p(require("dompurify"),1),A=null,$=(t,e)=>{if(typeof document>"u")return;let n=document.getElementById(t);if(!n)return;let r=n.innerHTML,s=re.default.sanitize(r,{ALLOWED_TAGS:["div","span","p","h1","h2","h3","h4","h5","h6","ul","ol","li","strong","em","a","img","br"],ALLOWED_ATTR:["href","src","alt","title","class","id","data-onclick","data-onchange"],ALLOW_DATA_ATTR:!1,KEEP_CONTENT:!1}).replace(/\b(href|src)=["']?(?!https?:|mailto:|\/|#)/gi,'$1="#"');if(A!==null&&s!==A){let i=document.createElement("div");e(i),n.innerHTML=A}else A=s,n.innerHTML=s,e(n)};var z=p(require("dompurify"),1);typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",t=>{let e=t.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var q=(t,e,n,r="",o=null)=>{if(!t)return;let s=z.default.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=z.default.sanitize(n,{USE_PROFILES:{html:!1}});t.setAttribute("href",s),t.setAttribute("aria-label",i),r&&(t.className=r.trim()),o&&t.replaceChildren(o),typeof window<"u"&&t.addEventListener("click",a=>{a.preventDefault();let l=a.currentTarget.getAttribute("href");if(l){let m=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:m},"",l),dispatchEvent(new PopStateEvent("popstate"))}})};var g=p(require("dompurify"),1);var oe=(t="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",n="'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",l=!1)=>{let m=()=>{try{let u=document.querySelector('meta[http-equiv="Content-Security-Policy"]');u||(u=document.createElement("meta"),u.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(u));let f=l?`report-uri ${c};`:"";u.setAttribute("content",`default-src 'self'; script-src ${t}; style-src ${e}; object-src ${n}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${f}`)}catch(u){console.error("Error adding CSP meta element:",u)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",m):m()};var N=(t,e)=>{let n={name:g.default.sanitize(t.name||""),description:g.default.sanitize(t.description||"Default description"),author:g.default.sanitize(t.author||"")},r=d=>{n.name=g.default.sanitize(d),u("name",n.name)},o=d=>{n.description=g.default.sanitize(d),u("description",n.description)},s=d=>{n.author=g.default.sanitize(d),u("author",n.author)},i=()=>n.name,a=()=>n.description,c=()=>n.author,l=()=>n,m=(d,L)=>{let S=document.createElement("meta");S.setAttribute("name",d),S.setAttribute("content",L),document.head.appendChild(S)},u=(d,L)=>{let S=document.querySelector(`meta[name="${d}"]`);S?S.setAttribute("content",L):m(d,L)},f=()=>{u("name",n.name),u("description",n.description),u("author",n.author)};return e&&oe(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:l,appendMetaTagsToHead:f}};var se=p(require("dompurify"),1),E=(t,e,n,r,o)=>{let s=`#${t}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${t}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${t}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=se.default.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),n(a,r,o)};var I=(t,e,n,r=[])=>{let o=new Set;t.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=n[i],l=Array.isArray(r)?r[i]:void 0;typeof c=="function"?E(s,e,c,l):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var _=(t,e)=>{let r=(e??document).querySelectorAll(t);if(r.length===0)return process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] No element found for selector: '${t}'`),null;if(t.startsWith("#")&&r.length>1){if(process.env.NODE_ENV!=="production")throw new Error(`[useTSSelect] Duplicate ID detected: '${t}'. Found ${r.length} elements with this ID.`);return r[0]}return r.length>1&&process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] Multiple elements found for selector: '${t}'. Returning the first one.`),r[0]};var ie=require("jwt-decode"),F=(t,e)=>{let n=localStorage.getItem("token");if(!n)return window.location.href=e,null;try{let r=(0,ie.jwtDecode)(n),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=(t,e,n)=>{t.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{n(r,s)})})})};var U=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var j=(t,e)=>{let n=document.querySelector(`#${t}`)||document.querySelector(`.${t}`);if(!n)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(n);break}}};function W(t,e){let n=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(n===s||n.startsWith(`${s}/`)){let i=t.querySelector(`#${o.outlet}`)||t.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}var ae=require("zustand/vanilla");function B(t){let e=(0,ae.createStore)(()=>({value:t})),n=new Set;return{get:()=>e.getState().value,set:r=>{e.setState({value:r}),n.forEach(o=>o(r))},subscribe:r=>(n.add(r),r(e.getState().value),()=>n.delete(r))}}function Q(t){let e=t();typeof e=="function"&&e()}var ce=()=>{let t=document.querySelectorAll('a[href^="#"]');y(t,["click"],(e,n)=>{n.preventDefault();let r=e.getAttribute("href")?.substring(1),o=r?document.getElementById(r):null;o&&o.scrollIntoView({behavior:"smooth",block:"start"})})};var le=require("lodash-es"),G=t=>t;typeof window<"u"&&typeof document<"u"&&(G=t=>{let e=document.createElement("div");return e.innerText=t,e.innerHTML});var Pe=t=>{(t?Array.isArray(t)?t:t instanceof HTMLAnchorElement?[t]:Array.from(t):Array.from(document.querySelectorAll("a"))).forEach(n=>{if(!n||n.dataset.anchorEnhanced==="true")return;n.dataset.anchorEnhanced="true";let r=n.getAttribute("class")||"";n.setAttribute("class",G(r));let o=n.getAttribute("aria-label");o&&n.setAttribute("aria-label",G(o));let s=n.querySelector(":scope > *");s&&(n.innerHTML="",n.appendChild(s));let i=n.getAttribute("href")||"";if(!i.startsWith("#")){try{if(new URL(i,window.location.href).origin!==window.location.origin)return}catch{return}n.addEventListener("click",a=>{a.preventDefault();let c=n.getAttribute("href")||"";try{let l=new URL(c,window.location.href);window.history.pushState({},"",l.pathname+l.search+l.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(l){console.error("Invalid URL in anchor:",c,l)}})}})},Re=(0,le.debounce)(Pe,50),ue=t=>{Re(t)};var de=t=>{let e=t.querySelectorAll("a");ue(e)};var V=t=>{ce(),de(t)};var X=async()=>{let t="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",n=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 n(t),await n(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},J=t=>new Promise((e,n)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${t}`,r.onload=()=>e(),r.onerror=()=>n(new Error(`Failed to load ${t}`)),document.body.appendChild(r)});function K(t){let e=null;return async(n,r)=>{try{if(!e){let o=await t();e=o.default||o}if(typeof e=="function")return e(n,r);if(e instanceof HTMLElement){n?.appendChild(e);return}if(e&&typeof e.render=="function")return e.render(n,r);console.warn("useTSLazy: Unsupported module type",e)}catch(o){console.error("useTSLazy failed:",o)}}}var Y=t=>typeof window>"u"?{isDOM:null}:{isDOM:t||document.body};var Z=p(require("dompurify"),1);var pe=require("zustand/vanilla"),fe=p(require("dompurify"),1),h=(0,pe.createStore)(t=>({params:{},query:{},setParams:e=>t(()=>({params:me(e)})),setQuery:e=>t(()=>({query:me(e)}))}));function me(t){let e={};for(let n in t)e[n]=fe.default.sanitize(t[n]);return e}var P=class{constructor(e,n){this.routes=[];this.routes=e,this.expectedParams=new Set(n),window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,n=window.location.search,r=this.parseQueryParams(n),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,n,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(n,e);if(i){let a=document.createElement("div");a.id="child";let c={...o,...i.params},l=this.filterAndSanitizeParams(c);if(h.getState().setParams(l),h.getState().setQuery(s),i.element?.(a,l,s),r.appendChild(a),i.children){let m=n.slice(i.path.length);this.renderChildren(i.children,m,a,l,s)}}}parseQueryParams(e){let n={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(n[o]=Z.default.sanitize(s));return n}findMatchingRoute(e,n,r={}){for(let o of n){let s=o.path;if(s==="*")return o;{let a=[],c=s.replace(/:[^\s/]+/g,u=>(a.push(u.substring(1)),"([^\\s/]+)")),l=new RegExp(`^${c}(?:/|$)`),m=e.match(l);if(m){let u={...r};if(a.forEach((f,d)=>{u[f]=m[d+1]??""}),o.children){let f=e.slice(m[0].length),d=this.findMatchingRoute(f,o.children,u);if(d)return d}return{...o,params:u}}}}}filterAndSanitizeParams(e){if(!e)return{};let n={};for(let r in e)this.expectedParams.has(r)&&(n[r]=Z.default.sanitize(e[r]??""));return n}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,mapper,renderChildRoutes,useAnchorSingle,useInitialDOM,useTSAnchorMount,useTSAuth,useTSCollection,useTSComponent,useTSElementEach,useTSElements,useTSEvent,useTSEventAll,useTSExtractParams,useTSLazy,useTSMetaData,useTSNavigate,useTSOutlet,useTSParams,useTSPurifier,useTSSSRHydration,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/func/index.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/hooks/useTSSSRHydration.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 { mapper } from './src/func'\r\nexport { createEffect, createSignal, renderChildRoutes, useTSSSRHydration, 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","function sanitize(input: unknown): string {\r\n // Always convert to string first\r\n const str = input === null || input === undefined ? \"\" : String(input);\r\n\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <style> blocks\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\\s*\\/\\s*\\1\\s*>/gi, \"\")\r\n // remove opening dangerous tags without closing\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>/gi, \"\")\r\n // strip inline event handlers like onclick=, onerror=, etc.\r\n .replace(/\\son\\w+\\s*=\\s*(['\"]).*?\\1/gi, \"\")\r\n // block javascript: URLs\r\n .replace(/\\s(href|src)\\s*=\\s*(['\"])\\s*javascript:[^'\"]*\\2/gi, \"\");\r\n}\r\n\r\nexport function html(strings: TemplateStringsArray, ...values: unknown[]): string {\r\n return strings.reduce((result, str, i) => {\r\n const safeValue = i < values.length ? sanitize(values[i]) : \"\";\r\n return result + str + safeValue;\r\n }, \"\");\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 };","// ✅ sanitize HTML but allow harmless tags\r\nconst sanitizeHtml = (str: string) => {\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <meta>, <style>\r\n .replace(/<\\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi, \"\")\r\n // remove any attribute that starts with \"on\" (onerror, onclick, etc.)\r\n .replace(/\\s+on[a-z]+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, \"\")\r\n // block javascript: in href/src\r\n .replace(/\\s+(href|src)\\s*=\\s*(['\"]?)\\s*javascript:[^'\"\\s>]*/gi, \"\")\r\n}\r\n\r\n// ✅ mapper with sanitization\r\nconst mapper = (arr: string[] | undefined) =>\r\n arr?.map((item) => sanitizeHtml(item)).join(\"\") ?? \"\"\r\n\r\nexport { mapper }\r\n","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 EventHandlers = Record<string, EventListener>;\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config,\r\n handlers?: EventHandlers\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (\r\n htmlElement,\r\n element,\r\n config,\r\n handlers = {}\r\n) => {\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 \"data-onclick\", \"data-onchange\", \"data-onselect\" // ✅ added safe attribute\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 inline 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 htmlElement.innerHTML = sanitizedContent;\r\n\r\n // ✅ Bind safe declarative events\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onclick]\").forEach((el) => {\r\n const key = el.dataset.onclick!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"click\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onchange]\").forEach((el) => {\r\n const key = el.dataset.onchange!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"change\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onselect]\").forEach((el) => {\r\n const key = el.dataset.onselect!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"select\", handlers[key]);\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 if (typeof document === \"undefined\") return;\r\n\r\n const targetElement = document.getElementById(id);\r\n if (!targetElement) return;\r\n\r\n const dirtyHTML = targetElement.innerHTML;\r\n\r\n // Strict allow-list: only allowed tags + attrs\r\n const sanitizedHTML = DOMPurify.sanitize(dirtyHTML, {\r\n ALLOWED_TAGS: [\r\n \"div\", \"span\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"ul\", \"ol\", \"li\", \"strong\", \"em\", \"a\", \"img\", \"br\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"href\", \"src\", \"alt\", \"title\", \"class\", \"id\",\r\n \"data-onclick\", \"data-onchange\" // ✅ only these two data-* attrs\r\n ],\r\n ALLOW_DATA_ATTR: false, // block all other data-* attributes\r\n KEEP_CONTENT: false,\r\n });\r\n\r\n // Extra safeguard: strip unsafe URL schemes\r\n const safeHTML = sanitizedHTML.replace(\r\n /\\b(href|src)=[\"']?(?!https?:|mailto:|\\/|#)/gi,\r\n '$1=\"#\"'\r\n );\r\n\r\n if (previousHTML !== null && safeHTML !== previousHTML) {\r\n const fallbackEl = document.createElement(\"div\");\r\n mount(fallbackEl);\r\n targetElement.innerHTML = previousHTML;\r\n } else {\r\n previousHTML = safeHTML;\r\n targetElement.innerHTML = safeHTML;\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>(\r\n selector: string,\r\n scope?: HTMLElement\r\n) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(\r\n selector: string,\r\n scope?: HTMLElement\r\n): T | null => {\r\n const root = scope ?? document;\r\n const elements = root.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n if (process.env.NODE_ENV !== \"production\") {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n }\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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 return elements[0]; // fallback: just return first\r\n }\r\n\r\n if (elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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\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","// useTSNoReload.ts\r\nimport { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = (DOM: HTMLElement) => {\r\n const anchors = DOM.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n\r\n anchors.forEach(anchor => {\r\n anchor.addEventListener(\"click\", (e) => {\r\n // If it's an internal link, stop reload\r\n const href = anchor.getAttribute(\"href\");\r\n if (href && href.startsWith(\"/\")) {\r\n e.preventDefault();\r\n useAnchor(anchor); // let your hook handle navigation\r\n }\r\n });\r\n });\r\n};\r\n\r\nexport { useTSNoReload };\r\n","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = (DOM: HTMLElement) => {\r\n useTSHashAnchor();\r\n useTSNoReload(DOM);\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","\r\nconst useTSSSRHydration = (DOM: HTMLElement) => {\r\n if (typeof window === \"undefined\") {\r\n return { isDOM: null };\r\n }\r\n\r\n const isDOM = DOM || document.body;\r\n\r\n return { isDOM };\r\n};\r\n\r\nexport { useTSSSRHydration };\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","mapper","renderChildRoutes","useAnchorSingle","useInitialDOM","useTSAnchorMount","useTSAuth","useTSCollection","useTSComponent","useTSElementEach","useTSElements","useTSEvent","useTSEventAll","useTSExtractParams","useTSLazy","useTSMetaData","useTSNavigate","useTSOutlet","useTSParams","useTSPurifier","useTSSSRHydration","useTSSelect","useTSloadBrython","__toCommonJS","sanitize","input","html","strings","values","result","str","i","safeValue","autoRegister","allTags","el","tagName","tag","sanitizeHtml","str","mapper","arr","item","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","handlers","defaultConfig","DOMPurify","node","data","tagName","sanitizedContent","el","key","import_dompurify","previousHTML","useInitialDOM","id","mount","targetElement","dirtyHTML","safeHTML","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","scope","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","DOM","anchor","e","href","useAnchor","useTSAnchorMount","DOM","useTSHashAnchor","useTSNoReload","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","factory","cached","el","props","mod","err","useTSSSRHydration","DOM","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/func/index.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/hooks/useTSSSRHydration.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 { mapper } from './src/func'\r\nexport { createEffect, createSignal, renderChildRoutes, useTSSSRHydration, 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","function sanitize(input: unknown): string {\r\n // Always convert to string first\r\n const str = input === null || input === undefined ? \"\" : String(input);\r\n\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <style> blocks\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\\s*\\/\\s*\\1\\s*>/gi, \"\")\r\n // remove opening dangerous tags without closing\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>/gi, \"\")\r\n // strip inline event handlers like onclick=, onerror=, etc.\r\n .replace(/\\son\\w+\\s*=\\s*(['\"]).*?\\1/gi, \"\")\r\n // block javascript: URLs\r\n .replace(/\\s(href|src)\\s*=\\s*(['\"])\\s*javascript:[^'\"]*\\2/gi, \"\");\r\n}\r\n\r\nexport function html(strings: TemplateStringsArray, ...values: unknown[]): string {\r\n return strings.reduce((result, str, i) => {\r\n const safeValue = i < values.length ? sanitize(values[i]) : \"\";\r\n return result + str + safeValue;\r\n }, \"\");\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 };","// ✅ sanitize HTML but allow harmless tags\r\nconst sanitizeHtml = (str: string) => {\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <meta>, <style>\r\n .replace(/<\\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi, \"\")\r\n // remove any attribute that starts with \"on\" (onerror, onclick, etc.)\r\n .replace(/\\s+on[a-z]+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, \"\")\r\n // block javascript: in href/src\r\n .replace(/\\s+(href|src)\\s*=\\s*(['\"]?)\\s*javascript:[^'\"\\s>]*/gi, \"\")\r\n}\r\n\r\n// ✅ mapper with sanitization\r\nconst mapper = (arr: string[] | undefined) =>\r\n arr?.map((item) => sanitizeHtml(item)).join(\"\") ?? \"\"\r\n\r\nexport { mapper }\r\n","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 EventHandlers = Record<string, EventListener>;\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config,\r\n handlers?: EventHandlers\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (\r\n htmlElement,\r\n element,\r\n config,\r\n handlers = {}\r\n) => {\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 \"data-onclick\", \"data-onchange\", \"data-onselect\" // ✅ added safe attribute\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 inline 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 htmlElement.innerHTML = sanitizedContent;\r\n\r\n // ✅ Bind safe declarative events\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onclick]\").forEach((el) => {\r\n const key = el.dataset.onclick!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"click\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onchange]\").forEach((el) => {\r\n const key = el.dataset.onchange!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"change\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onselect]\").forEach((el) => {\r\n const key = el.dataset.onselect!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"select\", handlers[key]);\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 if (typeof document === \"undefined\") return;\r\n\r\n const targetElement = document.getElementById(id);\r\n if (!targetElement) return;\r\n\r\n const dirtyHTML = targetElement.innerHTML;\r\n\r\n // Strict allow-list: only allowed tags + attrs\r\n const sanitizedHTML = DOMPurify.sanitize(dirtyHTML, {\r\n ALLOWED_TAGS: [\r\n \"div\", \"span\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"ul\", \"ol\", \"li\", \"strong\", \"em\", \"a\", \"img\", \"br\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"href\", \"src\", \"alt\", \"title\", \"class\", \"id\",\r\n \"data-onclick\", \"data-onchange\" // ✅ only these two data-* attrs\r\n ],\r\n ALLOW_DATA_ATTR: false, // block all other data-* attributes\r\n KEEP_CONTENT: false,\r\n });\r\n\r\n // Extra safeguard: strip unsafe URL schemes\r\n const safeHTML = sanitizedHTML.replace(\r\n /\\b(href|src)=[\"']?(?!https?:|mailto:|\\/|#)/gi,\r\n '$1=\"#\"'\r\n );\r\n\r\n if (previousHTML !== null && safeHTML !== previousHTML) {\r\n const fallbackEl = document.createElement(\"div\");\r\n mount(fallbackEl);\r\n targetElement.innerHTML = previousHTML;\r\n } else {\r\n previousHTML = safeHTML;\r\n targetElement.innerHTML = safeHTML;\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>(\r\n selector: string,\r\n scope?: HTMLElement\r\n) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(\r\n selector: string,\r\n scope?: HTMLElement\r\n): T | null => {\r\n const root = scope ?? document;\r\n const elements = root.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n if (process.env.NODE_ENV !== \"production\") {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n }\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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 return elements[0]; // fallback: just return first\r\n }\r\n\r\n if (elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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\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\n// Simple sanitization (escape HTML entities)\r\nlet sanitizeInput = (input: string): string => input;\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\n/**\r\n * Enhance anchors for SPA navigation\r\n */\r\nconst enhanceAnchors = (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 class + aria-label, but don't rewrite href\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 // Handle child sanitization safely (optional)\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 const href = anchor.getAttribute(\"href\") || \"\";\r\n\r\n // Skip hash links\r\n if (href.startsWith(\"#\")) return;\r\n\r\n // Skip external links\r\n try {\r\n const url = new URL(href, window.location.href);\r\n if (url.origin !== window.location.origin) return;\r\n } catch {\r\n return;\r\n }\r\n\r\n // ✅ Intercept internal navigation\r\n anchor.addEventListener(\"click\", (e: MouseEvent) => {\r\n e.preventDefault(); // stop reload immediately\r\n const rawHref = anchor.getAttribute(\"href\") || \"\";\r\n try {\r\n const url = new URL(rawHref, 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:\", rawHref, err);\r\n }\r\n });\r\n });\r\n};\r\n\r\n// Debounced wrapper (for dynamic DOM changes)\r\nconst _enhanceAnchors = debounce(enhanceAnchors, 50);\r\n\r\nexport const useAnchor = (anchors?: AnchorInput): void => {\r\n _enhanceAnchors(anchors);\r\n};\r\n","// useTSNoReload.ts\r\nimport { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = (DOM: HTMLElement) => {\r\n const anchors = DOM.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n useAnchor(anchors);\r\n};\r\n\r\nexport { useTSNoReload };\r\n","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = (DOM: HTMLElement) => {\r\n useTSHashAnchor();\r\n useTSNoReload(DOM);\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","\r\nconst useTSSSRHydration = (DOM: HTMLElement) => {\r\n if (typeof window === \"undefined\") {\r\n return { isDOM: null };\r\n }\r\n\r\n const isDOM = DOM || document.body;\r\n\r\n return { isDOM };\r\n};\r\n\r\nexport { useTSSSRHydration };\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","mapper","renderChildRoutes","useAnchorSingle","useInitialDOM","useTSAnchorMount","useTSAuth","useTSCollection","useTSComponent","useTSElementEach","useTSElements","useTSEvent","useTSEventAll","useTSExtractParams","useTSLazy","useTSMetaData","useTSNavigate","useTSOutlet","useTSParams","useTSPurifier","useTSSSRHydration","useTSSelect","useTSloadBrython","__toCommonJS","sanitize","input","html","strings","values","result","str","i","safeValue","autoRegister","allTags","el","tagName","tag","sanitizeHtml","str","mapper","arr","item","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","handlers","defaultConfig","DOMPurify","node","data","tagName","sanitizedContent","el","key","import_dompurify","previousHTML","useInitialDOM","id","mount","targetElement","dirtyHTML","safeHTML","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","scope","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","originalClassName","ariaLabel","child","href","e","rawHref","url","err","_enhanceAnchors","useAnchor","useTSNoReload","DOM","anchors","useAnchor","useTSAnchorMount","DOM","useTSHashAnchor","useTSNoReload","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","factory","cached","el","props","mod","err","useTSSSRHydration","DOM","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.js CHANGED
@@ -1,2 +1,2 @@
1
- function re(n){return(n==null?"":String(n)).replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\s*\/\s*\1\s*>/gi,"").replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>/gi,"").replace(/\son\w+\s*=\s*(['"]).*?\1/gi,"").replace(/\s(href|src)\s*=\s*(['"])\s*javascript:[^'"]*\2/gi,"")}function P(n,...e){return n.reduce((t,r,o)=>{let s=o<e.length?re(e[o]):"";return t+r+s},"")}function E(){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 oe=n=>n.replace(/<\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi,"").replace(/\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/\s+(href|src)\s*=\s*(['"]?)\s*javascript:[^'"\s>]*/gi,""),se=n=>n?.map(e=>oe(e)).join("")??"";import R from"dompurify";var x=(n,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof n=="string"?R.sanitize(n,r):R.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.")};import{createStore as ie}from"zustand/vanilla";import b from"dompurify";function ae(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 ce(n){let e={},t=new URLSearchParams(n);for(let[r,o]of t.entries())e[r]=b.sanitize(o);return e}var T=ie((n,e)=>({params:{},query:{},setFromPattern:t=>{let r=window.location.pathname,o=ae(t,r),s=ce(window.location.search);n({params:o,query:s})},getParam:t=>e().params[t],getQuery:t=>e().query[t]}));function C(n){let e=T.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,r={})=>{let o={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","data-onclick","data-onchange","data-onselect"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...t};M.addHook("uponSanitizeElement",(i,a)=>{let c=a.tagName.toLowerCase();c.includes("-")&&(a.allowedTags[c]=!0)}),M.addHook("uponSanitizeAttribute",(i,a)=>{a.attrName&&a.attrName.toLowerCase().startsWith("on")&&(a.keepAttr=!1)});let s=M.sanitize(e,o);n.innerHTML=s,n.querySelectorAll("[data-onclick]").forEach(i=>{let a=i.dataset.onclick;r[a]&&i.addEventListener("click",r[a])}),n.querySelectorAll("[data-onchange]").forEach(i=>{let a=i.dataset.onchange;r[a]&&i.addEventListener("change",r[a])}),n.querySelectorAll("[data-onselect]").forEach(i=>{let a=i.dataset.onselect;r[a]&&i.addEventListener("select",r[a])})};import le from"dompurify";var y=null,k=(n,e)=>{if(typeof document>"u")return;let t=document.getElementById(n);if(!t)return;let r=t.innerHTML,s=le.sanitize(r,{ALLOWED_TAGS:["div","span","p","h1","h2","h3","h4","h5","h6","ul","ol","li","strong","em","a","img","br"],ALLOWED_ATTR:["href","src","alt","title","class","id","data-onclick","data-onchange"],ALLOW_DATA_ATTR:!1,KEEP_CONTENT:!1}).replace(/\b(href|src)=["']?(?!https?:|mailto:|\/|#)/gi,'$1="#"');if(y!==null&&s!==y){let i=document.createElement("div");e(i),t.innerHTML=y}else y=s,t.innerHTML=s,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 z=(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 q=(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 N=(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&&q(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 ue 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=ue.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),t(a,r,o)};var I=(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,e)=>{let r=(e??document).querySelectorAll(n);if(r.length===0)return process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] No element found for selector: '${n}'`),null;if(n.startsWith("#")&&r.length>1){if(process.env.NODE_ENV!=="production")throw new Error(`[useTSSelect] Duplicate ID detected: '${n}'. Found ${r.length} elements with this ID.`);return r[0]}return r.length>1&&process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] Multiple elements found for selector: '${n}'. Returning the first one.`),r[0]};import{jwtDecode as de}from"jwt-decode";var F=(n,e)=>{let t=localStorage.getItem("token");if(!t)return window.location.href=e,null;try{let r=de(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 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)}})})}import{createStore as me}from"zustand/vanilla";function B(n){let e=me(()=>({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 pe}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 fe=pe(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),V=n=>{fe(n)};var X=n=>{n.querySelectorAll("a").forEach(t=>{t.addEventListener("click",r=>{let o=t.getAttribute("href");o&&o.startsWith("/")&&(r.preventDefault(),V(t))})})};var J=n=>{G(),X(n)};var K=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.")},Y=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)}}}var ee=n=>typeof window>"u"?{isDOM:null}:{isDOM:n||document.body};import ne from"dompurify";import{createStore as he}from"zustand/vanilla";import ge from"dompurify";var f=he(n=>({params:{},query:{},setParams:e=>n(()=>({params:te(e)})),setQuery:e=>n(()=>({query:te(e)}))}));function te(n){let e={};for(let t in n)e[t]=ge.sanitize(n[t]);return e}var A=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]=ne.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]=ne.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",()=>{E()}),document.addEventListener("DOMContentLoaded",E));export{A as TSRouter,Q as createEffect,B as createSignal,P as html,Y as loadPyFiles,se as mapper,W as renderChildRoutes,z as useAnchorSingle,k as useInitialDOM,J as useTSAnchorMount,F as useTSAuth,I as useTSCollection,v as useTSComponent,L as useTSElementEach,O as useTSElements,H as useTSEvent,D as useTSEventAll,C as useTSExtractParams,Z as useTSLazy,N as useTSMetaData,U as useTSNavigate,j as useTSOutlet,T as useTSParams,x as useTSPurifier,ee as useTSSSRHydration,_ as useTSSelect,K as useTSloadBrython};
1
+ function re(t){return(t==null?"":String(t)).replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\s*\/\s*\1\s*>/gi,"").replace(/<\s*(script|iframe|object|embed|link|style)[^>]*>/gi,"").replace(/\son\w+\s*=\s*(['"]).*?\1/gi,"").replace(/\s(href|src)\s*=\s*(['"])\s*javascript:[^'"]*\2/gi,"")}function P(t,...e){return t.reduce((n,r,o)=>{let s=o<e.length?re(e[o]):"";return n+r+s},"")}function T(){let t=new Set;document.querySelectorAll("*").forEach(e=>{let n=e.tagName.toLowerCase();n.includes("-")&&t.add(n)}),t.forEach(e=>{customElements.get(e)||customElements.define(e,class extends HTMLElement{connectedCallback(){this.innerHTML=`<div style="padding:10px;background:#eee;">${e} (Auto)</div>`}})})}var oe=t=>t.replace(/<\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi,"").replace(/\s+on[a-z]+\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi,"").replace(/\s+(href|src)\s*=\s*(['"]?)\s*javascript:[^'"\s>]*/gi,""),se=t=>t?.map(e=>oe(e)).join("")??"";import R from"dompurify";var x=(t,e)=>{let r={...{ADD_TAGS:["my-custom-tag"]},...e};return typeof t=="string"?R.sanitize(t,r):R.sanitize(t.innerHTML,r)};var H=(t,e,n)=>{if(typeof t=="string"){let r=document.getElementById(t);r?r.addEventListener(e,n):console.warn(`Element with id '${t}' not found.`)}else t===document?document.addEventListener(e,n):console.warn("Invalid id parameter provided.")};import{createStore as ie}from"zustand/vanilla";import b from"dompurify";function ae(t,e){let n=[],r=t.replace(/:[^/]+/g,a=>(n.push(a.slice(1)),"([^/]+)")),o=new RegExp(`^${r}$`),s=e.match(o),i={};return s&&n.forEach((a,c)=>{i[a]=b.sanitize(s[c+1]??"")}),i}function ce(t){let e={},n=new URLSearchParams(t);for(let[r,o]of n.entries())e[r]=b.sanitize(o);return e}var E=ie((t,e)=>({params:{},query:{},setFromPattern:n=>{let r=window.location.pathname,o=ae(n,r),s=ce(window.location.search);t({params:o,query:s})},getParam:n=>e().params[n],getQuery:n=>e().query[n]}));function C(t){let e=E.getState();e.setFromPattern(t);let n=e.params,r=e.query;return{...n,...r}}var D=(t,e,n)=>{let r=document.querySelectorAll(t);return r.forEach(o=>{o.addEventListener(e,n)}),()=>{r.forEach(o=>{o.removeEventListener(e,n)})}};import w from"dompurify";var O=(t,e,n,r={})=>{let o={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","data-onclick","data-onchange","data-onselect"],FORBID_TAGS:["script","iframe"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel|ftp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i,...n};w.addHook("uponSanitizeElement",(i,a)=>{let c=a.tagName.toLowerCase();c.includes("-")&&(a.allowedTags[c]=!0)}),w.addHook("uponSanitizeAttribute",(i,a)=>{a.attrName&&a.attrName.toLowerCase().startsWith("on")&&(a.keepAttr=!1)});let s=w.sanitize(e,o);t.innerHTML=s,t.querySelectorAll("[data-onclick]").forEach(i=>{let a=i.dataset.onclick;r[a]&&i.addEventListener("click",r[a])}),t.querySelectorAll("[data-onchange]").forEach(i=>{let a=i.dataset.onchange;r[a]&&i.addEventListener("change",r[a])}),t.querySelectorAll("[data-onselect]").forEach(i=>{let a=i.dataset.onselect;r[a]&&i.addEventListener("select",r[a])})};import le from"dompurify";var y=null,k=(t,e)=>{if(typeof document>"u")return;let n=document.getElementById(t);if(!n)return;let r=n.innerHTML,s=le.sanitize(r,{ALLOWED_TAGS:["div","span","p","h1","h2","h3","h4","h5","h6","ul","ol","li","strong","em","a","img","br"],ALLOWED_ATTR:["href","src","alt","title","class","id","data-onclick","data-onchange"],ALLOW_DATA_ATTR:!1,KEEP_CONTENT:!1}).replace(/\b(href|src)=["']?(?!https?:|mailto:|\/|#)/gi,'$1="#"');if(y!==null&&s!==y){let i=document.createElement("div");e(i),n.innerHTML=y}else y=s,n.innerHTML=s,e(n)};import $ from"dompurify";typeof window<"u"&&!window.__anchorSinglePopstateHandlerAttached&&(window.addEventListener("popstate",t=>{let e=t.state;e?.scrollPosition!==void 0&&window.scrollTo(0,e.scrollPosition)}),window.__anchorSinglePopstateHandlerAttached=!0);var z=(t,e,n,r="",o=null)=>{if(!t)return;let s=$.sanitize(e,{ALLOWED_URI_REGEXP:/^(https?:|\/)/}),i=$.sanitize(n,{USE_PROFILES:{html:!1}});t.setAttribute("href",s),t.setAttribute("aria-label",i),r&&(t.className=r.trim()),o&&t.replaceChildren(o),typeof window<"u"&&t.addEventListener("click",a=>{a.preventDefault();let l=a.currentTarget.getAttribute("href");if(l){let m=window.scrollY;window.scrollTo(0,0),window.history.pushState({scrollPosition:m},"",l),dispatchEvent(new PopStateEvent("popstate"))}})};import g from"dompurify";var q=(t="'self' 'nonce-rAnd0m123' 'unsafe-inline' 'unsafe-eval'",e="'self' 'nonce-rAnd0m123'",n="'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",l=!1)=>{let m=()=>{try{let u=document.querySelector('meta[http-equiv="Content-Security-Policy"]');u||(u=document.createElement("meta"),u.setAttribute("http-equiv","Content-Security-Policy"),document.head.appendChild(u));let p=l?`report-uri ${c};`:"";u.setAttribute("content",`default-src 'self'; script-src ${t}; style-src ${e}; object-src ${n}; font-src ${r}; img-src ${o}; connect-src ${s.join(" ")}; frame-src ${i}; base-uri ${a}; ${p}`)}catch(u){console.error("Error adding CSP meta element:",u)}};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",m):m()};var N=(t,e)=>{let n={name:g.sanitize(t.name||""),description:g.sanitize(t.description||"Default description"),author:g.sanitize(t.author||"")},r=d=>{n.name=g.sanitize(d),u("name",n.name)},o=d=>{n.description=g.sanitize(d),u("description",n.description)},s=d=>{n.author=g.sanitize(d),u("author",n.author)},i=()=>n.name,a=()=>n.description,c=()=>n.author,l=()=>n,m=(d,S)=>{let h=document.createElement("meta");h.setAttribute("name",d),h.setAttribute("content",S),document.head.appendChild(h)},u=(d,S)=>{let h=document.querySelector(`meta[name="${d}"]`);h?h.setAttribute("content",S):m(d,S)},p=()=>{u("name",n.name),u("description",n.description),u("author",n.author)};return e&&q(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:l,appendMetaTagsToHead:p}};import ue from"dompurify";var L=(t,e,n,r,o)=>{let s=`#${t}`,i=e.querySelectorAll(s);if(i.length===0)throw new Error(`[useTSComponent] No element found with id '${t}' in the given parent.`);if(i.length>1)throw new Error(`[useTSComponent] Duplicate id '${t}' detected. Found ${i.length} elements.`);let a=i[0];a.innerHTML=ue.sanitize(a.innerHTML,{USE_PROFILES:{html:!0}}),n(a,r,o)};var I=(t,e,n,r=[])=>{let o=new Set;t.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=n[i],l=Array.isArray(r)?r[i]:void 0;typeof c=="function"?L(s,e,c,l):console.warn(`[useTSCollection] No valid component function found for ID: "${s}"`)})};var _=(t,e)=>{let r=(e??document).querySelectorAll(t);if(r.length===0)return process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] No element found for selector: '${t}'`),null;if(t.startsWith("#")&&r.length>1){if(process.env.NODE_ENV!=="production")throw new Error(`[useTSSelect] Duplicate ID detected: '${t}'. Found ${r.length} elements with this ID.`);return r[0]}return r.length>1&&process.env.NODE_ENV!=="production"&&console.warn(`[useTSSelect] Multiple elements found for selector: '${t}'. Returning the first one.`),r[0]};import{jwtDecode as de}from"jwt-decode";var F=(t,e)=>{let n=localStorage.getItem("token");if(!n)return window.location.href=e,null;try{let r=de(n),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 v=(t,e,n)=>{t.forEach(r=>{e.forEach(o=>{r.addEventListener(o,s=>{n(r,s)})})})};var U=()=>({back:()=>window.history.back(),forward:()=>window.history.forward()});var j=(t,e)=>{let n=document.querySelector(`#${t}`)||document.querySelector(`.${t}`);if(!n)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(n);break}}};function W(t,e){let n=window.location.pathname.replace(/\/$/,"");e.routes.forEach(r=>{r.children?.length&&r.children.forEach(o=>{let s=o.path.replace(/\/$/,"");if(n===s||n.startsWith(`${s}/`)){let i=t.querySelector(`#${o.outlet}`)||t.querySelector(`.${o.outlet}`);i instanceof HTMLElement&&o.element&&o.element(i)}})})}import{createStore as me}from"zustand/vanilla";function B(t){let e=me(()=>({value:t})),n=new Set;return{get:()=>e.getState().value,set:r=>{e.setState({value:r}),n.forEach(o=>o(r))},subscribe:r=>(n.add(r),r(e.getState().value),()=>n.delete(r))}}function Q(t){let e=t();typeof e=="function"&&e()}var G=()=>{let t=document.querySelectorAll('a[href^="#"]');v(t,["click"],(e,n)=>{n.preventDefault();let r=e.getAttribute("href")?.substring(1),o=r?document.getElementById(r):null;o&&o.scrollIntoView({behavior:"smooth",block:"start"})})};import{debounce as pe}from"lodash-es";var M=t=>t;typeof window<"u"&&typeof document<"u"&&(M=t=>{let e=document.createElement("div");return e.innerText=t,e.innerHTML});var fe=t=>{(t?Array.isArray(t)?t:t instanceof HTMLAnchorElement?[t]:Array.from(t):Array.from(document.querySelectorAll("a"))).forEach(n=>{if(!n||n.dataset.anchorEnhanced==="true")return;n.dataset.anchorEnhanced="true";let r=n.getAttribute("class")||"";n.setAttribute("class",M(r));let o=n.getAttribute("aria-label");o&&n.setAttribute("aria-label",M(o));let s=n.querySelector(":scope > *");s&&(n.innerHTML="",n.appendChild(s));let i=n.getAttribute("href")||"";if(!i.startsWith("#")){try{if(new URL(i,window.location.href).origin!==window.location.origin)return}catch{return}n.addEventListener("click",a=>{a.preventDefault();let c=n.getAttribute("href")||"";try{let l=new URL(c,window.location.href);window.history.pushState({},"",l.pathname+l.search+l.hash),window.dispatchEvent(new PopStateEvent("popstate"))}catch(l){console.error("Invalid URL in anchor:",c,l)}})}})},he=pe(fe,50),V=t=>{he(t)};var X=t=>{let e=t.querySelectorAll("a");V(e)};var J=t=>{G(),X(t)};var K=async()=>{let t="https://cdn.jsdelivr.net/npm/brython@3/brython.min.js",e="https://cdn.jsdelivr.net/npm/brython@3/brython_stdlib.js",n=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 n(t),await n(e),typeof window.brython=="function"?window.brython():console.error("Brython did not load correctly.")},Y=t=>new Promise((e,n)=>{let r=document.createElement("script");r.type="text/python",r.src=`/src/python/${t}`,r.onload=()=>e(),r.onerror=()=>n(new Error(`Failed to load ${t}`)),document.body.appendChild(r)});function Z(t){let e=null;return async(n,r)=>{try{if(!e){let o=await t();e=o.default||o}if(typeof e=="function")return e(n,r);if(e instanceof HTMLElement){n?.appendChild(e);return}if(e&&typeof e.render=="function")return e.render(n,r);console.warn("useTSLazy: Unsupported module type",e)}catch(o){console.error("useTSLazy failed:",o)}}}var ee=t=>typeof window>"u"?{isDOM:null}:{isDOM:t||document.body};import ne from"dompurify";import{createStore as ge}from"zustand/vanilla";import Se from"dompurify";var f=ge(t=>({params:{},query:{},setParams:e=>t(()=>({params:te(e)})),setQuery:e=>t(()=>({query:te(e)}))}));function te(t){let e={};for(let n in t)e[n]=Se.sanitize(t[n]);return e}var A=class{constructor(e,n){this.routes=[];this.routes=e,this.expectedParams=new Set(n),window.addEventListener("popstate",this.handlePopState.bind(this)),this.handlePopState()}handlePopState(){let e=window.location.pathname,n=window.location.search,r=this.parseQueryParams(n),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,n,r,o,s){if(!e||e.length===0){let a=r.querySelector("#child");a&&a.remove();return}let i=this.findMatchingRoute(n,e);if(i){let a=document.createElement("div");a.id="child";let c={...o,...i.params},l=this.filterAndSanitizeParams(c);if(f.getState().setParams(l),f.getState().setQuery(s),i.element?.(a,l,s),r.appendChild(a),i.children){let m=n.slice(i.path.length);this.renderChildren(i.children,m,a,l,s)}}}parseQueryParams(e){let n={},r=new URLSearchParams(e);for(let[o,s]of r.entries())this.expectedParams.has(o)&&(n[o]=ne.sanitize(s));return n}findMatchingRoute(e,n,r={}){for(let o of n){let s=o.path;if(s==="*")return o;{let a=[],c=s.replace(/:[^\s/]+/g,u=>(a.push(u.substring(1)),"([^\\s/]+)")),l=new RegExp(`^${c}(?:/|$)`),m=e.match(l);if(m){let u={...r};if(a.forEach((p,d)=>{u[p]=m[d+1]??""}),o.children){let p=e.slice(m[0].length),d=this.findMatchingRoute(p,o.children,u);if(d)return d}return{...o,params:u}}}}}filterAndSanitizeParams(e){if(!e)return{};let n={};for(let r in e)this.expectedParams.has(r)&&(n[r]=ne.sanitize(e[r]??""));return n}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{A as TSRouter,Q as createEffect,B as createSignal,P as html,Y as loadPyFiles,se as mapper,W as renderChildRoutes,z as useAnchorSingle,k as useInitialDOM,J as useTSAnchorMount,F as useTSAuth,I as useTSCollection,L as useTSComponent,v as useTSElementEach,O as useTSElements,H as useTSEvent,D as useTSEventAll,C as useTSExtractParams,Z as useTSLazy,N as useTSMetaData,U as useTSNavigate,j as useTSOutlet,E as useTSParams,x as useTSPurifier,ee as useTSSSRHydration,_ as useTSSelect,K 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/func/index.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/hooks/useTSSSRHydration.ts","../src/routes/class/Router.class.ts","../src/store/useTSParam.store.ts","../index.mts"],"sourcesContent":["function sanitize(input: unknown): string {\r\n // Always convert to string first\r\n const str = input === null || input === undefined ? \"\" : String(input);\r\n\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <style> blocks\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\\s*\\/\\s*\\1\\s*>/gi, \"\")\r\n // remove opening dangerous tags without closing\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>/gi, \"\")\r\n // strip inline event handlers like onclick=, onerror=, etc.\r\n .replace(/\\son\\w+\\s*=\\s*(['\"]).*?\\1/gi, \"\")\r\n // block javascript: URLs\r\n .replace(/\\s(href|src)\\s*=\\s*(['\"])\\s*javascript:[^'\"]*\\2/gi, \"\");\r\n}\r\n\r\nexport function html(strings: TemplateStringsArray, ...values: unknown[]): string {\r\n return strings.reduce((result, str, i) => {\r\n const safeValue = i < values.length ? sanitize(values[i]) : \"\";\r\n return result + str + safeValue;\r\n }, \"\");\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 };","// ✅ sanitize HTML but allow harmless tags\r\nconst sanitizeHtml = (str: string) => {\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <meta>, <style>\r\n .replace(/<\\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi, \"\")\r\n // remove any attribute that starts with \"on\" (onerror, onclick, etc.)\r\n .replace(/\\s+on[a-z]+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, \"\")\r\n // block javascript: in href/src\r\n .replace(/\\s+(href|src)\\s*=\\s*(['\"]?)\\s*javascript:[^'\"\\s>]*/gi, \"\")\r\n}\r\n\r\n// ✅ mapper with sanitization\r\nconst mapper = (arr: string[] | undefined) =>\r\n arr?.map((item) => sanitizeHtml(item)).join(\"\") ?? \"\"\r\n\r\nexport { mapper }\r\n","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 EventHandlers = Record<string, EventListener>;\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config,\r\n handlers?: EventHandlers\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (\r\n htmlElement,\r\n element,\r\n config,\r\n handlers = {}\r\n) => {\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 \"data-onclick\", \"data-onchange\", \"data-onselect\" // ✅ added safe attribute\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 inline 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 htmlElement.innerHTML = sanitizedContent;\r\n\r\n // ✅ Bind safe declarative events\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onclick]\").forEach((el) => {\r\n const key = el.dataset.onclick!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"click\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onchange]\").forEach((el) => {\r\n const key = el.dataset.onchange!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"change\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onselect]\").forEach((el) => {\r\n const key = el.dataset.onselect!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"select\", handlers[key]);\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 if (typeof document === \"undefined\") return;\r\n\r\n const targetElement = document.getElementById(id);\r\n if (!targetElement) return;\r\n\r\n const dirtyHTML = targetElement.innerHTML;\r\n\r\n // Strict allow-list: only allowed tags + attrs\r\n const sanitizedHTML = DOMPurify.sanitize(dirtyHTML, {\r\n ALLOWED_TAGS: [\r\n \"div\", \"span\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"ul\", \"ol\", \"li\", \"strong\", \"em\", \"a\", \"img\", \"br\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"href\", \"src\", \"alt\", \"title\", \"class\", \"id\",\r\n \"data-onclick\", \"data-onchange\" // ✅ only these two data-* attrs\r\n ],\r\n ALLOW_DATA_ATTR: false, // block all other data-* attributes\r\n KEEP_CONTENT: false,\r\n });\r\n\r\n // Extra safeguard: strip unsafe URL schemes\r\n const safeHTML = sanitizedHTML.replace(\r\n /\\b(href|src)=[\"']?(?!https?:|mailto:|\\/|#)/gi,\r\n '$1=\"#\"'\r\n );\r\n\r\n if (previousHTML !== null && safeHTML !== previousHTML) {\r\n const fallbackEl = document.createElement(\"div\");\r\n mount(fallbackEl);\r\n targetElement.innerHTML = previousHTML;\r\n } else {\r\n previousHTML = safeHTML;\r\n targetElement.innerHTML = safeHTML;\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>(\r\n selector: string,\r\n scope?: HTMLElement\r\n) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(\r\n selector: string,\r\n scope?: HTMLElement\r\n): T | null => {\r\n const root = scope ?? document;\r\n const elements = root.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n if (process.env.NODE_ENV !== \"production\") {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n }\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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 return elements[0]; // fallback: just return first\r\n }\r\n\r\n if (elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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\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","// useTSNoReload.ts\r\nimport { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = (DOM: HTMLElement) => {\r\n const anchors = DOM.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n\r\n anchors.forEach(anchor => {\r\n anchor.addEventListener(\"click\", (e) => {\r\n // If it's an internal link, stop reload\r\n const href = anchor.getAttribute(\"href\");\r\n if (href && href.startsWith(\"/\")) {\r\n e.preventDefault();\r\n useAnchor(anchor); // let your hook handle navigation\r\n }\r\n });\r\n });\r\n};\r\n\r\nexport { useTSNoReload };\r\n","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = (DOM: HTMLElement) => {\r\n useTSHashAnchor();\r\n useTSNoReload(DOM);\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","\r\nconst useTSSSRHydration = (DOM: HTMLElement) => {\r\n if (typeof window === \"undefined\") {\r\n return { isDOM: null };\r\n }\r\n\r\n const isDOM = DOM || document.body;\r\n\r\n return { isDOM };\r\n};\r\n\r\nexport { useTSSSRHydration };\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 { mapper } from './src/func'\r\nexport { createEffect, createSignal, renderChildRoutes, useTSSSRHydration, 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":["sanitize","input","html","strings","values","result","str","i","safeValue","autoRegister","allTags","el","tagName","tag","sanitizeHtml","str","mapper","arr","item","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","handlers","defaultConfig","node","data","tagName","sanitizedContent","el","key","DOMPurify","previousHTML","useInitialDOM","id","mount","targetElement","dirtyHTML","safeHTML","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","scope","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","DOM","anchor","e","href","useAnchor","useTSAnchorMount","DOM","useTSHashAnchor","useTSNoReload","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","factory","cached","el","props","mod","err","useTSSSRHydration","DOM","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/func/index.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/hooks/useTSSSRHydration.ts","../src/routes/class/Router.class.ts","../src/store/useTSParam.store.ts","../index.mts"],"sourcesContent":["function sanitize(input: unknown): string {\r\n // Always convert to string first\r\n const str = input === null || input === undefined ? \"\" : String(input);\r\n\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <style> blocks\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>.*?<\\s*\\/\\s*\\1\\s*>/gi, \"\")\r\n // remove opening dangerous tags without closing\r\n .replace(/<\\s*(script|iframe|object|embed|link|style)[^>]*>/gi, \"\")\r\n // strip inline event handlers like onclick=, onerror=, etc.\r\n .replace(/\\son\\w+\\s*=\\s*(['\"]).*?\\1/gi, \"\")\r\n // block javascript: URLs\r\n .replace(/\\s(href|src)\\s*=\\s*(['\"])\\s*javascript:[^'\"]*\\2/gi, \"\");\r\n}\r\n\r\nexport function html(strings: TemplateStringsArray, ...values: unknown[]): string {\r\n return strings.reduce((result, str, i) => {\r\n const safeValue = i < values.length ? sanitize(values[i]) : \"\";\r\n return result + str + safeValue;\r\n }, \"\");\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 };","// ✅ sanitize HTML but allow harmless tags\r\nconst sanitizeHtml = (str: string) => {\r\n return str\r\n // remove <script>, <iframe>, <object>, <embed>, <link>, <meta>, <style>\r\n .replace(/<\\/?(script|iframe|object|embed|link|meta|style)[^>]*>/gi, \"\")\r\n // remove any attribute that starts with \"on\" (onerror, onclick, etc.)\r\n .replace(/\\s+on[a-z]+\\s*=\\s*(\"[^\"]*\"|'[^']*'|[^\\s>]+)/gi, \"\")\r\n // block javascript: in href/src\r\n .replace(/\\s+(href|src)\\s*=\\s*(['\"]?)\\s*javascript:[^'\"\\s>]*/gi, \"\")\r\n}\r\n\r\n// ✅ mapper with sanitization\r\nconst mapper = (arr: string[] | undefined) =>\r\n arr?.map((item) => sanitizeHtml(item)).join(\"\") ?? \"\"\r\n\r\nexport { mapper }\r\n","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 EventHandlers = Record<string, EventListener>;\r\n\r\ntype TSElements = (\r\n htmlElement: HTMLElement,\r\n element: string,\r\n config?: Config,\r\n handlers?: EventHandlers\r\n) => void;\r\n\r\nexport const useTSElements: TSElements = (\r\n htmlElement,\r\n element,\r\n config,\r\n handlers = {}\r\n) => {\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 \"data-onclick\", \"data-onchange\", \"data-onselect\" // ✅ added safe attribute\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 inline 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 htmlElement.innerHTML = sanitizedContent;\r\n\r\n // ✅ Bind safe declarative events\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onclick]\").forEach((el) => {\r\n const key = el.dataset.onclick!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"click\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onchange]\").forEach((el) => {\r\n const key = el.dataset.onchange!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"change\", handlers[key]);\r\n }\r\n });\r\n\r\n htmlElement.querySelectorAll<HTMLElement>(\"[data-onselect]\").forEach((el) => {\r\n const key = el.dataset.onselect!;\r\n if (handlers[key]) {\r\n el.addEventListener(\"select\", handlers[key]);\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 if (typeof document === \"undefined\") return;\r\n\r\n const targetElement = document.getElementById(id);\r\n if (!targetElement) return;\r\n\r\n const dirtyHTML = targetElement.innerHTML;\r\n\r\n // Strict allow-list: only allowed tags + attrs\r\n const sanitizedHTML = DOMPurify.sanitize(dirtyHTML, {\r\n ALLOWED_TAGS: [\r\n \"div\", \"span\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\",\r\n \"ul\", \"ol\", \"li\", \"strong\", \"em\", \"a\", \"img\", \"br\"\r\n ],\r\n ALLOWED_ATTR: [\r\n \"href\", \"src\", \"alt\", \"title\", \"class\", \"id\",\r\n \"data-onclick\", \"data-onchange\" // ✅ only these two data-* attrs\r\n ],\r\n ALLOW_DATA_ATTR: false, // block all other data-* attributes\r\n KEEP_CONTENT: false,\r\n });\r\n\r\n // Extra safeguard: strip unsafe URL schemes\r\n const safeHTML = sanitizedHTML.replace(\r\n /\\b(href|src)=[\"']?(?!https?:|mailto:|\\/|#)/gi,\r\n '$1=\"#\"'\r\n );\r\n\r\n if (previousHTML !== null && safeHTML !== previousHTML) {\r\n const fallbackEl = document.createElement(\"div\");\r\n mount(fallbackEl);\r\n targetElement.innerHTML = previousHTML;\r\n } else {\r\n previousHTML = safeHTML;\r\n targetElement.innerHTML = safeHTML;\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>(\r\n selector: string,\r\n scope?: HTMLElement\r\n) => T | null;\r\n\r\nconst useTSSelect: TSSelect = <T extends Element = HTMLElement>(\r\n selector: string,\r\n scope?: HTMLElement\r\n): T | null => {\r\n const root = scope ?? document;\r\n const elements = root.querySelectorAll<T>(selector);\r\n\r\n if (elements.length === 0) {\r\n if (process.env.NODE_ENV !== \"production\") {\r\n console.warn(`[useTSSelect] No element found for selector: '${selector}'`);\r\n }\r\n return null;\r\n }\r\n\r\n if (selector.startsWith(\"#\") && elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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 return elements[0]; // fallback: just return first\r\n }\r\n\r\n if (elements.length > 1) {\r\n if (process.env.NODE_ENV !== \"production\") {\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\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\n// Simple sanitization (escape HTML entities)\r\nlet sanitizeInput = (input: string): string => input;\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\n/**\r\n * Enhance anchors for SPA navigation\r\n */\r\nconst enhanceAnchors = (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 class + aria-label, but don't rewrite href\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 // Handle child sanitization safely (optional)\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 const href = anchor.getAttribute(\"href\") || \"\";\r\n\r\n // Skip hash links\r\n if (href.startsWith(\"#\")) return;\r\n\r\n // Skip external links\r\n try {\r\n const url = new URL(href, window.location.href);\r\n if (url.origin !== window.location.origin) return;\r\n } catch {\r\n return;\r\n }\r\n\r\n // ✅ Intercept internal navigation\r\n anchor.addEventListener(\"click\", (e: MouseEvent) => {\r\n e.preventDefault(); // stop reload immediately\r\n const rawHref = anchor.getAttribute(\"href\") || \"\";\r\n try {\r\n const url = new URL(rawHref, 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:\", rawHref, err);\r\n }\r\n });\r\n });\r\n};\r\n\r\n// Debounced wrapper (for dynamic DOM changes)\r\nconst _enhanceAnchors = debounce(enhanceAnchors, 50);\r\n\r\nexport const useAnchor = (anchors?: AnchorInput): void => {\r\n _enhanceAnchors(anchors);\r\n};\r\n","// useTSNoReload.ts\r\nimport { useAnchor } from './useTSAnchor';\r\n\r\nconst useTSNoReload = (DOM: HTMLElement) => {\r\n const anchors = DOM.querySelectorAll(\"a\") as NodeListOf<HTMLAnchorElement>;\r\n useAnchor(anchors);\r\n};\r\n\r\nexport { useTSNoReload };\r\n","import { useTSHashAnchor } from \"./useTSHashAnchor\";\r\nimport { useTSNoReload } from \"./useTSNoReload\";\r\n\r\nconst useTSAnchorMount = (DOM: HTMLElement) => {\r\n useTSHashAnchor();\r\n useTSNoReload(DOM);\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","\r\nconst useTSSSRHydration = (DOM: HTMLElement) => {\r\n if (typeof window === \"undefined\") {\r\n return { isDOM: null };\r\n }\r\n\r\n const isDOM = DOM || document.body;\r\n\r\n return { isDOM };\r\n};\r\n\r\nexport { useTSSSRHydration };\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 { mapper } from './src/func'\r\nexport { createEffect, createSignal, renderChildRoutes, useTSSSRHydration, 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":["sanitize","input","html","strings","values","result","str","i","safeValue","autoRegister","allTags","el","tagName","tag","sanitizeHtml","str","mapper","arr","item","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","handlers","defaultConfig","node","data","tagName","sanitizedContent","el","key","DOMPurify","previousHTML","useInitialDOM","id","mount","targetElement","dirtyHTML","safeHTML","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","scope","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","originalClassName","ariaLabel","child","href","e","rawHref","url","err","_enhanceAnchors","useAnchor","useTSNoReload","DOM","anchors","useAnchor","useTSAnchorMount","DOM","useTSHashAnchor","useTSNoReload","useTSloadBrython","brythonJS","brythonStdlib","loadScript","src","resolve","reject","script","loadPyFiles","useTSLazy","factory","cached","el","props","mod","err","useTSSSRHydration","DOM","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.132",
3
+ "version": "1.2.133",
4
4
  "description": "Framework-less TypeScript hooks for SPA development.",
5
5
  "author": "Waren Arapoc Gador",
6
6
  "license": "MIT",