lego-dom 2.1.3 → 2.1.4

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/lego.min.js CHANGED
@@ -1,7 +1,7 @@
1
- (()=>{var w={},q=new WeakMap,B=new WeakMap,M=new WeakMap,Q=new WeakMap,L=new Set,K=new Set,R=new Map,Z=new Map;var _=e=>(B.has(e)||B.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),B.get(e));var x={},he=e=>{x=e};var f={onError:(e,r,t)=>{console.error(`[Lego Error] [${r}]`,e,t)},metrics:{},debug:!1,syntax:"brackets"},P=(e,r)=>{!e||!r||Object.getOwnPropertyNames(e).forEach(t=>{let o=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,o)})},U=()=>f.syntax==="brackets"?["[[","]]"]:["{{","}}"],ne=new Map,j=()=>{let[e,r]=U(),t=e+r;if(ne.has(t))return ne.get(t);let o=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),s=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`${o}(.*?)${s}`,"g");return ne.set(t,n),n},be=e=>{let t=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!t.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return t},C=(e,r)=>{if(!e)return"";let t=e.trim().split("."),o=r;for(let s of t){if(o==null)return"";o=o[s]}return o??""},ae=e=>typeof Node<"u"&&e instanceof Node,k=(e,r,t)=>{if(r.nodeType!==Node.ELEMENT_NODE)return;let o=[...r.attributes].find(n=>n.name===e||n.name.startsWith(`${e}.`));if(!o)return;let s={};return t&&(s=t(o,r)),{type:e,node:r,expr:o.value,modifiers:o.name.split(".").slice(1),...s}};var Y=class{constructor(r=1e3){this.limit=r,this.cache=new Map}get(r){if(!this.cache.has(r))return;let t=this.cache.get(r);return this.cache.delete(r),this.cache.set(r,t),t}set(r,t){if(this.cache.has(r))this.cache.delete(r);else if(this.cache.size>=this.limit){let o=this.cache.keys().next().value;this.cache.delete(o)}this.cache.set(r,t)}get size(){return this.cache.size}clear(){this.cache.clear()}};var F=(e,r)=>{if(!e)return;let t=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;t;){let o=t.tagName?t.tagName.toLowerCase():"";if(o&&(r==="*"&&w[o]||o===r.toLowerCase()))return t;t=t.parentElement||t.getRootNode&&t.getRootNode().host}},ye=(e,r)=>{if(typeof e=="function"){let o=Array.from(document.querySelectorAll("*")).filter(s=>s.tagName.includes("-"));return[].concat(e(o))}if(e.startsWith("#")){let o=document.getElementById(e.slice(1));return o?[o]:[]}let t=r?.querySelectorAll(e)||[];return t.length>0?[...t]:[...document.querySelectorAll(e)]},ee=(e,r)=>{if(e.type==="checkbox")e.checked!==!!r&&(e.checked=!!r);else{let t=r==null?"":String(r);e.value!==t&&(e.value=t)}};var ie=null,Ee=e=>{ie=e},G=[],ce=e=>{let r=G.find(s=>s.regex.test(e));if(!r)return null;let t=e.match(r.regex).slice(1),o=r.paramNames?Object.fromEntries(r.paramNames.map((s,n)=>[s,t[n]])):{};return{match:r,params:o}},te=async(e=null,r=null)=>{if(typeof window>"u")return;let t=window.location.pathname,o=ce(t);if(f.debug&&console.log("[Lego Trace] Matching route",t,o?.match),!o)return;let{match:s,params:n}=o;if(s.middleware&&!await s.middleware({path:t,params:n}))return;let i=e&&e.length?e:["lego-router"],a=r||document;s.tagName&&i.flatMap(l=>ye(l,a)).forEach(l=>{l&&(l.innerHTML=`<${s.tagName}></${s.tagName}>`,ie&&ie(l.firstElementChild))})},re=(e,...r)=>t=>{let o=async(s,n=null,i=!0,a={})=>{if(i&&typeof history<"u"){let l={legoTargets:r.filter(m=>typeof m=="string"),method:s,body:n};history.pushState(l,"",e)}await te(r.length?r:null,t)};return{get:(s=!0,n={})=>o("GET",null,s,n),post:(s,n=!0,i={})=>o("POST",s,n,i),put:(s,n=!0,i={})=>o("PUT",s,n,i),patch:(s,n=!0,i={})=>o("PATCH",s,n,i),delete:(s=!0,n={})=>o("DELETE",null,s,n)}};var we=new Y(1e3),N=(e,r,t=!0)=>{if(/\b(function|eval|import|class|module|deploy|constructor|__proto__)\b/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let o=r.state||{},s=we.get(e);s||(s=new Function("global","self","event","helpers",`
1
+ (()=>{var y={},I=new WeakMap,D=new WeakMap,C=new WeakMap,X=new WeakMap,_=new Set,q=new Set,R=new Map,Q=new Map;var M=e=>(D.has(e)||D.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),D.get(e));var N={},he=e=>{N=e};var m={onError:(e,r,o)=>{console.error(`[Lego Error] [${r}]`,e,o)},metrics:{},debug:!1,syntax:"brackets"},P=(e,r)=>{!e||!r||Object.getOwnPropertyNames(e).forEach(o=>{let s=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(r,o,s)})},U=()=>m.syntax==="brackets"?["[[","]]"]:["{{","}}"],ne=new Map,j=()=>{let[e,r]=U(),o=e+r;if(ne.has(o))return ne.get(o);let s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`${s}(.*?)${t}`,"g");return ne.set(o,a),a},be=e=>{let o=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!o.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return o},B=(e,r)=>{if(!e)return"";let o=e.trim().split("."),s=r;for(let t of o){if(s==null)return"";s=s[t]}return s??""},ae=e=>typeof Node<"u"&&e instanceof Node,O=(e,r,o)=>{if(r.nodeType!==Node.ELEMENT_NODE)return;let s=[...r.attributes].find(a=>a.name===e||a.name.startsWith(`${e}.`));if(!s)return;let t={};return o&&(t=o(s,r)),{type:e,node:r,expr:s.value,modifiers:s.name.split(".").slice(1),...t}};var Z=class{constructor(r=1e3){this.limit=r,this.cache=new Map}get(r){if(!this.cache.has(r))return;let o=this.cache.get(r);return this.cache.delete(r),this.cache.set(r,o),o}set(r,o){if(this.cache.has(r))this.cache.delete(r);else if(this.cache.size>=this.limit){let s=this.cache.keys().next().value;this.cache.delete(s)}this.cache.set(r,o)}get size(){return this.cache.size}clear(){this.cache.clear()}};var F=(e,r)=>{if(!e)return;let o=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;o;){let s=o.tagName?o.tagName.toLowerCase():"";if(s&&(r==="*"&&y[s]||s===r.toLowerCase()))return o;o=o.parentElement||o.getRootNode&&o.getRootNode().host}},ye=(e,r)=>{if(typeof e=="function"){let s=Array.from(document.querySelectorAll("*")).filter(t=>t.tagName.includes("-"));return[].concat(e(s))}if(e.startsWith("#")){let s=document.getElementById(e.slice(1));return s?[s]:[]}let o=r?.querySelectorAll(e)||[];return o.length>0?[...o]:[...document.querySelectorAll(e)]},Y=(e,r)=>{if(e.type==="checkbox")e.checked!==!!r&&(e.checked=!!r);else{let o=r==null?"":String(r);e.value!==o&&(e.value=o)}};var ie=null,Ee=e=>{ie=e},K=[],ce=e=>{let r=K.find(t=>t.regex.test(e));if(!r)return null;let o=e.match(r.regex).slice(1),s=r.paramNames?Object.fromEntries(r.paramNames.map((t,a)=>[t,o[a]])):{};return{match:r,params:s}},ee=async(e=null,r=null)=>{if(typeof window>"u")return;let o=window.location.pathname,s=ce(o);if(m.debug&&console.log("[Lego Trace] Matching route",o,s?.match),!s)return;let{match:t,params:a}=s;if(t.middleware&&!await t.middleware({path:o,params:a}))return;let i=e&&e.length?e:["lego-router"],n=r||document;t.tagName&&i.flatMap(l=>ye(l,n)).forEach(l=>{l&&(l.innerHTML=`<${t.tagName}></${t.tagName}>`,ie&&ie(l.firstElementChild))})},te=(e,...r)=>o=>{let s=async(t,a=null,i=!0,n={})=>{if(i&&typeof history<"u"){let l={legoTargets:r.filter(d=>typeof d=="string"),method:t,body:a};history.pushState(l,"",e)}await ee(r.length?r:null,o)};return{get:(t=!0,a={})=>s("GET",null,t,a),post:(t,a=!0,i={})=>s("POST",t,a,i),put:(t,a=!0,i={})=>s("PUT",t,a,i),patch:(t,a=!0,i={})=>s("PATCH",t,a,i),delete:(t=!0,a={})=>s("DELETE",null,t,a)}};var we=new Z(1e3),x=(e,r,o=!0)=>{if(/\b(function|eval|import|class|module|deploy|constructor|__proto__)\b/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let s=r.state||{},t=we.get(e);t||(t=new Function("global","self","event","helpers",`
2
2
  with(this) {
3
3
  with(helpers) {
4
4
  return ${e}
5
5
  }
6
6
  }
7
- `),we.set(e,s));let n={$ancestors:a=>F(r.self,a),$registry:a=>Z.get(a.toLowerCase()),$element:r.self,$route:x.$route,$go:(a,...c)=>re(a,...c)(r.self),$db:x.$db,$emit:(a,c)=>{r.self.dispatchEvent(new CustomEvent(a,{detail:c,bubbles:!0,composed:!0}))}},i=s.call(o,r.global,r.self,r.event,n);return typeof i=="function"?i.call(o,r.event):i}catch(o){if(t)throw o;f.onError(o,"render-error",r.self);return}},le=(e,r={})=>{if(!e||e.trim()==="{}")return{};let t=o=>new Function("scope","global",`with(global) { with(scope) { return (${o}); } }`)(r,x);try{return t(e)}catch(o){let s=e.trim();if(!s.startsWith("{")&&s.includes(":"))try{return t(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,o),{}}};var Ne={name:"b-if",scan:(e,{checkGlobal:r,getPrivateData:t})=>k("b-if",e,(o,s)=>{r(o.value);let n=document.createComment(`b-if: ${o.value}`),i=t(s);return i.anchor=n,{anchor:n}}),execute({binding:e,state:r,global:t}){let{node:o,anchor:s,expr:n}=e,i=!!N(n,{state:r,global:t,self:o}),a=!!o.parentNode;i&&!a?s.parentNode&&s.parentNode.replaceChild(o,s):!i&&a&&o.parentNode.replaceChild(s,o)}};var xe={name:"b-show",scan(e,{checkGlobal:r}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let t=e.getAttribute("b-show");return r(t),{type:"b-show",node:e,expr:t}}},execute({binding:e,state:r,global:t}){let{node:o,expr:s}=e;o.style.display=N(s,{state:r,global:t,self:o})?"":"none"}};var ve={name:"b-text",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text"))return{type:"b-text",node:e,path:e.getAttribute("b-text")}},execute({binding:e,state:r}){let{node:t,path:o}=e;t.textContent=C(o,r)}};var Se={name:"b-html",scan:e=>k("b-html",e),execute:({binding:e,state:r,global:t})=>{let{node:o,expr:s}=e;o.innerHTML=N(s,{state:r,global:t,self:o})||""}};var Le={name:"b-sync",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-sync"))return{type:"b-sync",node:e}},execute({binding:e,state:r}){let{node:t}=e;ee(t,C(t.getAttribute("b-sync"),r))}};var $e={name:"b-for",scan(e,{checkGlobal:r,pendingOperations:t}){if(e.nodeType!==Node.ELEMENT_NODE)return;let o=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(o){r(o[2]);let s=document.createComment(`b-for: ${o[1]} in ${o[2].trim()}`);return t.push(()=>{e.parentNode&&(e.parentNode.insertBefore(s,e),e.remove())}),{type:"b-for",anchor:s,itemName:o[1],listName:o[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0)}}},execute({binding:e,state:r,global:t,helpers:o}){let{bind:s,updateNodeBindings:n}=o;if(!s||!n){console.error("[Lego] b-for directive missing required helpers: bind, updateNodeBindings");return}let{anchor:i,listName:a,itemName:c,keyPath:l,template:m}=e,{contextEl:g}=o,d=N(a,{state:r,global:t,self:g})||[];M.has(i)||M.set(i,new Map);let p=M.get(i),b=new Set,h=[];d.forEach((u,v)=>{let y;l?(y=C(l,u),y===void 0&&console.warn(`[Lego] b-key="${l}" resolved to undefined for item at index ${v}. Check for typos.`)):u&&typeof u=="object"?(y=u.id||u._id||u.uuid||u.key,y===void 0&&(Q.has(u)||Q.set(u,Math.random()),y=Q.get(u))):y=`${v}-${u}`,b.add(y);let A=p.get(y);A||(A=m.cloneNode(!0),A.removeAttribute("b-for"),A.removeAttribute("b-key"),p.set(y,A),s(A,g,{name:c,listName:a,index:v}));let Ie=Object.assign(Object.create(r),{[c]:u,$index:v});n(A,Ie),A.querySelectorAll("[b-sync]").forEach(me=>{let ge=me.getAttribute("b-sync");if(ge.startsWith(`${c}.`)){let qe=N(a,{state:r,global:t,self:g});ee(me,C(ge.split(".").slice(1).join("."),qe[v]))}}),h.push(A)});let E=i.nextSibling;h.forEach(u=>{u!==E?i.parentNode.insertBefore(u,E):E=E.nextSibling});for(let[u,v]of p.entries())b.has(u)||(v.remove(),p.delete(u))}};var _e={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:r})=>{e.initialized||(e.initialized=!0,N(e.expr,{state:r}))}};var Te={name:"b-enter",scan:e=>k("b-enter",e,(r,t)=>({modifiers:r.name.split(".").slice(1)})),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let t=new IntersectionObserver((o,s)=>{o[0].isIntersecting&&(N(e.expr,{state:r}),e.modifiers.includes("once")&&(s.disconnect(),e.observer=null,e.done=!0))});t.observe(e.node),e.observer=t},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Ae={scan:e=>k("b-leave",e),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let t=new IntersectionObserver((o,s)=>{let n=o[0];n.isIntersecting&&(e.activated=!0),!n.isIntersecting&&e.activated&&(N(e.expr,{state:r}),e.modifiers.includes("once")&&(s.disconnect(),e.observer=null,e.done=!0))});t.observe(e.node),e.observer=t},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var J={"b-if":Ne,"b-show":xe,"b-text":ve,"b-html":Se,"b-sync":Le,"b-for":$e,"b-init":_e,"b-enter":Te,"b-leave":Ae};var Ke=(e=null)=>{let r=!1,t=new Set,o=!1,s=e,n=new Set,i=null,a=new Set,c=d=>{s=d},l=()=>{i&&clearTimeout(i),i=setTimeout(()=>{a.forEach(d=>{let p=d._studs;if(p&&typeof p.updated=="function")try{p.updated.call(p)}catch(b){console.error("[Lego] Error in updated hook:",b)}}),a.clear(),i=null},50)},m=()=>{n.size>0&&(n.forEach(d=>t.add(d)),n.clear(),!r&&t.size>0&&(r=!0,requestAnimationFrame(g)))},g=()=>{o=!0;let d=Array.from(t);t.clear(),r=!1,d.forEach(p=>{p.isConnected&&s&&s(p)}),d.forEach(p=>a.add(p)),l(),o=!1,m()};return{add:d=>{if(d){if(o){n.add(d);return}t.add(d),!r&&(r=!0,requestAnimationFrame(g))}},setHandler:c}},oe=Ke();var $=new Map,se=new Map,V=new WeakMap,X=new Map,Ue=e=>{let r=Array.from(X.entries()).filter(([s])=>s.startsWith("lego:")).sort((s,n)=>s[1].timestamp-n[1].timestamp),t=0,o=[];for(let[s,n]of r){if(t>=e)break;try{localStorage.removeItem(s),t+=n.size,o.push(s),X.delete(s)}catch(i){console.error(`[Lego] Failed to evict ${s}:`,i)}}return o},Me=(e,r,t)=>{f.debug&&console.log("[Lego Trace] scheduleSave",e,r,t),se.has(e)&&clearTimeout(se.get(e));let o=()=>{try{let s=JSON.stringify(r),n=new Blob([s]).size;localStorage.setItem(e,s);let i=e.startsWith("lego:")?e:`lego:${e}`;X.set(i,{timestamp:Date.now(),size:n}),se.delete(e)}catch(s){if(s.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let n=JSON.stringify(r),i=new Blob([n]).size,a=Ue(i*2);if(a.length>0){f.debug&&console.log(`[Lego] Evicted ${a.length} old keys, retrying save`),localStorage.setItem(e,n);let c=e.startsWith("lego:")?e:`lego:${e}`;X.set(c,{timestamp:Date.now(),size:i})}else f.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{f.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,s)}};t>0?se.set(e,setTimeout(o,t)):o()},ue=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(t){return this._default=t,this},debounce(t){return this._debounce=t,this},set(t,o=0){return Me(e,t,o),$.has(e)&&$.get(e).forEach(({target:s,prop:n,el:i,batcher:a})=>{s[n]=t,i&&a&&a.add(i)}),t},get(){try{let t=localStorage.getItem(e);return t!==null?JSON.parse(t):null}catch(t){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,t),null}},delete(){try{return localStorage.removeItem(e),X.delete(e.startsWith("lego:")?e:`lego:${e}`),$.has(e)&&$.get(e).forEach(({target:t,prop:o,el:s,batcher:n})=>{t[o]=null,s&&n&&n.add(s)}),!0}catch(t){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,t),!1}}}),ke=e=>e&&e.__type==="lego-db",Ce=(e,r,t,o,s)=>{f.debug&&console.log("[Lego Trace] Reactive DB Init:",r,t);let n=t._default;try{let i=localStorage.getItem(t.key);i!==null&&(n=JSON.parse(i))}catch(i){console.warn(`[Lego] Failed to parse localStorage value for key "${t.key}":`,i)}e[r]=n,V.has(e)||V.set(e,{}),V.get(e)[r]={key:t.key,debounce:t._debounce},f.debug&&console.log("[Lego Trace] DB Metadata Set:",r,V.get(e)[r]),$.has(t.key)||$.set(t.key,new Set),$.get(t.key).add({target:e,prop:r,el:o,batcher:s})},Oe=(e,r,t)=>{let o=V.get(e);if(o&&o[r]){let s=o[r].key;Me(s,t,o[r].debounce),$.has(s)&&$.get(s).forEach(({target:n,prop:i,el:a,batcher:c})=>{n!==e&&(n[i]=t,a&&c&&c.add(a))})}},De=()=>{typeof window<"u"&&window.addEventListener("storage",e=>{if(!(!e.key||!$.has(e.key)))try{let r=JSON.parse(e.newValue);$.get(e.key).forEach(({target:t,prop:o,el:s,batcher:n})=>{t[o]=r,s&&n&&n.add(s)})}catch(r){console.warn("[Lego] Cross-tab sync error:",r)}})};var z=(e,r,t=oe)=>{if(e===null||typeof e!="object"||ae(e))return e;if(q.has(e))return q.get(e);for(let n in e){let i=Object.getOwnPropertyDescriptor(e,n);if(i&&i.get)continue;let a=e[n];ke(a)&&Ce(e,n,a,r,t)}let o={get:(n,i)=>{let a=Reflect.get(n,i);return a!==null&&typeof a=="object"&&!ae(a)?z(a,r,t):a},set:(n,i,a,c)=>{let l=n[i];f.debug&&l!==a&&console.log("[Lego Trace] Reactive SET:",i,"Old:",l,"New:",a,"Target:",n);let m=Reflect.set(n,i,a,c);return c===q.get(n)&&l!==a&&(t.add(r),Oe(n,i,a)),m},deleteProperty:(n,i)=>{let a=Reflect.deleteProperty(n,i);return t.add(r),a}},s=new Proxy(e,o);return q.set(e,s),s};var je=e=>{let r=e;for(;r;){let t=r.getAttribute&&r.getAttribute("b-error");if(t)return{errorTag:t,targetElement:r};let o=r.tagName?r.tagName.toLowerCase():"",s=w[o];if(s){let n=s.getAttribute("b-error");if(n)return{errorTag:n,targetElement:r}}r=r.parentElement||r.getRootNode&&r.getRootNode().host}return null},de=null,fe=null,Be=(e,r)=>{de=e,fe=r},Ge=(e,r,t)=>{if(!de||!fe){console.error("[Lego] Error boundary dependencies not loaded",t);return}try{r.shadowRoot?r.shadowRoot.innerHTML="":r.innerHTML="";let o=document.createElement(e);(r.shadowRoot||r).appendChild(o),de(o),o._studs&&(o._studs.$error={message:t.message,stack:t.stack,component:r.tagName.toLowerCase()},fe(o))}catch(o){console.error("[Lego] Error boundary failed to render:",o),console.error("[Lego] Original error:",t)}},W=(e,r,t)=>{let o=je(r);o?Ge(o.errorTag,o.targetElement,e):f.onError(e,t,r)};var H=(e,r,t=null)=>{let o=r._studs,s=a=>{let c=_(a);if(!c.bound){if(a.hasAttributes()){let l=a.attributes;for(let m=0;m<l.length;m++){let g=l[m];if(g.name.startsWith("@")){let d=g.name.slice(1).split("."),p=d[0],b=d.slice(1);a.addEventListener(p,h=>{if(b.includes("prevent")&&h.preventDefault(),b.includes("stop")&&h.stopPropagation(),!(b.includes("self")&&h.target!==h.currentTarget)){if(typeof KeyboardEvent<"u"&&h instanceof KeyboardEvent){if(b.includes("ctrl")&&!h.ctrlKey||b.includes("alt")&&!h.altKey||b.includes("shift")&&!h.shiftKey||b.includes("meta")&&!h.metaKey)return;let E=b.filter(u=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(u));if(E.length>0){let u=h.key.toLowerCase();if(!E.some(y=>y==="enter"?u==="enter":y==="esc"||y==="escape"?u==="escape":y==="space"?u===" ":y==="tab"?u==="tab":y==="delete"?u==="delete":y==="backspace"?u==="backspace":y==="up"?u==="arrowup":y==="down"?u==="arrowdown":y==="left"?u==="arrowleft":y==="right"?u==="arrowright":y==="alpha"?/^[a-z]$/.test(u):y==="numbers"?/^[0-9]$/.test(u):y===u))return}}try{let E=o;if(t){let v=N(t.listName,{state:o,global:x,self:r})[t.index];E=Object.assign(Object.create(o),{[t.name]:v})}N(g.value,{state:E,global:x,self:a,event:h,$event:h},!0)}catch(E){W(E,r,"event-handler")}}})}}if(a.hasAttribute("b-sync")){let m=a.getAttribute("b-sync"),g=()=>{try{let d,p;if(t&&m.startsWith(`${t.name}.`)){let E=N(t.listName,{state:o,global:x,self:r})[t.index];if(!E)return;let u=m.split(".").slice(1);p=u.pop(),d=u.reduce((v,y)=>v[y],E)}else{let h=m.split(".");p=h.pop(),d=h.reduce((E,u)=>E[u],o)}let b=a.type==="checkbox"?a.checked:a.value;d&&d[p]!==b&&(d[p]=b)}catch(d){f.onError(d,"sync-update",a)}};a.addEventListener("input",g),a.addEventListener("change",g)}if(a.hasAttribute("b-var")){let m=a.getAttribute("b-var");o.$vars&&(o.$vars[m]=a)}}c.bound=!0}};e instanceof Element&&s(e);let n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),i;for(;i=n.nextNode();)s(i)},Je=e=>{let r=[],t=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),o,s=[];for(;o=t.nextNode();){let n=o;if((c=>{let l=c.parentNode;for(;l&&l!==e;){if(l.hasAttribute&&l.hasAttribute("b-for"))return!0;l=l.parentNode}return!1})(o))continue;let a=c=>{if(/\bglobal\b/.test(c)){let l=e.host||e;K.add(l)}};if(o.nodeType===Node.ELEMENT_NODE){for(let[l,m]of Object.entries(J))if(m.scan){let g=m.scan(o,{checkGlobal:a,getPrivateData:_,pendingOperations:s,current:n});g&&r.push(g)}let[c]=U();[...o.attributes].forEach(l=>{l.value.includes(c)&&(a(l.value),r.push({type:"attr",node:o,attrName:l.name,template:l.value}))})}else if(o.nodeType===Node.TEXT_NODE){let[c]=U();o.textContent.includes(c)&&(a(o.textContent),r.push({type:"text",node:o,template:o.textContent}))}}return s.forEach(n=>n()),r},Ve=(e,r)=>{let t=n=>{if(n.nodeType===Node.TEXT_NODE){n._tpl===void 0&&(n._tpl=n.textContent);let i=n._tpl.replace(j(),(a,c)=>N(c.trim(),{state:r,global:x,self:n})??"");n.textContent!==i&&(n.textContent=i)}else if(n.nodeType===Node.ELEMENT_NODE){let[i]=U();[...n.attributes].forEach(a=>{if(a._tpl===void 0&&(a._tpl=a.value),a._tpl.includes(i)){let c=a._tpl.replace(j(),(l,m)=>N(m.trim(),{state:r,global:x,self:n})??"");a.value!==c&&(a.value=c,a.name==="class"&&(n.className=c))}})}};t(e);let o=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),s;for(;s=o.nextNode();)t(s)},O=e=>{f.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let r=e._studs;if(!r)return;let t=_(e);if(!t.rendering){t.rendering=!0,f.metrics&&f.metrics.onRenderStart&&f.metrics.onRenderStart(e);try{let o=e.shadowRoot||e;t.bindings||(t.bindings=Je(o)),t.bindings.forEach(s=>{let n=J[s.type];if(n){n.execute({binding:s,state:r,global:x,helpers:{bind:H,updateNodeBindings:Ve,contextEl:e}});return}if(s.type==="text"){let i=s.template.replace(j(),(a,c)=>N(c.trim(),{state:r,global:x,self:s.node})??"");s.node.textContent!==i&&(s.node.textContent=i)}if(s.type==="attr"){let i=s.template.replace(j(),(a,c)=>N(c.trim(),{state:r,global:x,self:s.node})??"");s.node.getAttribute(s.attrName)!==i&&(s.node.setAttribute(s.attrName,i),s.attrName==="class"&&(s.node.className=i))}}),r===x&&K.forEach(s=>O(s))}catch(o){W(o,e,"render")}finally{f.metrics&&f.metrics.onRenderEnd&&f.metrics.onRenderEnd(e),t.rendering=!1}}};var Re=new Map,Pe={},Fe=e=>{Pe=e},ze=async()=>{let e=Object.entries(Pe).map(async([r,t])=>{let o=await Promise.all(t.map(async s=>{try{if(s instanceof CSSStyleSheet)return s;let n=await fetch(s);if(!n.ok)throw new Error(`Status ${n.status}`);let i=await n.text(),a=new CSSStyleSheet;return await a.replace(i),a}catch(n){return console.error(`[Lego] Failed to load stylesheet: ${s}`,n),null}}));Re.set(r,o.filter(s=>s!==null))});await Promise.all(e),f.debug&&console.log("[Lego Debug] Re-applying stylesheets to",L.size,"blocks"),L.forEach(r=>{pe(r)})},pe=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let r=e.shadowRoot||e._legoShadow,t=e.tagName.toLowerCase(),o=w[t],s=(o&&o.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),n=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),i=[],a=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;a;){let g=(a.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);g.length&&i.push(...g);let d=a.tagName?a.tagName.toLowerCase():"";if(w[d]){let p=(w[d].getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);p.length&&i.push(...p)}a=a.parentElement||a.getRootNode&&a.getRootNode().host}let c=[...new Set([...s,...n])],l=[...new Set(i)],m=[...new Set([...l,...c])];if(m.length>0){let g=m.flatMap(d=>Re.get(d)||[]);g.length>0&&f.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",m,"- Sheets:",g.length),g.length>0&&(r.adoptedStyleSheets=[...g])}e._studsMeta={stylesheets:{explicit:c,inherited:l,applied:m}}};var S=e=>{if(f.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let r=_(e),t=e.tagName.toLowerCase(),o=w[t];if(o&&!r.snapped){r.snapped=!0;let n=o.content.cloneNode(!0),i=e.shadowRoot;i?i.innerHTML="":i=e.attachShadow({mode:"open"}),pe(e);let a=F(e,"*")||F(e.getRootNode().host,"*"),c=a&&a.state?a.state:{},l=R.get(t)||{},m=le(o.getAttribute("b-logic")||"{}"),g=le(e.getAttribute("b-logic")||"{}",c),d={$vars:{},$element:e,get $parent(){return F(e,"*")},$emit:(h,E)=>{e.dispatchEvent(new CustomEvent(h,{detail:E,bubbles:!0,composed:!0}))},get $route(){return x.$route},get $go(){return x.$go}};P(l,d),P(m,d),P(g,d),e._studs=z(d,e),Object.defineProperty(e,"state",{get(){return this._studs},set(h){Object.assign(this._studs,h)},configurable:!0,enumerable:!1}),i.appendChild(n);let p=i.querySelector("style");p&&(p.textContent=p.textContent.replace(/\bself\b/g,":host")),H(i,e),L.add(e),O(e),e.setAttribute("b-id",t);let b=i.querySelectorAll("*");if(f.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",b.length),b.forEach(h=>{let E=h.tagName.toLowerCase(),u=!!w[E];u&&f.debug&&console.log("[Lego Debug] Checking",E,"- Registered:",u),u&&S(h)}),e._legoShadow||(e._legoShadow=i),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(h){W(h,e,"mounted")}}let s=e.parentElement;for(;s&&!s._studs;)s=s.parentElement;s&&s._studs&&H(e,s),[...e.children].forEach(S)},I=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(t){W(t,e,"unmounted")}e.shadowRoot&&[...e.shadowRoot.children].forEach(I),L.delete(e),K.delete(e),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(t=>{e._studs.$vars[t]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let r=B.get(e);if(r&&(r.bindings&&(r.bindings.forEach(t=>{let o=J[t.type];if(o&&o.destroy)try{o.destroy({binding:t})}catch(s){console.error(`[Lego] Error in directive cleanup (${t.type}):`,s)}t.node=null,t.anchor=null}),r.bindings=null),r.anchor=null,B.delete(e)),M.has(e)){let t=M.get(e);t.forEach((o,s)=>{o&&o._studs&&(o._studs=null)}),t.clear(),M.delete(e)}[...e.children].forEach(I)};function We(e,r="block.lego"){let t={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",blockName:be(r)},o=e,s=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;o;){let n=o.match(s);if(!n)break;let i=n[1].toLowerCase(),a=n[2],c=n[0],l=n.index,m=`</${i}>`,g=l+c.length,d=o.indexOf(m,g);if(d===-1){console.warn(`[Lego] Unclosed <${i}> tag in ${r}`);break}let p=o.slice(g,d);if(i==="template"){t.template=p.trim();let b=a.match(/b-stylesheets=["']([^"']+)["']/);b&&(t.stylesAttr=b[1]);let h=a.match(/b-cascade=["']([^"']+)["']/);h&&(t.cascadeAttr=h[1]);let E=a.match(/b-error=["']([^"']+)["']/);E&&(t.errorAttr=E[1])}else if(i==="script"){t.script=p.trim();let b=a.match(/lang=["']([^"']+)["']/);b&&(t.scriptLang=b[1])}else i==="style"&&(t.style=p.trim());o=o.slice(d+m.length)}return t}var He=(e,r,t="block.lego")=>{let o=We(r,t),{blockName:s,template:n,script:i,style:a,stylesAttr:c,cascadeAttr:l,errorAttr:m}=o,g={};if(i)try{let p=i.trim(),b=p.match(/export\s+default\s+({[\s\S]*})/),h=b?b[1]:p;g=new Function("Lego","$db",`return ${h}`)(e,e.globals.$db)}catch(p){f.onError(p,"script",s)}let d=n;a&&(d=`<style>${a}</style>`+d),w[s]=document.createElement("template"),w[s].innerHTML=d,c&&w[s].setAttribute("b-stylesheets",c),l&&w[s].setAttribute("b-cascade",l),m&&w[s].setAttribute("b-error",m),R.set(s,g),document.querySelectorAll(s).forEach(p=>!_(p).snapped&&S(p))};oe.setHandler(O);Be(S,O);Ee(S);var Xe={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},T=z({$route:Xe,$go:(e,...r)=>re(e,...r)(document.body),$db:ue},typeof document<"u"?document.body:null);he(T);var D={db:ue,snap:S,unsnap:I,defineLegoFile:(e,r)=>He(D,e,r),block:(e,r,t={},o="",s="",n="")=>{let i=document.createElement("template");i.setAttribute("b-id",e),i.setAttribute("b-stylesheets",o),s&&i.setAttribute("b-cascade",s),n&&i.setAttribute("b-error",n),i.innerHTML=r,w[e]=i,R.set(e,t);try{let a={};P(t,a),Z.set(e.toLowerCase(),z(a,document.body))}catch(a){f.onError(a,"define",e)}document.querySelectorAll(e).forEach(S),[...L].forEach(a=>{a.tagName.toLowerCase()===e.toLowerCase()&&(f.debug&&console.log("[Lego HMR] Reloading",e),I(a),S(a))}),L.forEach(a=>{a._legoShadow&&a._legoShadow.querySelectorAll(e).forEach(c=>{_(c).snapped||(f.debug&&console.log("[Lego Debug] Lazy-initializing",e,"in",a.tagName),S(c))})})},getActiveBlocksCount:()=>L.size,getLegos:()=>Object.keys(w),config:f,globals:T,route:(e,r,t=null)=>{let o=[],s=e==="*"?".*":e;s=s.replace(/:([^\/]+)/g,(n,i)=>(o.push(i),"([^/]+)")),G.push({path:e,regex:new RegExp(`^${s}$`),tagName:r,paramNames:o,middleware:t})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,r={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),Fe(r.styles||{}),f.loader=r.loader,f.debug=r.debug===!0,await ze(),G.length>0){let n=window.location.pathname,i=window.location.search,a=ce(n);if(a){let{match:c,params:l}=a,m=Object.fromEntries(new URLSearchParams(i));T.$route.url=n+i,T.$route.route=c.path,T.$route.params=l,T.$route.query=m,T.$route.method="GET",T.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(n=>{w[n.getAttribute("b-id")]=n});let t=n=>{if(n.nodeType!==Node.ELEMENT_NODE)return;S(n);let i=n.tagName.toLowerCase();if(i.includes("-")&&!w[i]&&f.loader&&!L.has(n)){let a=f.loader(i);if(a){let c=typeof a=="string"?fetch(a).then(l=>l.text()):a;Promise.resolve(c).then(l=>D.defineLegoFile(l,`${i}.lego`)).catch(l=>console.error(`[Lego] Failed to load ${i}:`,l))}}};new MutationObserver(n=>n.forEach(i=>{i.addedNodes.forEach(t),i.removedNodes.forEach(a=>a.nodeType===Node.ELEMENT_NODE&&I(a))})).observe(e,{childList:!0,subtree:!0});let s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(t(e);s.nextNode();)t(s.currentNode);if(e._studs=T,H(e,e),O(e),r.studio){if(!w["lego-studio"]){let n=document.createElement("script");n.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",n.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(n)}D.route("/_/studio","lego-studio"),D.route("/_/studio/:block","lego-studio")}G.length>0&&(window.addEventListener("popstate",n=>{let i=n.state?.legoTargets||null;te(i)}),document.addEventListener("submit",n=>{n.preventDefault()}),document.addEventListener("click",n=>{let a=n.composedPath().find(c=>c.tagName==="A"&&(c.hasAttribute("b-target")||c.hasAttribute("b-link")));if(a){n.preventDefault();let c=a.getAttribute("href"),l=a.getAttribute("b-target"),m=l?l.split(/\s+/).filter(Boolean):[],g=a.getAttribute("b-link")!=="false";T.$go(c,...m).get(g)}}),te()),De()}};typeof window<"u"?window.Lego=D:typeof global<"u"&&(global.Lego=D);var go=D;})();
7
+ `),we.set(e,t));let a={$ancestors:n=>F(r.self,n),$registry:n=>Q.get(n.toLowerCase()),$element:r.self,$route:N.$route,$go:(n,...c)=>te(n,...c)(r.self),$db:N.$db,$emit:(n,c)=>{r.self.dispatchEvent(new CustomEvent(n,{detail:c,bubbles:!0,composed:!0}))}},i=t.call(s,r.global,r.self,r.event,a);return typeof i=="function"?i.call(s,r.event):i}catch(s){if(o)throw s;m.onError(s,"render-error",r.self);return}},le=(e,r={})=>{if(!e||e.trim()==="{}")return{};let o=s=>new Function("scope","global",`with(global) { with(scope) { return (${s}); } }`)(r,N);try{return o(e)}catch(s){let t=e.trim();if(!t.startsWith("{")&&t.includes(":"))try{return o(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,s),{}}};var xe={name:"b-if",scan:(e,{checkGlobal:r,getPrivateData:o})=>O("b-if",e,(s,t)=>{r(s.value);let a=document.createComment(`b-if: ${s.value}`),i=o(t);return i.anchor=a,{anchor:a}}),execute({binding:e,state:r,global:o}){let{node:s,anchor:t,expr:a}=e,i=!!x(a,{state:r,global:o,self:s}),n=!!s.parentNode;i&&!n?t.parentNode&&t.parentNode.replaceChild(s,t):!i&&n&&s.parentNode.replaceChild(t,s)}};var ve={name:"b-show",scan(e,{checkGlobal:r}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let o=e.getAttribute("b-show");return r(o),{type:"b-show",node:e,expr:o}}},execute({binding:e,state:r,global:o}){let{node:s,expr:t}=e;s.style.display=x(t,{state:r,global:o,self:s})?"":"none"}};var Ne={name:"b-text",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text"))return{type:"b-text",node:e,path:e.getAttribute("b-text")}},execute({binding:e,state:r}){let{node:o,path:s}=e;o.textContent=B(s,r)}};var Se={name:"b-html",scan:e=>O("b-html",e),execute:({binding:e,state:r,global:o})=>{let{node:s,expr:t}=e;s.innerHTML=x(t,{state:r,global:o,self:s})||""}};var $e={name:"b-sync",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-sync"))return{type:"b-sync",node:e}},execute({binding:e,state:r}){let{node:o}=e;Y(o,B(o.getAttribute("b-sync"),r))}};var Le={name:"b-for",scan(e,{checkGlobal:r,pendingOperations:o}){if(e.nodeType!==Node.ELEMENT_NODE)return;let s=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(s){r(s[2]);let t=document.createComment(`b-for: ${s[1]} in ${s[2].trim()}`);return o.push(()=>{e.parentNode&&(e.parentNode.insertBefore(t,e),e.remove())}),{type:"b-for",anchor:t,itemName:s[1],listName:s[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0)}}},execute({binding:e,state:r,global:o,helpers:s}){let{bind:t,updateNodeBindings:a}=s;if(!t||!a){console.error("[Lego] b-for directive missing required helpers: bind, updateNodeBindings");return}let{anchor:i,listName:n,itemName:c,keyPath:l,template:d}=e,{contextEl:u}=s,f=x(n,{state:r,global:o,self:u})||[];C.has(i)||C.set(i,new Map);let g=C.get(i),b=new Set,h=[];f.forEach((p,$)=>{let E;l?(E=B(l,p),E===void 0&&console.warn(`[Lego] b-key="${l}" resolved to undefined for item at index ${$}. Check for typos.`)):p&&typeof p=="object"?(E=p.id||p._id||p.uuid||p.key,E===void 0&&(X.has(p)||X.set(p,Math.random()),E=X.get(p))):E=`${$}-${p}`,b.add(E);let T=g.get(E);T||(T=d.cloneNode(!0),T.removeAttribute("b-for"),T.removeAttribute("b-key"),g.set(E,T),t(T,u,{name:c,listName:n,index:$}));let Ie=Object.assign(Object.create(r),{[c]:p,$index:$});a(T,Ie),T.querySelectorAll("[b-sync]").forEach(me=>{let ge=me.getAttribute("b-sync");if(ge.startsWith(`${c}.`)){let qe=x(n,{state:r,global:o,self:u});Y(me,B(ge.split(".").slice(1).join("."),qe[$]))}}),h.push(T)});let w=i.nextSibling;h.forEach(p=>{p!==w?i.parentNode.insertBefore(p,w):w=w.nextSibling});for(let[p,$]of g.entries())b.has(p)||($.remove(),g.delete(p))}};var _e={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:r})=>{e.initialized||(e.initialized=!0,x(e.expr,{state:r}))}};var Te={name:"b-enter",scan:e=>O("b-enter",e,(r,o)=>({modifiers:r.name.split(".").slice(1)})),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((s,t)=>{s[0].isIntersecting&&(x(e.expr,{state:r}),e.modifiers.includes("once")&&(t.disconnect(),e.observer=null,e.done=!0))});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Ae={scan:e=>O("b-leave",e),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((s,t)=>{let a=s[0];a.isIntersecting&&(e.activated=!0),!a.isIntersecting&&e.activated&&(x(e.expr,{state:r}),e.modifiers.includes("once")&&(t.disconnect(),e.observer=null,e.done=!0))});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var G={"b-if":xe,"b-show":ve,"b-text":Ne,"b-html":Se,"b-sync":$e,"b-for":Le,"b-init":_e,"b-enter":Te,"b-leave":Ae};var Ue=(e=null)=>{let r=!1,o=new Set,s=!1,t=e,a=new Set,i=null,n=new Set,c=f=>{t=f},l=()=>{i&&clearTimeout(i),i=setTimeout(()=>{n.forEach(f=>{let g=f._studs;if(g&&typeof g.updated=="function")try{g.updated.call(g)}catch(b){console.error("[Lego] Error in updated hook:",b)}}),n.clear(),i=null},50)},d=()=>{a.size>0&&(a.forEach(f=>o.add(f)),a.clear(),!r&&o.size>0&&(r=!0,requestAnimationFrame(u)))},u=()=>{s=!0;let f=Array.from(o);o.clear(),r=!1,f.forEach(g=>{g.isConnected&&t&&t(g)}),f.forEach(g=>n.add(g)),l(),s=!1,d()};return{add:f=>{if(f){if(s){a.add(f);return}o.add(f),!r&&(r=!0,requestAnimationFrame(u))}},setHandler:c}},re=Ue();var L=new Map,oe=new Map,J=new WeakMap,V=new Map,je=e=>{let r=Array.from(V.entries()).filter(([t])=>t.startsWith("lego:")).sort((t,a)=>t[1].timestamp-a[1].timestamp),o=0,s=[];for(let[t,a]of r){if(o>=e)break;try{localStorage.removeItem(t),o+=a.size,s.push(t),V.delete(t)}catch(i){console.error(`[Lego] Failed to evict ${t}:`,i)}}return s},ke=(e,r,o)=>{m.debug&&console.log("[Lego Trace] scheduleSave",e,r,o),oe.has(e)&&clearTimeout(oe.get(e));let s=()=>{try{let t=JSON.stringify(r),a=new Blob([t]).size;localStorage.setItem(e,t);let i=e.startsWith("lego:")?e:`lego:${e}`;V.set(i,{timestamp:Date.now(),size:a}),oe.delete(e)}catch(t){if(t.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let a=JSON.stringify(r),i=new Blob([a]).size,n=je(i*2);if(n.length>0){m.debug&&console.log(`[Lego] Evicted ${n.length} old keys, retrying save`),localStorage.setItem(e,a);let c=e.startsWith("lego:")?e:`lego:${e}`;V.set(c,{timestamp:Date.now(),size:i})}else m.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{m.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,t)}};o>0?oe.set(e,setTimeout(s,o)):s()},fe=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(o){return this._default=o,this},debounce(o){return this._debounce=o,this},set(o,s=0){return ke(e,o,s),L.has(e)&&L.get(e).forEach(({target:t,prop:a,el:i,batcher:n})=>{t[a]=o,i&&n&&n.add(i)}),o},get(){try{let o=localStorage.getItem(e);return o!==null?JSON.parse(o):null}catch(o){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,o),null}},delete(){try{return localStorage.removeItem(e),V.delete(e.startsWith("lego:")?e:`lego:${e}`),L.has(e)&&L.get(e).forEach(({target:o,prop:s,el:t,batcher:a})=>{o[s]=null,t&&a&&a.add(t)}),!0}catch(o){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,o),!1}}}),Ce=e=>e&&e.__type==="lego-db",Me=(e,r,o,s,t)=>{m.debug&&console.log("[Lego Trace] Reactive DB Init:",r,o);let a=o._default;try{let i=localStorage.getItem(o.key);i!==null&&(a=JSON.parse(i))}catch(i){console.warn(`[Lego] Failed to parse localStorage value for key "${o.key}":`,i)}e[r]=a,J.has(e)||J.set(e,{}),J.get(e)[r]={key:o.key,debounce:o._debounce},m.debug&&console.log("[Lego Trace] DB Metadata Set:",r,J.get(e)[r]),L.has(o.key)||L.set(o.key,new Set),L.get(o.key).add({target:e,prop:r,el:s,batcher:t})},Oe=(e,r,o)=>{let s=J.get(e);if(s&&s[r]){let t=s[r].key;ke(t,o,s[r].debounce),L.has(t)&&L.get(t).forEach(({target:a,prop:i,el:n,batcher:c})=>{a!==e&&(a[i]=o,n&&c&&c.add(n))})}},Be=()=>{typeof window<"u"&&window.addEventListener("storage",e=>{if(!(!e.key||!L.has(e.key)))try{let r=JSON.parse(e.newValue);L.get(e.key).forEach(({target:o,prop:s,el:t,batcher:a})=>{o[s]=r,t&&a&&a.add(t)})}catch(r){console.warn("[Lego] Cross-tab sync error:",r)}})};var z=(e,r,o=re)=>{if(e===null||typeof e!="object"||ae(e))return e;if(I.has(e))return I.get(e);for(let a in e){let i=Object.getOwnPropertyDescriptor(e,a);if(i&&i.get)continue;let n=e[a];Ce(n)&&Me(e,a,n,r,o)}let s={get:(a,i)=>{let n=Reflect.get(a,i);return n!==null&&typeof n=="object"&&!ae(n)?z(n,r,o):n},set:(a,i,n,c)=>{let l=a[i];m.debug&&l!==n&&console.log("[Lego Trace] Reactive SET:",i,"Old:",l,"New:",n,"Target:",a);let d=Reflect.set(a,i,n,c);return c===I.get(a)&&l!==n&&(o.add(r),Oe(a,i,n)),d},deleteProperty:(a,i)=>{let n=Reflect.deleteProperty(a,i);return o.add(r),n}},t=new Proxy(e,s);return I.set(e,t),t};var Ke=e=>{let r=e;for(;r;){let o=r.getAttribute&&r.getAttribute("b-error");if(o)return{errorTag:o,targetElement:r};let s=r.tagName?r.tagName.toLowerCase():"",t=y[s];if(t){let a=t.getAttribute("b-error");if(a)return{errorTag:a,targetElement:r}}r=r.parentElement||r.getRootNode&&r.getRootNode().host}return null},de=null,ue=null,De=(e,r)=>{de=e,ue=r},Ge=(e,r,o)=>{if(!de||!ue){console.error("[Lego] Error boundary dependencies not loaded",o);return}try{r.shadowRoot?r.shadowRoot.innerHTML="":r.innerHTML="";let s=document.createElement(e);(r.shadowRoot||r).appendChild(s),de(s),s._studs&&(s._studs.$error={message:o.message,stack:o.stack,component:r.tagName.toLowerCase()},ue(s))}catch(s){console.error("[Lego] Error boundary failed to render:",s),console.error("[Lego] Original error:",o)}},W=(e,r,o)=>{let s=Ke(r);s?Ge(s.errorTag,s.targetElement,e):m.onError(e,o,r)};var se=(e,r,o=null)=>{let s=r._studs,t=n=>{let c=M(n);if(!c.bound){if(n.hasAttributes()){let l=n.attributes;for(let d=0;d<l.length;d++){let u=l[d];if(u.name.startsWith("@")){let f=u.name.slice(1).split("."),g=f[0],b=f.slice(1);n.addEventListener(g,h=>{if(b.includes("prevent")&&h.preventDefault(),b.includes("stop")&&h.stopPropagation(),!(b.includes("self")&&h.target!==h.currentTarget)){if(typeof KeyboardEvent<"u"&&h instanceof KeyboardEvent){if(b.includes("ctrl")&&!h.ctrlKey||b.includes("alt")&&!h.altKey||b.includes("shift")&&!h.shiftKey||b.includes("meta")&&!h.metaKey)return;let w=b.filter(p=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(p));if(w.length>0){let p=h.key.toLowerCase();if(!w.some(E=>E==="enter"?p==="enter":E==="esc"||E==="escape"?p==="escape":E==="space"?p===" ":E==="tab"?p==="tab":E==="delete"?p==="delete":E==="backspace"?p==="backspace":E==="up"?p==="arrowup":E==="down"?p==="arrowdown":E==="left"?p==="arrowleft":E==="right"?p==="arrowright":E==="alpha"?/^[a-z]$/.test(p):E==="numbers"?/^[0-9]$/.test(p):E===p))return}}try{let w=s;if(o){let $=x(o.listName,{state:s,global:N,self:r})[o.index];w=Object.assign(Object.create(s),{[o.name]:$})}x(u.value,{state:w,global:N,self:n,event:h,$event:h},!0)}catch(w){W(w,r,"event-handler")}}})}}if(n.hasAttribute("b-sync")){let d=n.getAttribute("b-sync"),u=()=>{try{let f,g;if(o&&d.startsWith(`${o.name}.`)){let w=x(o.listName,{state:s,global:N,self:r})[o.index];if(!w)return;let p=d.split(".").slice(1);g=p.pop(),f=p.reduce(($,E)=>$[E],w)}else{let h=d.split(".");g=h.pop(),f=h.reduce((w,p)=>w[p],s)}let b=n.type==="checkbox"?n.checked:n.value;f&&f[g]!==b&&(f[g]=b)}catch(f){m.onError(f,"sync-update",n)}};n.addEventListener("input",u),n.addEventListener("change",u)}if(n.hasAttribute("b-var")){let d=n.getAttribute("b-var");s.$vars&&(s.$vars[d]=n)}}c.bound=!0}};e instanceof Element&&t(e);let a=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),i;for(;i=a.nextNode();)t(i)},Je=e=>{let r=[],o=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),s,t=[];for(;s=o.nextNode();){let a=s;if((c=>{let l=c.parentNode;for(;l&&l!==e;){if(l.hasAttribute&&l.hasAttribute("b-for"))return!0;l=l.parentNode}return!1})(s))continue;let n=c=>{if(/\bglobal\b/.test(c)){let l=e.host||e;q.add(l)}};if(s.nodeType===Node.ELEMENT_NODE){for(let[l,d]of Object.entries(G))if(d.scan){let u=d.scan(s,{checkGlobal:n,getPrivateData:M,pendingOperations:t,current:a});u&&r.push(u)}let[c]=U();[...s.attributes].forEach(l=>{l.value.includes(c)&&(n(l.value),r.push({type:"attr",node:s,attrName:l.name,template:l.value}))})}else if(s.nodeType===Node.TEXT_NODE){let[c]=U();s.textContent.includes(c)&&(n(s.textContent),r.push({type:"text",node:s,template:s.textContent}))}}return t.forEach(a=>a()),r},Ve=(e,r)=>{let o=a=>{if(a.nodeType===Node.TEXT_NODE){a._tpl===void 0&&(a._tpl=a.textContent);let i=a._tpl.replace(j(),(n,c)=>x(c.trim(),{state:r,global:N,self:a})??"");a.textContent!==i&&(a.textContent=i)}else if(a.nodeType===Node.ELEMENT_NODE){let[i]=U();[...a.attributes].forEach(n=>{if(n._tpl===void 0&&(n._tpl=n.value),n._tpl.includes(i)){let c=n._tpl.replace(j(),(l,d)=>x(d.trim(),{state:r,global:N,self:a})??"");n.value!==c&&(n.value=c,n.name==="class"&&(a.className=c))}})}};o(e);let s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),t;for(;t=s.nextNode();)o(t)},H=e=>{m.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let r=e._studs;if(!r)return;let o=M(e);if(!o.rendering){o.rendering=!0,m.metrics&&m.metrics.onRenderStart&&m.metrics.onRenderStart(e);try{let s=e.shadowRoot||e;o.bindings||(o.bindings=Je(s)),o.bindings.forEach(t=>{let a=G[t.type];if(a){a.execute({binding:t,state:r,global:N,helpers:{bind:se,updateNodeBindings:Ve,contextEl:e}});return}if(t.type==="text"){let i=t.template.replace(j(),(n,c)=>x(c.trim(),{state:r,global:N,self:t.node})??"");t.node.textContent!==i&&(t.node.textContent=i)}if(t.type==="attr"){let i=t.template.replace(j(),(n,c)=>x(c.trim(),{state:r,global:N,self:t.node})??"");t.node.getAttribute(t.attrName)!==i&&(t.node.setAttribute(t.attrName,i),t.attrName==="class"&&(t.node.className=i))}}),r===N&&q.forEach(t=>H(t))}catch(s){W(s,e,"render")}finally{m.metrics&&m.metrics.onRenderEnd&&m.metrics.onRenderEnd(e),o.rendering=!1}}};var Re=new Map,Pe={},Fe=e=>{Pe=e},ze=async()=>{let e=Object.entries(Pe).map(async([r,o])=>{let s=await Promise.all(o.map(async t=>{try{if(t instanceof CSSStyleSheet)return t;let a=await fetch(t);if(!a.ok)throw new Error(`Status ${a.status}`);let i=await a.text(),n=new CSSStyleSheet;return await n.replace(i),n}catch(a){return console.error(`[Lego] Failed to load stylesheet: ${t}`,a),null}}));Re.set(r,s.filter(t=>t!==null))});await Promise.all(e),m.debug&&console.log("[Lego Debug] Re-applying stylesheets to",_.size,"blocks"),_.forEach(r=>{pe(r)})},pe=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let r=e.shadowRoot||e._legoShadow,o=e.tagName.toLowerCase(),s=y[o],t=(s&&s.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),a=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),i=[],n=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;n;){let u=(n.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);u.length&&i.push(...u);let f=n.tagName?n.tagName.toLowerCase():"";if(y[f]){let g=(y[f].getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);g.length&&i.push(...g)}n=n.parentElement||n.getRootNode&&n.getRootNode().host}let c=[...new Set([...t,...a])],l=[...new Set(i)],d=[...new Set([...l,...c])];if(d.length>0){let u=d.flatMap(f=>Re.get(f)||[]);u.length>0&&m.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",d,"- Sheets:",u.length),u.length>0&&(r.adoptedStyleSheets=[...u])}e._studsMeta={stylesheets:{explicit:c,inherited:l,applied:d}}};var S=e=>{if(m.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let r=M(e),o=e.tagName.toLowerCase(),s=y[o];if(s&&!r.snapped){r.snapped=!0;let a=s.content.cloneNode(!0),i=e.shadowRoot;i?i.innerHTML="":i=e.attachShadow({mode:"open"}),pe(e);let n=F(e,"*")||F(e.getRootNode().host,"*"),c=n&&n.state?n.state:{},l=R.get(o)||{},d=le(s.getAttribute("b-logic")||"{}"),u=le(e.getAttribute("b-logic")||"{}",c),f={$vars:{},$element:e,get $parent(){return F(e,"*")},$emit:(h,w)=>{e.dispatchEvent(new CustomEvent(h,{detail:w,bubbles:!0,composed:!0}))},get $route(){return N.$route},get $go(){return N.$go}};P(l,f),P(d,f),P(u,f),e._studs=z(f,e),Object.defineProperty(e,"state",{get(){return this._studs},set(h){Object.assign(this._studs,h)},configurable:!0,enumerable:!1}),i.appendChild(a);let g=i.querySelector("style");g&&(g.textContent=g.textContent.replace(/\bself\b/g,":host")),se(i,e),_.add(e),H(e),e.setAttribute("b-id",o);let b=i.querySelectorAll("*");if(m.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",b.length),b.forEach(h=>{let w=h.tagName.toLowerCase(),p=!!y[w];p&&m.debug&&console.log("[Lego Debug] Checking",w,"- Registered:",p),p&&S(h)}),e._legoShadow||(e._legoShadow=i),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(h){W(h,e,"mounted")}}let t=e.parentElement;for(;t&&!t._studs;)t=t.parentElement;t&&t._studs&&se(e,t),[...e.children].forEach(S)},A=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(o){W(o,e,"unmounted")}e.shadowRoot&&[...e.shadowRoot.children].forEach(A),_.delete(e),q.delete(e),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(o=>{e._studs.$vars[o]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let r=D.get(e);if(r&&(r.bindings&&(r.bindings.forEach(o=>{let s=G[o.type];if(s&&s.destroy)try{s.destroy({binding:o})}catch(t){console.error(`[Lego] Error in directive cleanup (${o.type}):`,t)}o.node=null,o.anchor=null}),r.bindings=null),r.anchor=null,D.delete(e)),C.has(e)){let o=C.get(e);o.forEach((s,t)=>{s&&s._studs&&(s._studs=null)}),o.clear(),C.delete(e)}[...e.children].forEach(A)};function We(e,r="block.lego"){let o={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",blockName:be(r)},s=e,t=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;s;){let a=s.match(t);if(!a)break;let i=a[1].toLowerCase(),n=a[2],c=a[0],l=a.index,d=`</${i}>`,u=l+c.length,f=s.indexOf(d,u);if(f===-1){console.warn(`[Lego] Unclosed <${i}> tag in ${r}`);break}let g=s.slice(u,f);if(i==="template"){o.template=g.trim();let b=n.match(/b-stylesheets=["']([^"']+)["']/);b&&(o.stylesAttr=b[1]);let h=n.match(/b-cascade=["']([^"']+)["']/);h&&(o.cascadeAttr=h[1]);let w=n.match(/b-error=["']([^"']+)["']/);w&&(o.errorAttr=w[1])}else if(i==="script"){o.script=g.trim();let b=n.match(/lang=["']([^"']+)["']/);b&&(o.scriptLang=b[1])}else i==="style"&&(o.style=g.trim());s=s.slice(f+d.length)}return o}var He=(e,r,o="block.lego")=>{let s=We(r,o),{blockName:t,template:a,script:i,style:n,stylesAttr:c,cascadeAttr:l,errorAttr:d}=s,u={};if(i)try{let g=i.trim(),b=g.match(/export\s+default\s+({[\s\S]*})/),h=b?b[1]:g;u=new Function("Lego","$db",`return ${h}`)(e,e.globals.$db)}catch(g){m.onError(g,"script",t)}let f=a;n&&(f=`<style>${n}</style>`+f),y[t]=document.createElement("template"),y[t].innerHTML=f,c&&y[t].setAttribute("b-stylesheets",c),l&&y[t].setAttribute("b-cascade",l),d&&y[t].setAttribute("b-error",d),R.set(t,u),document.querySelectorAll(t).forEach(g=>!M(g).snapped&&S(g))};re.setHandler(H);De(S,H);Ee(S);var Xe={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},k=z({$route:Xe,$go:(e,...r)=>te(e,...r)(document.body),$db:fe},typeof document<"u"?document.body:null);he(k);var v={db:fe,snap:S,unsnap:A,defineLegoFile:(e,r)=>He(v,e,r),block:(e,r,o={},s="",t="",a="")=>{let i=document.createElement("template");i.setAttribute("b-id",e),i.setAttribute("b-stylesheets",s),t&&i.setAttribute("b-cascade",t),a&&i.setAttribute("b-error",a),i.innerHTML=r,y[e]=i,R.set(e,o);try{let n={};P(o,n),Q.set(e.toLowerCase(),z(n,document.body))}catch(n){m.onError(n,"define",e)}if(customElements.get(e))document.querySelectorAll(e).forEach(n=>{A(n),S(n)}),_.forEach(n=>{n._legoShadow&&n._legoShadow.querySelectorAll(e).forEach(c=>{A(c),S(c)})});else try{customElements.define(e,class extends HTMLElement{connectedCallback(){y[e]&&S(this)}disconnectedCallback(){A(this)}})}catch(n){console.warn(`[Lego] Failed to register web component ${e}:`,n)}},getActiveBlocksCount:()=>_.size,getLegos:()=>Object.keys(y),config:m,globals:k,route:(e,r,o=null)=>{let s=[],t=e==="*"?".*":e;t=t.replace(/:([^\/]+)/g,(a,i)=>(s.push(i),"([^/]+)")),K.push({path:e,regex:new RegExp(`^${t}$`),tagName:r,paramNames:s,middleware:o})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,r={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),Fe(r.styles||{}),m.loader=r.loader,m.debug=r.debug===!0,await ze(),K.length>0){let t=window.location.pathname,a=window.location.search,i=ce(t);if(i){let{match:n,params:c}=i,l=Object.fromEntries(new URLSearchParams(a));k.$route.url=t+a,k.$route.route=n.path,k.$route.params=c,k.$route.query=l,k.$route.method="GET",k.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(t=>{let a=t.getAttribute("b-id");y[a]=t,customElements.get(a)||customElements.define(a,class extends HTMLElement{connectedCallback(){y[a]&&S(this)}disconnectedCallback(){A(this)}})});let o=t=>{if(!t)return{};let a={};return Object.entries(t).forEach(([i,n])=>{if(typeof n=="function")a[i]=n();else if(typeof n=="string"&&n.startsWith("$db.")){let c=n.slice(4);a[i]=v.db(c).get()}else if(typeof n=="string"&&n.startsWith("$globals.")){let c=n.slice(9);a[i]=N[c]}else a[i]=n}),a},s=(t,a,i={})=>{customElements.get(t)||customElements.define(t,class extends HTMLElement{async connectedCallback(){if(y[t]){S(this);return}if(v._fetching||(v._fetching=new Set),!v._fetching.has(t)){v._fetching.add(t);try{let n=a.startsWith("POST:")?"POST":"GET",c=a.replace(/^POST:/,""),l=o(i.headers),d={method:n,headers:l,credentials:i.credentials},f=await(await fetch(c,d)).text();v.defineLegoFile(f,`${t}.lego`),y[t]&&S(this)}catch(n){console.error(`[Lego] Failed to load manifest block ${t}:`,n)}finally{v._fetching.delete(t)}}}disconnectedCallback(){A(this)}})};if(r.manifest){let t=r.manifest;if(t.url&&typeof t.url=="string")try{let i=o(t.headers);t=await(await fetch(t.url,{headers:i,credentials:t.credentials})).json()}catch(i){console.error("[Lego] Failed to load manifest:",i),t=[]}else if(typeof t=="string")try{t=await(await fetch(t)).json()}catch(i){console.error("[Lego] Failed to load manifest:",i),t=[]}let a=Array.isArray(t)?t:[t];for(let i of a){let n=i.base||"",c=i.suffix===!0?".lego":i.suffix||"",l={headers:i.headers||{},credentials:i.credentials};i.legos&&i.legos.forEach(d=>{s(d,`${n}${d}${c}`,l)}),i.map&&Object.entries(i.map).forEach(([d,u])=>{let f=u.match(/^https?:|^\//)?u:`${n}${u}`;s(d,f,l)})}}if(m.loader){let t=n=>{if(n.nodeType!==Node.ELEMENT_NODE)return;let c=n.tagName.toLowerCase();if(c.includes("-")&&!y[c]&&!_.has(n)){if(v._fetching&&v._fetching.has(c))return;v._fetching||(v._fetching=new Set),v._fetching.add(c);let l=m.loader(c);if(l){let d=typeof l=="string"?fetch(l).then(u=>u.text()):l;Promise.resolve(d).then(u=>{v.defineLegoFile(u,`${c}.lego`),v._fetching.delete(c)}).catch(u=>{console.error(`[Lego] Failed to load ${c}:`,u),v._fetching.delete(c)})}}if(n.children.length>0){let l=n.firstElementChild;for(;l;)t(l),l=l.nextElementSibling}};new MutationObserver(n=>n.forEach(c=>{c.addedNodes.forEach(t)})).observe(e,{childList:!0,subtree:!0});let i=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;i.nextNode();)t(i.currentNode)}if(r.studio){if(!y["lego-studio"]){let t=document.createElement("script");t.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",t.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(t)}v.route("/_/studio","lego-studio"),v.route("/_/studio/:block","lego-studio")}K.length>0&&(window.addEventListener("popstate",t=>{let a=t.state?.legoTargets||null;ee(a)}),document.addEventListener("submit",t=>{t.preventDefault()}),document.addEventListener("click",t=>{let i=t.composedPath().find(n=>n.tagName==="A"&&(n.hasAttribute("b-target")||n.hasAttribute("b-link")));if(i){t.preventDefault();let n=i.getAttribute("href"),c=i.getAttribute("b-target"),l=c?c.split(/\s+/).filter(Boolean):[],d=i.getAttribute("b-link")!=="false";k.$go(n,...l).get(d)}}),ee()),Be()}};typeof window<"u"?window.Lego=v:typeof global<"u"&&(global.Lego=v);var ho=v;})();
package/dist/lego.mjs CHANGED
@@ -1,7 +1,7 @@
1
- var w={},q=new WeakMap,B=new WeakMap,M=new WeakMap,Q=new WeakMap,L=new Set,K=new Set,R=new Map,Z=new Map;var _=e=>(B.has(e)||B.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),B.get(e));var x={},he=e=>{x=e};var f={onError:(e,r,t)=>{console.error(`[Lego Error] [${r}]`,e,t)},metrics:{},debug:!1,syntax:"brackets"},P=(e,r)=>{!e||!r||Object.getOwnPropertyNames(e).forEach(t=>{let o=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,o)})},U=()=>f.syntax==="brackets"?["[[","]]"]:["{{","}}"],ne=new Map,j=()=>{let[e,r]=U(),t=e+r;if(ne.has(t))return ne.get(t);let o=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),s=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`${o}(.*?)${s}`,"g");return ne.set(t,n),n},be=e=>{let t=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!t.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return t},C=(e,r)=>{if(!e)return"";let t=e.trim().split("."),o=r;for(let s of t){if(o==null)return"";o=o[s]}return o??""},ae=e=>typeof Node<"u"&&e instanceof Node,k=(e,r,t)=>{if(r.nodeType!==Node.ELEMENT_NODE)return;let o=[...r.attributes].find(n=>n.name===e||n.name.startsWith(`${e}.`));if(!o)return;let s={};return t&&(s=t(o,r)),{type:e,node:r,expr:o.value,modifiers:o.name.split(".").slice(1),...s}};var Y=class{constructor(r=1e3){this.limit=r,this.cache=new Map}get(r){if(!this.cache.has(r))return;let t=this.cache.get(r);return this.cache.delete(r),this.cache.set(r,t),t}set(r,t){if(this.cache.has(r))this.cache.delete(r);else if(this.cache.size>=this.limit){let o=this.cache.keys().next().value;this.cache.delete(o)}this.cache.set(r,t)}get size(){return this.cache.size}clear(){this.cache.clear()}};var F=(e,r)=>{if(!e)return;let t=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;t;){let o=t.tagName?t.tagName.toLowerCase():"";if(o&&(r==="*"&&w[o]||o===r.toLowerCase()))return t;t=t.parentElement||t.getRootNode&&t.getRootNode().host}},ye=(e,r)=>{if(typeof e=="function"){let o=Array.from(document.querySelectorAll("*")).filter(s=>s.tagName.includes("-"));return[].concat(e(o))}if(e.startsWith("#")){let o=document.getElementById(e.slice(1));return o?[o]:[]}let t=r?.querySelectorAll(e)||[];return t.length>0?[...t]:[...document.querySelectorAll(e)]},ee=(e,r)=>{if(e.type==="checkbox")e.checked!==!!r&&(e.checked=!!r);else{let t=r==null?"":String(r);e.value!==t&&(e.value=t)}};var ie=null,Ee=e=>{ie=e},G=[],ce=e=>{let r=G.find(s=>s.regex.test(e));if(!r)return null;let t=e.match(r.regex).slice(1),o=r.paramNames?Object.fromEntries(r.paramNames.map((s,n)=>[s,t[n]])):{};return{match:r,params:o}},te=async(e=null,r=null)=>{if(typeof window>"u")return;let t=window.location.pathname,o=ce(t);if(f.debug&&console.log("[Lego Trace] Matching route",t,o?.match),!o)return;let{match:s,params:n}=o;if(s.middleware&&!await s.middleware({path:t,params:n}))return;let i=e&&e.length?e:["lego-router"],a=r||document;s.tagName&&i.flatMap(l=>ye(l,a)).forEach(l=>{l&&(l.innerHTML=`<${s.tagName}></${s.tagName}>`,ie&&ie(l.firstElementChild))})},re=(e,...r)=>t=>{let o=async(s,n=null,i=!0,a={})=>{if(i&&typeof history<"u"){let l={legoTargets:r.filter(m=>typeof m=="string"),method:s,body:n};history.pushState(l,"",e)}await te(r.length?r:null,t)};return{get:(s=!0,n={})=>o("GET",null,s,n),post:(s,n=!0,i={})=>o("POST",s,n,i),put:(s,n=!0,i={})=>o("PUT",s,n,i),patch:(s,n=!0,i={})=>o("PATCH",s,n,i),delete:(s=!0,n={})=>o("DELETE",null,s,n)}};var we=new Y(1e3),N=(e,r,t=!0)=>{if(/\b(function|eval|import|class|module|deploy|constructor|__proto__)\b/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let o=r.state||{},s=we.get(e);s||(s=new Function("global","self","event","helpers",`
1
+ var y={},I=new WeakMap,D=new WeakMap,C=new WeakMap,X=new WeakMap,_=new Set,q=new Set,R=new Map,Q=new Map;var M=e=>(D.has(e)||D.set(e,{snapped:!1,bindings:null,bound:!1,rendering:!1,anchor:null}),D.get(e));var N={},he=e=>{N=e};var m={onError:(e,r,o)=>{console.error(`[Lego Error] [${r}]`,e,o)},metrics:{},debug:!1,syntax:"brackets"},P=(e,r)=>{!e||!r||Object.getOwnPropertyNames(e).forEach(o=>{let s=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(r,o,s)})},U=()=>m.syntax==="brackets"?["[[","]]"]:["{{","}}"],ne=new Map,j=()=>{let[e,r]=U(),o=e+r;if(ne.has(o))return ne.get(o);let s=e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),t=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`${s}(.*?)${t}`,"g");return ne.set(o,a),a},be=e=>{let o=e.split("/").pop().replace(/\.lego$/,"").replace(/_/g,"-").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();if(!o.includes("-"))throw new Error(`[Lego] Invalid block definition: "${e}". Block names must contain a hyphen (e.g. user-card.lego or UserCard.lego).`);return o},B=(e,r)=>{if(!e)return"";let o=e.trim().split("."),s=r;for(let t of o){if(s==null)return"";s=s[t]}return s??""},ae=e=>typeof Node<"u"&&e instanceof Node,O=(e,r,o)=>{if(r.nodeType!==Node.ELEMENT_NODE)return;let s=[...r.attributes].find(a=>a.name===e||a.name.startsWith(`${e}.`));if(!s)return;let t={};return o&&(t=o(s,r)),{type:e,node:r,expr:s.value,modifiers:s.name.split(".").slice(1),...t}};var Z=class{constructor(r=1e3){this.limit=r,this.cache=new Map}get(r){if(!this.cache.has(r))return;let o=this.cache.get(r);return this.cache.delete(r),this.cache.set(r,o),o}set(r,o){if(this.cache.has(r))this.cache.delete(r);else if(this.cache.size>=this.limit){let s=this.cache.keys().next().value;this.cache.delete(s)}this.cache.set(r,o)}get size(){return this.cache.size}clear(){this.cache.clear()}};var F=(e,r)=>{if(!e)return;let o=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;o;){let s=o.tagName?o.tagName.toLowerCase():"";if(s&&(r==="*"&&y[s]||s===r.toLowerCase()))return o;o=o.parentElement||o.getRootNode&&o.getRootNode().host}},ye=(e,r)=>{if(typeof e=="function"){let s=Array.from(document.querySelectorAll("*")).filter(t=>t.tagName.includes("-"));return[].concat(e(s))}if(e.startsWith("#")){let s=document.getElementById(e.slice(1));return s?[s]:[]}let o=r?.querySelectorAll(e)||[];return o.length>0?[...o]:[...document.querySelectorAll(e)]},Y=(e,r)=>{if(e.type==="checkbox")e.checked!==!!r&&(e.checked=!!r);else{let o=r==null?"":String(r);e.value!==o&&(e.value=o)}};var ie=null,Ee=e=>{ie=e},K=[],ce=e=>{let r=K.find(t=>t.regex.test(e));if(!r)return null;let o=e.match(r.regex).slice(1),s=r.paramNames?Object.fromEntries(r.paramNames.map((t,a)=>[t,o[a]])):{};return{match:r,params:s}},ee=async(e=null,r=null)=>{if(typeof window>"u")return;let o=window.location.pathname,s=ce(o);if(m.debug&&console.log("[Lego Trace] Matching route",o,s?.match),!s)return;let{match:t,params:a}=s;if(t.middleware&&!await t.middleware({path:o,params:a}))return;let i=e&&e.length?e:["lego-router"],n=r||document;t.tagName&&i.flatMap(l=>ye(l,n)).forEach(l=>{l&&(l.innerHTML=`<${t.tagName}></${t.tagName}>`,ie&&ie(l.firstElementChild))})},te=(e,...r)=>o=>{let s=async(t,a=null,i=!0,n={})=>{if(i&&typeof history<"u"){let l={legoTargets:r.filter(d=>typeof d=="string"),method:t,body:a};history.pushState(l,"",e)}await ee(r.length?r:null,o)};return{get:(t=!0,a={})=>s("GET",null,t,a),post:(t,a=!0,i={})=>s("POST",t,a,i),put:(t,a=!0,i={})=>s("PUT",t,a,i),patch:(t,a=!0,i={})=>s("PATCH",t,a,i),delete:(t=!0,a={})=>s("DELETE",null,t,a)}};var we=new Z(1e3),x=(e,r,o=!0)=>{if(/\b(function|eval|import|class|module|deploy|constructor|__proto__)\b/.test(e)){console.warn(`[Lego] Security Warning: Blocked dangerous expression "${e}"`);return}try{let s=r.state||{},t=we.get(e);t||(t=new Function("global","self","event","helpers",`
2
2
  with(this) {
3
3
  with(helpers) {
4
4
  return ${e}
5
5
  }
6
6
  }
7
- `),we.set(e,s));let n={$ancestors:a=>F(r.self,a),$registry:a=>Z.get(a.toLowerCase()),$element:r.self,$route:x.$route,$go:(a,...c)=>re(a,...c)(r.self),$db:x.$db,$emit:(a,c)=>{r.self.dispatchEvent(new CustomEvent(a,{detail:c,bubbles:!0,composed:!0}))}},i=s.call(o,r.global,r.self,r.event,n);return typeof i=="function"?i.call(o,r.event):i}catch(o){if(t)throw o;f.onError(o,"render-error",r.self);return}},le=(e,r={})=>{if(!e||e.trim()==="{}")return{};let t=o=>new Function("scope","global",`with(global) { with(scope) { return (${o}); } }`)(r,x);try{return t(e)}catch(o){let s=e.trim();if(!s.startsWith("{")&&s.includes(":"))try{return t(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,o),{}}};var Ne={name:"b-if",scan:(e,{checkGlobal:r,getPrivateData:t})=>k("b-if",e,(o,s)=>{r(o.value);let n=document.createComment(`b-if: ${o.value}`),i=t(s);return i.anchor=n,{anchor:n}}),execute({binding:e,state:r,global:t}){let{node:o,anchor:s,expr:n}=e,i=!!N(n,{state:r,global:t,self:o}),a=!!o.parentNode;i&&!a?s.parentNode&&s.parentNode.replaceChild(o,s):!i&&a&&o.parentNode.replaceChild(s,o)}};var xe={name:"b-show",scan(e,{checkGlobal:r}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let t=e.getAttribute("b-show");return r(t),{type:"b-show",node:e,expr:t}}},execute({binding:e,state:r,global:t}){let{node:o,expr:s}=e;o.style.display=N(s,{state:r,global:t,self:o})?"":"none"}};var ve={name:"b-text",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text"))return{type:"b-text",node:e,path:e.getAttribute("b-text")}},execute({binding:e,state:r}){let{node:t,path:o}=e;t.textContent=C(o,r)}};var Se={name:"b-html",scan:e=>k("b-html",e),execute:({binding:e,state:r,global:t})=>{let{node:o,expr:s}=e;o.innerHTML=N(s,{state:r,global:t,self:o})||""}};var Le={name:"b-sync",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-sync"))return{type:"b-sync",node:e}},execute({binding:e,state:r}){let{node:t}=e;ee(t,C(t.getAttribute("b-sync"),r))}};var $e={name:"b-for",scan(e,{checkGlobal:r,pendingOperations:t}){if(e.nodeType!==Node.ELEMENT_NODE)return;let o=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(o){r(o[2]);let s=document.createComment(`b-for: ${o[1]} in ${o[2].trim()}`);return t.push(()=>{e.parentNode&&(e.parentNode.insertBefore(s,e),e.remove())}),{type:"b-for",anchor:s,itemName:o[1],listName:o[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0)}}},execute({binding:e,state:r,global:t,helpers:o}){let{bind:s,updateNodeBindings:n}=o;if(!s||!n){console.error("[Lego] b-for directive missing required helpers: bind, updateNodeBindings");return}let{anchor:i,listName:a,itemName:c,keyPath:l,template:m}=e,{contextEl:g}=o,d=N(a,{state:r,global:t,self:g})||[];M.has(i)||M.set(i,new Map);let p=M.get(i),b=new Set,h=[];d.forEach((u,v)=>{let y;l?(y=C(l,u),y===void 0&&console.warn(`[Lego] b-key="${l}" resolved to undefined for item at index ${v}. Check for typos.`)):u&&typeof u=="object"?(y=u.id||u._id||u.uuid||u.key,y===void 0&&(Q.has(u)||Q.set(u,Math.random()),y=Q.get(u))):y=`${v}-${u}`,b.add(y);let A=p.get(y);A||(A=m.cloneNode(!0),A.removeAttribute("b-for"),A.removeAttribute("b-key"),p.set(y,A),s(A,g,{name:c,listName:a,index:v}));let Ie=Object.assign(Object.create(r),{[c]:u,$index:v});n(A,Ie),A.querySelectorAll("[b-sync]").forEach(me=>{let ge=me.getAttribute("b-sync");if(ge.startsWith(`${c}.`)){let qe=N(a,{state:r,global:t,self:g});ee(me,C(ge.split(".").slice(1).join("."),qe[v]))}}),h.push(A)});let E=i.nextSibling;h.forEach(u=>{u!==E?i.parentNode.insertBefore(u,E):E=E.nextSibling});for(let[u,v]of p.entries())b.has(u)||(v.remove(),p.delete(u))}};var _e={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:r})=>{e.initialized||(e.initialized=!0,N(e.expr,{state:r}))}};var Te={name:"b-enter",scan:e=>k("b-enter",e,(r,t)=>({modifiers:r.name.split(".").slice(1)})),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let t=new IntersectionObserver((o,s)=>{o[0].isIntersecting&&(N(e.expr,{state:r}),e.modifiers.includes("once")&&(s.disconnect(),e.observer=null,e.done=!0))});t.observe(e.node),e.observer=t},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Ae={scan:e=>k("b-leave",e),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let t=new IntersectionObserver((o,s)=>{let n=o[0];n.isIntersecting&&(e.activated=!0),!n.isIntersecting&&e.activated&&(N(e.expr,{state:r}),e.modifiers.includes("once")&&(s.disconnect(),e.observer=null,e.done=!0))});t.observe(e.node),e.observer=t},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var J={"b-if":Ne,"b-show":xe,"b-text":ve,"b-html":Se,"b-sync":Le,"b-for":$e,"b-init":_e,"b-enter":Te,"b-leave":Ae};var Ke=(e=null)=>{let r=!1,t=new Set,o=!1,s=e,n=new Set,i=null,a=new Set,c=d=>{s=d},l=()=>{i&&clearTimeout(i),i=setTimeout(()=>{a.forEach(d=>{let p=d._studs;if(p&&typeof p.updated=="function")try{p.updated.call(p)}catch(b){console.error("[Lego] Error in updated hook:",b)}}),a.clear(),i=null},50)},m=()=>{n.size>0&&(n.forEach(d=>t.add(d)),n.clear(),!r&&t.size>0&&(r=!0,requestAnimationFrame(g)))},g=()=>{o=!0;let d=Array.from(t);t.clear(),r=!1,d.forEach(p=>{p.isConnected&&s&&s(p)}),d.forEach(p=>a.add(p)),l(),o=!1,m()};return{add:d=>{if(d){if(o){n.add(d);return}t.add(d),!r&&(r=!0,requestAnimationFrame(g))}},setHandler:c}},oe=Ke();var $=new Map,se=new Map,V=new WeakMap,X=new Map,Ue=e=>{let r=Array.from(X.entries()).filter(([s])=>s.startsWith("lego:")).sort((s,n)=>s[1].timestamp-n[1].timestamp),t=0,o=[];for(let[s,n]of r){if(t>=e)break;try{localStorage.removeItem(s),t+=n.size,o.push(s),X.delete(s)}catch(i){console.error(`[Lego] Failed to evict ${s}:`,i)}}return o},Me=(e,r,t)=>{f.debug&&console.log("[Lego Trace] scheduleSave",e,r,t),se.has(e)&&clearTimeout(se.get(e));let o=()=>{try{let s=JSON.stringify(r),n=new Blob([s]).size;localStorage.setItem(e,s);let i=e.startsWith("lego:")?e:`lego:${e}`;X.set(i,{timestamp:Date.now(),size:n}),se.delete(e)}catch(s){if(s.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let n=JSON.stringify(r),i=new Blob([n]).size,a=Ue(i*2);if(a.length>0){f.debug&&console.log(`[Lego] Evicted ${a.length} old keys, retrying save`),localStorage.setItem(e,n);let c=e.startsWith("lego:")?e:`lego:${e}`;X.set(c,{timestamp:Date.now(),size:i})}else f.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{f.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,s)}};t>0?se.set(e,setTimeout(o,t)):o()},ue=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(t){return this._default=t,this},debounce(t){return this._debounce=t,this},set(t,o=0){return Me(e,t,o),$.has(e)&&$.get(e).forEach(({target:s,prop:n,el:i,batcher:a})=>{s[n]=t,i&&a&&a.add(i)}),t},get(){try{let t=localStorage.getItem(e);return t!==null?JSON.parse(t):null}catch(t){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,t),null}},delete(){try{return localStorage.removeItem(e),X.delete(e.startsWith("lego:")?e:`lego:${e}`),$.has(e)&&$.get(e).forEach(({target:t,prop:o,el:s,batcher:n})=>{t[o]=null,s&&n&&n.add(s)}),!0}catch(t){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,t),!1}}}),ke=e=>e&&e.__type==="lego-db",Ce=(e,r,t,o,s)=>{f.debug&&console.log("[Lego Trace] Reactive DB Init:",r,t);let n=t._default;try{let i=localStorage.getItem(t.key);i!==null&&(n=JSON.parse(i))}catch(i){console.warn(`[Lego] Failed to parse localStorage value for key "${t.key}":`,i)}e[r]=n,V.has(e)||V.set(e,{}),V.get(e)[r]={key:t.key,debounce:t._debounce},f.debug&&console.log("[Lego Trace] DB Metadata Set:",r,V.get(e)[r]),$.has(t.key)||$.set(t.key,new Set),$.get(t.key).add({target:e,prop:r,el:o,batcher:s})},Oe=(e,r,t)=>{let o=V.get(e);if(o&&o[r]){let s=o[r].key;Me(s,t,o[r].debounce),$.has(s)&&$.get(s).forEach(({target:n,prop:i,el:a,batcher:c})=>{n!==e&&(n[i]=t,a&&c&&c.add(a))})}},De=()=>{typeof window<"u"&&window.addEventListener("storage",e=>{if(!(!e.key||!$.has(e.key)))try{let r=JSON.parse(e.newValue);$.get(e.key).forEach(({target:t,prop:o,el:s,batcher:n})=>{t[o]=r,s&&n&&n.add(s)})}catch(r){console.warn("[Lego] Cross-tab sync error:",r)}})};var z=(e,r,t=oe)=>{if(e===null||typeof e!="object"||ae(e))return e;if(q.has(e))return q.get(e);for(let n in e){let i=Object.getOwnPropertyDescriptor(e,n);if(i&&i.get)continue;let a=e[n];ke(a)&&Ce(e,n,a,r,t)}let o={get:(n,i)=>{let a=Reflect.get(n,i);return a!==null&&typeof a=="object"&&!ae(a)?z(a,r,t):a},set:(n,i,a,c)=>{let l=n[i];f.debug&&l!==a&&console.log("[Lego Trace] Reactive SET:",i,"Old:",l,"New:",a,"Target:",n);let m=Reflect.set(n,i,a,c);return c===q.get(n)&&l!==a&&(t.add(r),Oe(n,i,a)),m},deleteProperty:(n,i)=>{let a=Reflect.deleteProperty(n,i);return t.add(r),a}},s=new Proxy(e,o);return q.set(e,s),s};var je=e=>{let r=e;for(;r;){let t=r.getAttribute&&r.getAttribute("b-error");if(t)return{errorTag:t,targetElement:r};let o=r.tagName?r.tagName.toLowerCase():"",s=w[o];if(s){let n=s.getAttribute("b-error");if(n)return{errorTag:n,targetElement:r}}r=r.parentElement||r.getRootNode&&r.getRootNode().host}return null},de=null,fe=null,Be=(e,r)=>{de=e,fe=r},Ge=(e,r,t)=>{if(!de||!fe){console.error("[Lego] Error boundary dependencies not loaded",t);return}try{r.shadowRoot?r.shadowRoot.innerHTML="":r.innerHTML="";let o=document.createElement(e);(r.shadowRoot||r).appendChild(o),de(o),o._studs&&(o._studs.$error={message:t.message,stack:t.stack,component:r.tagName.toLowerCase()},fe(o))}catch(o){console.error("[Lego] Error boundary failed to render:",o),console.error("[Lego] Original error:",t)}},W=(e,r,t)=>{let o=je(r);o?Ge(o.errorTag,o.targetElement,e):f.onError(e,t,r)};var H=(e,r,t=null)=>{let o=r._studs,s=a=>{let c=_(a);if(!c.bound){if(a.hasAttributes()){let l=a.attributes;for(let m=0;m<l.length;m++){let g=l[m];if(g.name.startsWith("@")){let d=g.name.slice(1).split("."),p=d[0],b=d.slice(1);a.addEventListener(p,h=>{if(b.includes("prevent")&&h.preventDefault(),b.includes("stop")&&h.stopPropagation(),!(b.includes("self")&&h.target!==h.currentTarget)){if(typeof KeyboardEvent<"u"&&h instanceof KeyboardEvent){if(b.includes("ctrl")&&!h.ctrlKey||b.includes("alt")&&!h.altKey||b.includes("shift")&&!h.shiftKey||b.includes("meta")&&!h.metaKey)return;let E=b.filter(u=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(u));if(E.length>0){let u=h.key.toLowerCase();if(!E.some(y=>y==="enter"?u==="enter":y==="esc"||y==="escape"?u==="escape":y==="space"?u===" ":y==="tab"?u==="tab":y==="delete"?u==="delete":y==="backspace"?u==="backspace":y==="up"?u==="arrowup":y==="down"?u==="arrowdown":y==="left"?u==="arrowleft":y==="right"?u==="arrowright":y==="alpha"?/^[a-z]$/.test(u):y==="numbers"?/^[0-9]$/.test(u):y===u))return}}try{let E=o;if(t){let v=N(t.listName,{state:o,global:x,self:r})[t.index];E=Object.assign(Object.create(o),{[t.name]:v})}N(g.value,{state:E,global:x,self:a,event:h,$event:h},!0)}catch(E){W(E,r,"event-handler")}}})}}if(a.hasAttribute("b-sync")){let m=a.getAttribute("b-sync"),g=()=>{try{let d,p;if(t&&m.startsWith(`${t.name}.`)){let E=N(t.listName,{state:o,global:x,self:r})[t.index];if(!E)return;let u=m.split(".").slice(1);p=u.pop(),d=u.reduce((v,y)=>v[y],E)}else{let h=m.split(".");p=h.pop(),d=h.reduce((E,u)=>E[u],o)}let b=a.type==="checkbox"?a.checked:a.value;d&&d[p]!==b&&(d[p]=b)}catch(d){f.onError(d,"sync-update",a)}};a.addEventListener("input",g),a.addEventListener("change",g)}if(a.hasAttribute("b-var")){let m=a.getAttribute("b-var");o.$vars&&(o.$vars[m]=a)}}c.bound=!0}};e instanceof Element&&s(e);let n=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),i;for(;i=n.nextNode();)s(i)},Je=e=>{let r=[],t=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),o,s=[];for(;o=t.nextNode();){let n=o;if((c=>{let l=c.parentNode;for(;l&&l!==e;){if(l.hasAttribute&&l.hasAttribute("b-for"))return!0;l=l.parentNode}return!1})(o))continue;let a=c=>{if(/\bglobal\b/.test(c)){let l=e.host||e;K.add(l)}};if(o.nodeType===Node.ELEMENT_NODE){for(let[l,m]of Object.entries(J))if(m.scan){let g=m.scan(o,{checkGlobal:a,getPrivateData:_,pendingOperations:s,current:n});g&&r.push(g)}let[c]=U();[...o.attributes].forEach(l=>{l.value.includes(c)&&(a(l.value),r.push({type:"attr",node:o,attrName:l.name,template:l.value}))})}else if(o.nodeType===Node.TEXT_NODE){let[c]=U();o.textContent.includes(c)&&(a(o.textContent),r.push({type:"text",node:o,template:o.textContent}))}}return s.forEach(n=>n()),r},Ve=(e,r)=>{let t=n=>{if(n.nodeType===Node.TEXT_NODE){n._tpl===void 0&&(n._tpl=n.textContent);let i=n._tpl.replace(j(),(a,c)=>N(c.trim(),{state:r,global:x,self:n})??"");n.textContent!==i&&(n.textContent=i)}else if(n.nodeType===Node.ELEMENT_NODE){let[i]=U();[...n.attributes].forEach(a=>{if(a._tpl===void 0&&(a._tpl=a.value),a._tpl.includes(i)){let c=a._tpl.replace(j(),(l,m)=>N(m.trim(),{state:r,global:x,self:n})??"");a.value!==c&&(a.value=c,a.name==="class"&&(n.className=c))}})}};t(e);let o=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),s;for(;s=o.nextNode();)t(s)},O=e=>{f.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let r=e._studs;if(!r)return;let t=_(e);if(!t.rendering){t.rendering=!0,f.metrics&&f.metrics.onRenderStart&&f.metrics.onRenderStart(e);try{let o=e.shadowRoot||e;t.bindings||(t.bindings=Je(o)),t.bindings.forEach(s=>{let n=J[s.type];if(n){n.execute({binding:s,state:r,global:x,helpers:{bind:H,updateNodeBindings:Ve,contextEl:e}});return}if(s.type==="text"){let i=s.template.replace(j(),(a,c)=>N(c.trim(),{state:r,global:x,self:s.node})??"");s.node.textContent!==i&&(s.node.textContent=i)}if(s.type==="attr"){let i=s.template.replace(j(),(a,c)=>N(c.trim(),{state:r,global:x,self:s.node})??"");s.node.getAttribute(s.attrName)!==i&&(s.node.setAttribute(s.attrName,i),s.attrName==="class"&&(s.node.className=i))}}),r===x&&K.forEach(s=>O(s))}catch(o){W(o,e,"render")}finally{f.metrics&&f.metrics.onRenderEnd&&f.metrics.onRenderEnd(e),t.rendering=!1}}};var Re=new Map,Pe={},Fe=e=>{Pe=e},ze=async()=>{let e=Object.entries(Pe).map(async([r,t])=>{let o=await Promise.all(t.map(async s=>{try{if(s instanceof CSSStyleSheet)return s;let n=await fetch(s);if(!n.ok)throw new Error(`Status ${n.status}`);let i=await n.text(),a=new CSSStyleSheet;return await a.replace(i),a}catch(n){return console.error(`[Lego] Failed to load stylesheet: ${s}`,n),null}}));Re.set(r,o.filter(s=>s!==null))});await Promise.all(e),f.debug&&console.log("[Lego Debug] Re-applying stylesheets to",L.size,"blocks"),L.forEach(r=>{pe(r)})},pe=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let r=e.shadowRoot||e._legoShadow,t=e.tagName.toLowerCase(),o=w[t],s=(o&&o.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),n=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),i=[],a=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;a;){let g=(a.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);g.length&&i.push(...g);let d=a.tagName?a.tagName.toLowerCase():"";if(w[d]){let p=(w[d].getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);p.length&&i.push(...p)}a=a.parentElement||a.getRootNode&&a.getRootNode().host}let c=[...new Set([...s,...n])],l=[...new Set(i)],m=[...new Set([...l,...c])];if(m.length>0){let g=m.flatMap(d=>Re.get(d)||[]);g.length>0&&f.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",m,"- Sheets:",g.length),g.length>0&&(r.adoptedStyleSheets=[...g])}e._studsMeta={stylesheets:{explicit:c,inherited:l,applied:m}}};var S=e=>{if(f.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let r=_(e),t=e.tagName.toLowerCase(),o=w[t];if(o&&!r.snapped){r.snapped=!0;let n=o.content.cloneNode(!0),i=e.shadowRoot;i?i.innerHTML="":i=e.attachShadow({mode:"open"}),pe(e);let a=F(e,"*")||F(e.getRootNode().host,"*"),c=a&&a.state?a.state:{},l=R.get(t)||{},m=le(o.getAttribute("b-logic")||"{}"),g=le(e.getAttribute("b-logic")||"{}",c),d={$vars:{},$element:e,get $parent(){return F(e,"*")},$emit:(h,E)=>{e.dispatchEvent(new CustomEvent(h,{detail:E,bubbles:!0,composed:!0}))},get $route(){return x.$route},get $go(){return x.$go}};P(l,d),P(m,d),P(g,d),e._studs=z(d,e),Object.defineProperty(e,"state",{get(){return this._studs},set(h){Object.assign(this._studs,h)},configurable:!0,enumerable:!1}),i.appendChild(n);let p=i.querySelector("style");p&&(p.textContent=p.textContent.replace(/\bself\b/g,":host")),H(i,e),L.add(e),O(e),e.setAttribute("b-id",t);let b=i.querySelectorAll("*");if(f.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",b.length),b.forEach(h=>{let E=h.tagName.toLowerCase(),u=!!w[E];u&&f.debug&&console.log("[Lego Debug] Checking",E,"- Registered:",u),u&&S(h)}),e._legoShadow||(e._legoShadow=i),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(h){W(h,e,"mounted")}}let s=e.parentElement;for(;s&&!s._studs;)s=s.parentElement;s&&s._studs&&H(e,s),[...e.children].forEach(S)},I=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(t){W(t,e,"unmounted")}e.shadowRoot&&[...e.shadowRoot.children].forEach(I),L.delete(e),K.delete(e),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(t=>{e._studs.$vars[t]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let r=B.get(e);if(r&&(r.bindings&&(r.bindings.forEach(t=>{let o=J[t.type];if(o&&o.destroy)try{o.destroy({binding:t})}catch(s){console.error(`[Lego] Error in directive cleanup (${t.type}):`,s)}t.node=null,t.anchor=null}),r.bindings=null),r.anchor=null,B.delete(e)),M.has(e)){let t=M.get(e);t.forEach((o,s)=>{o&&o._studs&&(o._studs=null)}),t.clear(),M.delete(e)}[...e.children].forEach(I)};function We(e,r="block.lego"){let t={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",blockName:be(r)},o=e,s=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;o;){let n=o.match(s);if(!n)break;let i=n[1].toLowerCase(),a=n[2],c=n[0],l=n.index,m=`</${i}>`,g=l+c.length,d=o.indexOf(m,g);if(d===-1){console.warn(`[Lego] Unclosed <${i}> tag in ${r}`);break}let p=o.slice(g,d);if(i==="template"){t.template=p.trim();let b=a.match(/b-stylesheets=["']([^"']+)["']/);b&&(t.stylesAttr=b[1]);let h=a.match(/b-cascade=["']([^"']+)["']/);h&&(t.cascadeAttr=h[1]);let E=a.match(/b-error=["']([^"']+)["']/);E&&(t.errorAttr=E[1])}else if(i==="script"){t.script=p.trim();let b=a.match(/lang=["']([^"']+)["']/);b&&(t.scriptLang=b[1])}else i==="style"&&(t.style=p.trim());o=o.slice(d+m.length)}return t}var He=(e,r,t="block.lego")=>{let o=We(r,t),{blockName:s,template:n,script:i,style:a,stylesAttr:c,cascadeAttr:l,errorAttr:m}=o,g={};if(i)try{let p=i.trim(),b=p.match(/export\s+default\s+({[\s\S]*})/),h=b?b[1]:p;g=new Function("Lego","$db",`return ${h}`)(e,e.globals.$db)}catch(p){f.onError(p,"script",s)}let d=n;a&&(d=`<style>${a}</style>`+d),w[s]=document.createElement("template"),w[s].innerHTML=d,c&&w[s].setAttribute("b-stylesheets",c),l&&w[s].setAttribute("b-cascade",l),m&&w[s].setAttribute("b-error",m),R.set(s,g),document.querySelectorAll(s).forEach(p=>!_(p).snapped&&S(p))};oe.setHandler(O);Be(S,O);Ee(S);var Xe={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},T=z({$route:Xe,$go:(e,...r)=>re(e,...r)(document.body),$db:ue},typeof document<"u"?document.body:null);he(T);var D={db:ue,snap:S,unsnap:I,defineLegoFile:(e,r)=>He(D,e,r),block:(e,r,t={},o="",s="",n="")=>{let i=document.createElement("template");i.setAttribute("b-id",e),i.setAttribute("b-stylesheets",o),s&&i.setAttribute("b-cascade",s),n&&i.setAttribute("b-error",n),i.innerHTML=r,w[e]=i,R.set(e,t);try{let a={};P(t,a),Z.set(e.toLowerCase(),z(a,document.body))}catch(a){f.onError(a,"define",e)}document.querySelectorAll(e).forEach(S),[...L].forEach(a=>{a.tagName.toLowerCase()===e.toLowerCase()&&(f.debug&&console.log("[Lego HMR] Reloading",e),I(a),S(a))}),L.forEach(a=>{a._legoShadow&&a._legoShadow.querySelectorAll(e).forEach(c=>{_(c).snapped||(f.debug&&console.log("[Lego Debug] Lazy-initializing",e,"in",a.tagName),S(c))})})},getActiveBlocksCount:()=>L.size,getLegos:()=>Object.keys(w),config:f,globals:T,route:(e,r,t=null)=>{let o=[],s=e==="*"?".*":e;s=s.replace(/:([^\/]+)/g,(n,i)=>(o.push(i),"([^/]+)")),G.push({path:e,regex:new RegExp(`^${s}$`),tagName:r,paramNames:o,middleware:t})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,r={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),Fe(r.styles||{}),f.loader=r.loader,f.debug=r.debug===!0,await ze(),G.length>0){let n=window.location.pathname,i=window.location.search,a=ce(n);if(a){let{match:c,params:l}=a,m=Object.fromEntries(new URLSearchParams(i));T.$route.url=n+i,T.$route.route=c.path,T.$route.params=l,T.$route.query=m,T.$route.method="GET",T.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(n=>{w[n.getAttribute("b-id")]=n});let t=n=>{if(n.nodeType!==Node.ELEMENT_NODE)return;S(n);let i=n.tagName.toLowerCase();if(i.includes("-")&&!w[i]&&f.loader&&!L.has(n)){let a=f.loader(i);if(a){let c=typeof a=="string"?fetch(a).then(l=>l.text()):a;Promise.resolve(c).then(l=>D.defineLegoFile(l,`${i}.lego`)).catch(l=>console.error(`[Lego] Failed to load ${i}:`,l))}}};new MutationObserver(n=>n.forEach(i=>{i.addedNodes.forEach(t),i.removedNodes.forEach(a=>a.nodeType===Node.ELEMENT_NODE&&I(a))})).observe(e,{childList:!0,subtree:!0});let s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(t(e);s.nextNode();)t(s.currentNode);if(e._studs=T,H(e,e),O(e),r.studio){if(!w["lego-studio"]){let n=document.createElement("script");n.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",n.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(n)}D.route("/_/studio","lego-studio"),D.route("/_/studio/:block","lego-studio")}G.length>0&&(window.addEventListener("popstate",n=>{let i=n.state?.legoTargets||null;te(i)}),document.addEventListener("submit",n=>{n.preventDefault()}),document.addEventListener("click",n=>{let a=n.composedPath().find(c=>c.tagName==="A"&&(c.hasAttribute("b-target")||c.hasAttribute("b-link")));if(a){n.preventDefault();let c=a.getAttribute("href"),l=a.getAttribute("b-target"),m=l?l.split(/\s+/).filter(Boolean):[],g=a.getAttribute("b-link")!=="false";T.$go(c,...m).get(g)}}),te()),De()}};typeof window<"u"?window.Lego=D:typeof global<"u"&&(global.Lego=D);var go=D;export{D as Lego,go as default};
7
+ `),we.set(e,t));let a={$ancestors:n=>F(r.self,n),$registry:n=>Q.get(n.toLowerCase()),$element:r.self,$route:N.$route,$go:(n,...c)=>te(n,...c)(r.self),$db:N.$db,$emit:(n,c)=>{r.self.dispatchEvent(new CustomEvent(n,{detail:c,bubbles:!0,composed:!0}))}},i=t.call(s,r.global,r.self,r.event,a);return typeof i=="function"?i.call(s,r.event):i}catch(s){if(o)throw s;m.onError(s,"render-error",r.self);return}},le=(e,r={})=>{if(!e||e.trim()==="{}")return{};let o=s=>new Function("scope","global",`with(global) { with(scope) { return (${s}); } }`)(r,N);try{return o(e)}catch(s){let t=e.trim();if(!t.startsWith("{")&&t.includes(":"))try{return o(`{${e}}`)}catch{}return console.error(`[Lego] Error parsing b-logic: "${e.length>80?e.slice(0,80)+"...":e}"`,s),{}}};var xe={name:"b-if",scan:(e,{checkGlobal:r,getPrivateData:o})=>O("b-if",e,(s,t)=>{r(s.value);let a=document.createComment(`b-if: ${s.value}`),i=o(t);return i.anchor=a,{anchor:a}}),execute({binding:e,state:r,global:o}){let{node:s,anchor:t,expr:a}=e,i=!!x(a,{state:r,global:o,self:s}),n=!!s.parentNode;i&&!n?t.parentNode&&t.parentNode.replaceChild(s,t):!i&&n&&s.parentNode.replaceChild(t,s)}};var ve={name:"b-show",scan(e,{checkGlobal:r}){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-show")){let o=e.getAttribute("b-show");return r(o),{type:"b-show",node:e,expr:o}}},execute({binding:e,state:r,global:o}){let{node:s,expr:t}=e;s.style.display=x(t,{state:r,global:o,self:s})?"":"none"}};var Ne={name:"b-text",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-text"))return{type:"b-text",node:e,path:e.getAttribute("b-text")}},execute({binding:e,state:r}){let{node:o,path:s}=e;o.textContent=B(s,r)}};var Se={name:"b-html",scan:e=>O("b-html",e),execute:({binding:e,state:r,global:o})=>{let{node:s,expr:t}=e;s.innerHTML=x(t,{state:r,global:o,self:s})||""}};var $e={name:"b-sync",scan(e){if(e.nodeType===Node.ELEMENT_NODE&&e.hasAttribute("b-sync"))return{type:"b-sync",node:e}},execute({binding:e,state:r}){let{node:o}=e;Y(o,B(o.getAttribute("b-sync"),r))}};var Le={name:"b-for",scan(e,{checkGlobal:r,pendingOperations:o}){if(e.nodeType!==Node.ELEMENT_NODE)return;let s=e.getAttribute("b-for")?.match(/^\s*(\w+)\s+in\s+([\s\S]+?)\s*$/);if(s){r(s[2]);let t=document.createComment(`b-for: ${s[1]} in ${s[2].trim()}`);return o.push(()=>{e.parentNode&&(e.parentNode.insertBefore(t,e),e.remove())}),{type:"b-for",anchor:t,itemName:s[1],listName:s[2].trim(),keyPath:e.getAttribute("b-key")||null,template:e.cloneNode(!0)}}},execute({binding:e,state:r,global:o,helpers:s}){let{bind:t,updateNodeBindings:a}=s;if(!t||!a){console.error("[Lego] b-for directive missing required helpers: bind, updateNodeBindings");return}let{anchor:i,listName:n,itemName:c,keyPath:l,template:d}=e,{contextEl:u}=s,f=x(n,{state:r,global:o,self:u})||[];C.has(i)||C.set(i,new Map);let g=C.get(i),b=new Set,h=[];f.forEach((p,$)=>{let E;l?(E=B(l,p),E===void 0&&console.warn(`[Lego] b-key="${l}" resolved to undefined for item at index ${$}. Check for typos.`)):p&&typeof p=="object"?(E=p.id||p._id||p.uuid||p.key,E===void 0&&(X.has(p)||X.set(p,Math.random()),E=X.get(p))):E=`${$}-${p}`,b.add(E);let T=g.get(E);T||(T=d.cloneNode(!0),T.removeAttribute("b-for"),T.removeAttribute("b-key"),g.set(E,T),t(T,u,{name:c,listName:n,index:$}));let Ie=Object.assign(Object.create(r),{[c]:p,$index:$});a(T,Ie),T.querySelectorAll("[b-sync]").forEach(me=>{let ge=me.getAttribute("b-sync");if(ge.startsWith(`${c}.`)){let qe=x(n,{state:r,global:o,self:u});Y(me,B(ge.split(".").slice(1).join("."),qe[$]))}}),h.push(T)});let w=i.nextSibling;h.forEach(p=>{p!==w?i.parentNode.insertBefore(p,w):w=w.nextSibling});for(let[p,$]of g.entries())b.has(p)||($.remove(),g.delete(p))}};var _e={scan:e=>{if(e.hasAttribute("b-init"))return{type:"b-init",node:e,expr:e.getAttribute("b-init")}},execute:({binding:e,state:r})=>{e.initialized||(e.initialized=!0,x(e.expr,{state:r}))}};var Te={name:"b-enter",scan:e=>O("b-enter",e,(r,o)=>({modifiers:r.name.split(".").slice(1)})),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((s,t)=>{s[0].isIntersecting&&(x(e.expr,{state:r}),e.modifiers.includes("once")&&(t.disconnect(),e.observer=null,e.done=!0))});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var Ae={scan:e=>O("b-leave",e),execute:({binding:e,state:r})=>{if(e.observer||e.done)return;let o=new IntersectionObserver((s,t)=>{let a=s[0];a.isIntersecting&&(e.activated=!0),!a.isIntersecting&&e.activated&&(x(e.expr,{state:r}),e.modifiers.includes("once")&&(t.disconnect(),e.observer=null,e.done=!0))});o.observe(e.node),e.observer=o},destroy:({binding:e})=>{e.observer&&(e.observer.disconnect(),e.observer=null)}};var G={"b-if":xe,"b-show":ve,"b-text":Ne,"b-html":Se,"b-sync":$e,"b-for":Le,"b-init":_e,"b-enter":Te,"b-leave":Ae};var Ue=(e=null)=>{let r=!1,o=new Set,s=!1,t=e,a=new Set,i=null,n=new Set,c=f=>{t=f},l=()=>{i&&clearTimeout(i),i=setTimeout(()=>{n.forEach(f=>{let g=f._studs;if(g&&typeof g.updated=="function")try{g.updated.call(g)}catch(b){console.error("[Lego] Error in updated hook:",b)}}),n.clear(),i=null},50)},d=()=>{a.size>0&&(a.forEach(f=>o.add(f)),a.clear(),!r&&o.size>0&&(r=!0,requestAnimationFrame(u)))},u=()=>{s=!0;let f=Array.from(o);o.clear(),r=!1,f.forEach(g=>{g.isConnected&&t&&t(g)}),f.forEach(g=>n.add(g)),l(),s=!1,d()};return{add:f=>{if(f){if(s){a.add(f);return}o.add(f),!r&&(r=!0,requestAnimationFrame(u))}},setHandler:c}},re=Ue();var L=new Map,oe=new Map,J=new WeakMap,V=new Map,je=e=>{let r=Array.from(V.entries()).filter(([t])=>t.startsWith("lego:")).sort((t,a)=>t[1].timestamp-a[1].timestamp),o=0,s=[];for(let[t,a]of r){if(o>=e)break;try{localStorage.removeItem(t),o+=a.size,s.push(t),V.delete(t)}catch(i){console.error(`[Lego] Failed to evict ${t}:`,i)}}return s},ke=(e,r,o)=>{m.debug&&console.log("[Lego Trace] scheduleSave",e,r,o),oe.has(e)&&clearTimeout(oe.get(e));let s=()=>{try{let t=JSON.stringify(r),a=new Blob([t]).size;localStorage.setItem(e,t);let i=e.startsWith("lego:")?e:`lego:${e}`;V.set(i,{timestamp:Date.now(),size:a}),oe.delete(e)}catch(t){if(t.name==="QuotaExceededError"){console.warn(`[Lego] Storage quota exceeded for key: ${e}`);try{let a=JSON.stringify(r),i=new Blob([a]).size,n=je(i*2);if(n.length>0){m.debug&&console.log(`[Lego] Evicted ${n.length} old keys, retrying save`),localStorage.setItem(e,a);let c=e.startsWith("lego:")?e:`lego:${e}`;V.set(c,{timestamp:Date.now(),size:i})}else m.onError(new Error("Storage quota exceeded and no keys available for eviction"),"quota",e)}catch{m.onError(new Error(`Critical: Could not save ${e} even after eviction`),"quota-critical",e)}}else console.error(`[Lego] Storage Error (${e}):`,t)}};o>0?oe.set(e,setTimeout(s,o)):s()},fe=e=>({__type:"lego-db",key:e,_default:void 0,_debounce:0,default(o){return this._default=o,this},debounce(o){return this._debounce=o,this},set(o,s=0){return ke(e,o,s),L.has(e)&&L.get(e).forEach(({target:t,prop:a,el:i,batcher:n})=>{t[a]=o,i&&n&&n.add(i)}),o},get(){try{let o=localStorage.getItem(e);return o!==null?JSON.parse(o):null}catch(o){return console.warn(`[Lego] Failed to get localStorage value for key "${e}":`,o),null}},delete(){try{return localStorage.removeItem(e),V.delete(e.startsWith("lego:")?e:`lego:${e}`),L.has(e)&&L.get(e).forEach(({target:o,prop:s,el:t,batcher:a})=>{o[s]=null,t&&a&&a.add(t)}),!0}catch(o){return console.error(`[Lego] Failed to delete localStorage key "${e}":`,o),!1}}}),Ce=e=>e&&e.__type==="lego-db",Me=(e,r,o,s,t)=>{m.debug&&console.log("[Lego Trace] Reactive DB Init:",r,o);let a=o._default;try{let i=localStorage.getItem(o.key);i!==null&&(a=JSON.parse(i))}catch(i){console.warn(`[Lego] Failed to parse localStorage value for key "${o.key}":`,i)}e[r]=a,J.has(e)||J.set(e,{}),J.get(e)[r]={key:o.key,debounce:o._debounce},m.debug&&console.log("[Lego Trace] DB Metadata Set:",r,J.get(e)[r]),L.has(o.key)||L.set(o.key,new Set),L.get(o.key).add({target:e,prop:r,el:s,batcher:t})},Oe=(e,r,o)=>{let s=J.get(e);if(s&&s[r]){let t=s[r].key;ke(t,o,s[r].debounce),L.has(t)&&L.get(t).forEach(({target:a,prop:i,el:n,batcher:c})=>{a!==e&&(a[i]=o,n&&c&&c.add(n))})}},Be=()=>{typeof window<"u"&&window.addEventListener("storage",e=>{if(!(!e.key||!L.has(e.key)))try{let r=JSON.parse(e.newValue);L.get(e.key).forEach(({target:o,prop:s,el:t,batcher:a})=>{o[s]=r,t&&a&&a.add(t)})}catch(r){console.warn("[Lego] Cross-tab sync error:",r)}})};var z=(e,r,o=re)=>{if(e===null||typeof e!="object"||ae(e))return e;if(I.has(e))return I.get(e);for(let a in e){let i=Object.getOwnPropertyDescriptor(e,a);if(i&&i.get)continue;let n=e[a];Ce(n)&&Me(e,a,n,r,o)}let s={get:(a,i)=>{let n=Reflect.get(a,i);return n!==null&&typeof n=="object"&&!ae(n)?z(n,r,o):n},set:(a,i,n,c)=>{let l=a[i];m.debug&&l!==n&&console.log("[Lego Trace] Reactive SET:",i,"Old:",l,"New:",n,"Target:",a);let d=Reflect.set(a,i,n,c);return c===I.get(a)&&l!==n&&(o.add(r),Oe(a,i,n)),d},deleteProperty:(a,i)=>{let n=Reflect.deleteProperty(a,i);return o.add(r),n}},t=new Proxy(e,s);return I.set(e,t),t};var Ke=e=>{let r=e;for(;r;){let o=r.getAttribute&&r.getAttribute("b-error");if(o)return{errorTag:o,targetElement:r};let s=r.tagName?r.tagName.toLowerCase():"",t=y[s];if(t){let a=t.getAttribute("b-error");if(a)return{errorTag:a,targetElement:r}}r=r.parentElement||r.getRootNode&&r.getRootNode().host}return null},de=null,ue=null,De=(e,r)=>{de=e,ue=r},Ge=(e,r,o)=>{if(!de||!ue){console.error("[Lego] Error boundary dependencies not loaded",o);return}try{r.shadowRoot?r.shadowRoot.innerHTML="":r.innerHTML="";let s=document.createElement(e);(r.shadowRoot||r).appendChild(s),de(s),s._studs&&(s._studs.$error={message:o.message,stack:o.stack,component:r.tagName.toLowerCase()},ue(s))}catch(s){console.error("[Lego] Error boundary failed to render:",s),console.error("[Lego] Original error:",o)}},W=(e,r,o)=>{let s=Ke(r);s?Ge(s.errorTag,s.targetElement,e):m.onError(e,o,r)};var se=(e,r,o=null)=>{let s=r._studs,t=n=>{let c=M(n);if(!c.bound){if(n.hasAttributes()){let l=n.attributes;for(let d=0;d<l.length;d++){let u=l[d];if(u.name.startsWith("@")){let f=u.name.slice(1).split("."),g=f[0],b=f.slice(1);n.addEventListener(g,h=>{if(b.includes("prevent")&&h.preventDefault(),b.includes("stop")&&h.stopPropagation(),!(b.includes("self")&&h.target!==h.currentTarget)){if(typeof KeyboardEvent<"u"&&h instanceof KeyboardEvent){if(b.includes("ctrl")&&!h.ctrlKey||b.includes("alt")&&!h.altKey||b.includes("shift")&&!h.shiftKey||b.includes("meta")&&!h.metaKey)return;let w=b.filter(p=>!["prevent","stop","self","ctrl","alt","shift","meta","capture","once","passive"].includes(p));if(w.length>0){let p=h.key.toLowerCase();if(!w.some(E=>E==="enter"?p==="enter":E==="esc"||E==="escape"?p==="escape":E==="space"?p===" ":E==="tab"?p==="tab":E==="delete"?p==="delete":E==="backspace"?p==="backspace":E==="up"?p==="arrowup":E==="down"?p==="arrowdown":E==="left"?p==="arrowleft":E==="right"?p==="arrowright":E==="alpha"?/^[a-z]$/.test(p):E==="numbers"?/^[0-9]$/.test(p):E===p))return}}try{let w=s;if(o){let $=x(o.listName,{state:s,global:N,self:r})[o.index];w=Object.assign(Object.create(s),{[o.name]:$})}x(u.value,{state:w,global:N,self:n,event:h,$event:h},!0)}catch(w){W(w,r,"event-handler")}}})}}if(n.hasAttribute("b-sync")){let d=n.getAttribute("b-sync"),u=()=>{try{let f,g;if(o&&d.startsWith(`${o.name}.`)){let w=x(o.listName,{state:s,global:N,self:r})[o.index];if(!w)return;let p=d.split(".").slice(1);g=p.pop(),f=p.reduce(($,E)=>$[E],w)}else{let h=d.split(".");g=h.pop(),f=h.reduce((w,p)=>w[p],s)}let b=n.type==="checkbox"?n.checked:n.value;f&&f[g]!==b&&(f[g]=b)}catch(f){m.onError(f,"sync-update",n)}};n.addEventListener("input",u),n.addEventListener("change",u)}if(n.hasAttribute("b-var")){let d=n.getAttribute("b-var");s.$vars&&(s.$vars[d]=n)}}c.bound=!0}};e instanceof Element&&t(e);let a=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT),i;for(;i=a.nextNode();)t(i)},Je=e=>{let r=[],o=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),s,t=[];for(;s=o.nextNode();){let a=s;if((c=>{let l=c.parentNode;for(;l&&l!==e;){if(l.hasAttribute&&l.hasAttribute("b-for"))return!0;l=l.parentNode}return!1})(s))continue;let n=c=>{if(/\bglobal\b/.test(c)){let l=e.host||e;q.add(l)}};if(s.nodeType===Node.ELEMENT_NODE){for(let[l,d]of Object.entries(G))if(d.scan){let u=d.scan(s,{checkGlobal:n,getPrivateData:M,pendingOperations:t,current:a});u&&r.push(u)}let[c]=U();[...s.attributes].forEach(l=>{l.value.includes(c)&&(n(l.value),r.push({type:"attr",node:s,attrName:l.name,template:l.value}))})}else if(s.nodeType===Node.TEXT_NODE){let[c]=U();s.textContent.includes(c)&&(n(s.textContent),r.push({type:"text",node:s,template:s.textContent}))}}return t.forEach(a=>a()),r},Ve=(e,r)=>{let o=a=>{if(a.nodeType===Node.TEXT_NODE){a._tpl===void 0&&(a._tpl=a.textContent);let i=a._tpl.replace(j(),(n,c)=>x(c.trim(),{state:r,global:N,self:a})??"");a.textContent!==i&&(a.textContent=i)}else if(a.nodeType===Node.ELEMENT_NODE){let[i]=U();[...a.attributes].forEach(n=>{if(n._tpl===void 0&&(n._tpl=n.value),n._tpl.includes(i)){let c=n._tpl.replace(j(),(l,d)=>x(d.trim(),{state:r,global:N,self:a})??"");n.value!==c&&(n.value=c,n.name==="class"&&(a.className=c))}})}};o(e);let s=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT),t;for(;t=s.nextNode();)o(t)},H=e=>{m.debug&&console.log("[Lego Trace] render() called for:",e.tagName);let r=e._studs;if(!r)return;let o=M(e);if(!o.rendering){o.rendering=!0,m.metrics&&m.metrics.onRenderStart&&m.metrics.onRenderStart(e);try{let s=e.shadowRoot||e;o.bindings||(o.bindings=Je(s)),o.bindings.forEach(t=>{let a=G[t.type];if(a){a.execute({binding:t,state:r,global:N,helpers:{bind:se,updateNodeBindings:Ve,contextEl:e}});return}if(t.type==="text"){let i=t.template.replace(j(),(n,c)=>x(c.trim(),{state:r,global:N,self:t.node})??"");t.node.textContent!==i&&(t.node.textContent=i)}if(t.type==="attr"){let i=t.template.replace(j(),(n,c)=>x(c.trim(),{state:r,global:N,self:t.node})??"");t.node.getAttribute(t.attrName)!==i&&(t.node.setAttribute(t.attrName,i),t.attrName==="class"&&(t.node.className=i))}}),r===N&&q.forEach(t=>H(t))}catch(s){W(s,e,"render")}finally{m.metrics&&m.metrics.onRenderEnd&&m.metrics.onRenderEnd(e),o.rendering=!1}}};var Re=new Map,Pe={},Fe=e=>{Pe=e},ze=async()=>{let e=Object.entries(Pe).map(async([r,o])=>{let s=await Promise.all(o.map(async t=>{try{if(t instanceof CSSStyleSheet)return t;let a=await fetch(t);if(!a.ok)throw new Error(`Status ${a.status}`);let i=await a.text(),n=new CSSStyleSheet;return await n.replace(i),n}catch(a){return console.error(`[Lego] Failed to load stylesheet: ${t}`,a),null}}));Re.set(r,s.filter(t=>t!==null))});await Promise.all(e),m.debug&&console.log("[Lego Debug] Re-applying stylesheets to",_.size,"blocks"),_.forEach(r=>{pe(r)})},pe=e=>{if(!e.shadowRoot&&!e._legoShadow)return;let r=e.shadowRoot||e._legoShadow,o=e.tagName.toLowerCase(),s=y[o],t=(s&&s.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),a=(e.getAttribute("b-stylesheets")||"").split(/\s+/).filter(Boolean),i=[],n=e.parentElement||(e.getRootNode?e.getRootNode().host:null);for(;n;){let u=(n.getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);u.length&&i.push(...u);let f=n.tagName?n.tagName.toLowerCase():"";if(y[f]){let g=(y[f].getAttribute("b-cascade")||"").split(/\s+/).filter(Boolean);g.length&&i.push(...g)}n=n.parentElement||n.getRootNode&&n.getRootNode().host}let c=[...new Set([...t,...a])],l=[...new Set(i)],d=[...new Set([...l,...c])];if(d.length>0){let u=d.flatMap(f=>Re.get(f)||[]);u.length>0&&m.debug&&console.log("[Lego Debug] Applying styles to",e.tagName,"- Names:",d,"- Sheets:",u.length),u.length>0&&(r.adoptedStyleSheets=[...u])}e._studsMeta={stylesheets:{explicit:c,inherited:l,applied:d}}};var S=e=>{if(m.debug&&console.log("[Lego Trace] snap() called for:",e.tagName),!e||e.nodeType!==Node.ELEMENT_NODE)return;let r=M(e),o=e.tagName.toLowerCase(),s=y[o];if(s&&!r.snapped){r.snapped=!0;let a=s.content.cloneNode(!0),i=e.shadowRoot;i?i.innerHTML="":i=e.attachShadow({mode:"open"}),pe(e);let n=F(e,"*")||F(e.getRootNode().host,"*"),c=n&&n.state?n.state:{},l=R.get(o)||{},d=le(s.getAttribute("b-logic")||"{}"),u=le(e.getAttribute("b-logic")||"{}",c),f={$vars:{},$element:e,get $parent(){return F(e,"*")},$emit:(h,w)=>{e.dispatchEvent(new CustomEvent(h,{detail:w,bubbles:!0,composed:!0}))},get $route(){return N.$route},get $go(){return N.$go}};P(l,f),P(d,f),P(u,f),e._studs=z(f,e),Object.defineProperty(e,"state",{get(){return this._studs},set(h){Object.assign(this._studs,h)},configurable:!0,enumerable:!1}),i.appendChild(a);let g=i.querySelector("style");g&&(g.textContent=g.textContent.replace(/\bself\b/g,":host")),se(i,e),_.add(e),H(e),e.setAttribute("b-id",o);let b=i.querySelectorAll("*");if(m.debug&&console.log("[Lego Debug] Nested scan in",e.tagName,"- Found elements:",b.length),b.forEach(h=>{let w=h.tagName.toLowerCase(),p=!!y[w];p&&m.debug&&console.log("[Lego Debug] Checking",w,"- Registered:",p),p&&S(h)}),e._legoShadow||(e._legoShadow=i),typeof e._studs.mounted=="function")try{e._studs.mounted.call(e._studs)}catch(h){W(h,e,"mounted")}}let t=e.parentElement;for(;t&&!t._studs;)t=t.parentElement;t&&t._studs&&se(e,t),[...e.children].forEach(S)},A=e=>{if(e._studs&&typeof e._studs.unmounted=="function")try{e._studs.unmounted.call(e._studs)}catch(o){W(o,e,"unmounted")}e.shadowRoot&&[...e.shadowRoot.children].forEach(A),_.delete(e),q.delete(e),e._studs&&(e._studs.$element=null,e._studs.$vars&&(Object.keys(e._studs.$vars).forEach(o=>{e._studs.$vars[o]=null}),e._studs.$vars=null),e._studs.$emit&&(e._studs.$emit=null),delete e._studs.$parent,delete e._studs.$route,delete e._studs.$go,e._studs=null),e.hasOwnProperty("state")&&delete e.state;let r=D.get(e);if(r&&(r.bindings&&(r.bindings.forEach(o=>{let s=G[o.type];if(s&&s.destroy)try{s.destroy({binding:o})}catch(t){console.error(`[Lego] Error in directive cleanup (${o.type}):`,t)}o.node=null,o.anchor=null}),r.bindings=null),r.anchor=null,D.delete(e)),C.has(e)){let o=C.get(e);o.forEach((s,t)=>{s&&s._studs&&(s._studs=null)}),o.clear(),C.delete(e)}[...e.children].forEach(A)};function We(e,r="block.lego"){let o={template:"",script:"",style:"",stylesAttr:"",cascadeAttr:"",errorAttr:"",blockName:be(r)},s=e,t=/<(template|script|style)\b((?:\s+(?:[^>"']|"[^"]*"|'[^']*')*)*)>/i;for(;s;){let a=s.match(t);if(!a)break;let i=a[1].toLowerCase(),n=a[2],c=a[0],l=a.index,d=`</${i}>`,u=l+c.length,f=s.indexOf(d,u);if(f===-1){console.warn(`[Lego] Unclosed <${i}> tag in ${r}`);break}let g=s.slice(u,f);if(i==="template"){o.template=g.trim();let b=n.match(/b-stylesheets=["']([^"']+)["']/);b&&(o.stylesAttr=b[1]);let h=n.match(/b-cascade=["']([^"']+)["']/);h&&(o.cascadeAttr=h[1]);let w=n.match(/b-error=["']([^"']+)["']/);w&&(o.errorAttr=w[1])}else if(i==="script"){o.script=g.trim();let b=n.match(/lang=["']([^"']+)["']/);b&&(o.scriptLang=b[1])}else i==="style"&&(o.style=g.trim());s=s.slice(f+d.length)}return o}var He=(e,r,o="block.lego")=>{let s=We(r,o),{blockName:t,template:a,script:i,style:n,stylesAttr:c,cascadeAttr:l,errorAttr:d}=s,u={};if(i)try{let g=i.trim(),b=g.match(/export\s+default\s+({[\s\S]*})/),h=b?b[1]:g;u=new Function("Lego","$db",`return ${h}`)(e,e.globals.$db)}catch(g){m.onError(g,"script",t)}let f=a;n&&(f=`<style>${n}</style>`+f),y[t]=document.createElement("template"),y[t].innerHTML=f,c&&y[t].setAttribute("b-stylesheets",c),l&&y[t].setAttribute("b-cascade",l),d&&y[t].setAttribute("b-error",d),R.set(t,u),document.querySelectorAll(t).forEach(g=>!M(g).snapped&&S(g))};re.setHandler(H);De(S,H);Ee(S);var Xe={url:typeof window<"u"?window.location.pathname:"/",route:"",params:{},query:{},method:"GET",body:null},k=z({$route:Xe,$go:(e,...r)=>te(e,...r)(document.body),$db:fe},typeof document<"u"?document.body:null);he(k);var v={db:fe,snap:S,unsnap:A,defineLegoFile:(e,r)=>He(v,e,r),block:(e,r,o={},s="",t="",a="")=>{let i=document.createElement("template");i.setAttribute("b-id",e),i.setAttribute("b-stylesheets",s),t&&i.setAttribute("b-cascade",t),a&&i.setAttribute("b-error",a),i.innerHTML=r,y[e]=i,R.set(e,o);try{let n={};P(o,n),Q.set(e.toLowerCase(),z(n,document.body))}catch(n){m.onError(n,"define",e)}if(customElements.get(e))document.querySelectorAll(e).forEach(n=>{A(n),S(n)}),_.forEach(n=>{n._legoShadow&&n._legoShadow.querySelectorAll(e).forEach(c=>{A(c),S(c)})});else try{customElements.define(e,class extends HTMLElement{connectedCallback(){y[e]&&S(this)}disconnectedCallback(){A(this)}})}catch(n){console.warn(`[Lego] Failed to register web component ${e}:`,n)}},getActiveBlocksCount:()=>_.size,getLegos:()=>Object.keys(y),config:m,globals:k,route:(e,r,o=null)=>{let s=[],t=e==="*"?".*":e;t=t.replace(/:([^\/]+)/g,(a,i)=>(s.push(i),"([^/]+)")),K.push({path:e,regex:new RegExp(`^${t}$`),tagName:r,paramNames:s,middleware:o})},debug:{stylesheets:e=>!e||!e._studsMeta?null:e._studsMeta.stylesheets},init:async(e=document.body,r={})=>{if((!e||typeof e.nodeType!="number")&&(e=document.body),Fe(r.styles||{}),m.loader=r.loader,m.debug=r.debug===!0,await ze(),K.length>0){let t=window.location.pathname,a=window.location.search,i=ce(t);if(i){let{match:n,params:c}=i,l=Object.fromEntries(new URLSearchParams(a));k.$route.url=t+a,k.$route.route=n.path,k.$route.params=c,k.$route.query=l,k.$route.method="GET",k.$route.body=null}}document.querySelectorAll("template[b-id]").forEach(t=>{let a=t.getAttribute("b-id");y[a]=t,customElements.get(a)||customElements.define(a,class extends HTMLElement{connectedCallback(){y[a]&&S(this)}disconnectedCallback(){A(this)}})});let o=t=>{if(!t)return{};let a={};return Object.entries(t).forEach(([i,n])=>{if(typeof n=="function")a[i]=n();else if(typeof n=="string"&&n.startsWith("$db.")){let c=n.slice(4);a[i]=v.db(c).get()}else if(typeof n=="string"&&n.startsWith("$globals.")){let c=n.slice(9);a[i]=N[c]}else a[i]=n}),a},s=(t,a,i={})=>{customElements.get(t)||customElements.define(t,class extends HTMLElement{async connectedCallback(){if(y[t]){S(this);return}if(v._fetching||(v._fetching=new Set),!v._fetching.has(t)){v._fetching.add(t);try{let n=a.startsWith("POST:")?"POST":"GET",c=a.replace(/^POST:/,""),l=o(i.headers),d={method:n,headers:l,credentials:i.credentials},f=await(await fetch(c,d)).text();v.defineLegoFile(f,`${t}.lego`),y[t]&&S(this)}catch(n){console.error(`[Lego] Failed to load manifest block ${t}:`,n)}finally{v._fetching.delete(t)}}}disconnectedCallback(){A(this)}})};if(r.manifest){let t=r.manifest;if(t.url&&typeof t.url=="string")try{let i=o(t.headers);t=await(await fetch(t.url,{headers:i,credentials:t.credentials})).json()}catch(i){console.error("[Lego] Failed to load manifest:",i),t=[]}else if(typeof t=="string")try{t=await(await fetch(t)).json()}catch(i){console.error("[Lego] Failed to load manifest:",i),t=[]}let a=Array.isArray(t)?t:[t];for(let i of a){let n=i.base||"",c=i.suffix===!0?".lego":i.suffix||"",l={headers:i.headers||{},credentials:i.credentials};i.legos&&i.legos.forEach(d=>{s(d,`${n}${d}${c}`,l)}),i.map&&Object.entries(i.map).forEach(([d,u])=>{let f=u.match(/^https?:|^\//)?u:`${n}${u}`;s(d,f,l)})}}if(m.loader){let t=n=>{if(n.nodeType!==Node.ELEMENT_NODE)return;let c=n.tagName.toLowerCase();if(c.includes("-")&&!y[c]&&!_.has(n)){if(v._fetching&&v._fetching.has(c))return;v._fetching||(v._fetching=new Set),v._fetching.add(c);let l=m.loader(c);if(l){let d=typeof l=="string"?fetch(l).then(u=>u.text()):l;Promise.resolve(d).then(u=>{v.defineLegoFile(u,`${c}.lego`),v._fetching.delete(c)}).catch(u=>{console.error(`[Lego] Failed to load ${c}:`,u),v._fetching.delete(c)})}}if(n.children.length>0){let l=n.firstElementChild;for(;l;)t(l),l=l.nextElementSibling}};new MutationObserver(n=>n.forEach(c=>{c.addedNodes.forEach(t)})).observe(e,{childList:!0,subtree:!0});let i=document.createTreeWalker(e,NodeFilter.SHOW_ELEMENT);for(;i.nextNode();)t(i.currentNode)}if(r.studio){if(!y["lego-studio"]){let t=document.createElement("script");t.src="https://unpkg.com/@legodom/studio@0.0.2/dist/lego-studio.js",t.onerror=()=>console.warn("[Lego] Failed to load Studio from CDN"),document.head.appendChild(t)}v.route("/_/studio","lego-studio"),v.route("/_/studio/:block","lego-studio")}K.length>0&&(window.addEventListener("popstate",t=>{let a=t.state?.legoTargets||null;ee(a)}),document.addEventListener("submit",t=>{t.preventDefault()}),document.addEventListener("click",t=>{let i=t.composedPath().find(n=>n.tagName==="A"&&(n.hasAttribute("b-target")||n.hasAttribute("b-link")));if(i){t.preventDefault();let n=i.getAttribute("href"),c=i.getAttribute("b-target"),l=c?c.split(/\s+/).filter(Boolean):[],d=i.getAttribute("b-link")!=="false";k.$go(n,...l).get(d)}}),ee()),Be()}};typeof window<"u"?window.Lego=v:typeof global<"u"&&(global.Lego=v);var ho=v;export{v as Lego,ho as default};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lego-dom",
3
- "version": "2.1.3",
3
+ "version": "2.1.4",
4
4
  "license": "MIT",
5
5
  "description": "A feature-rich web components + SFC frontend framework",
6
6
  "main": "dist/lego.min.js",
package/src/index.js CHANGED
@@ -60,27 +60,36 @@ const Lego = {
60
60
  config.onError(e, 'define', tagName);
61
61
  }
62
62
 
63
- document.querySelectorAll(tagName).forEach(snap);
64
-
65
- // HMR Support: Find and reload existing instances
66
- [...activeBlocks].forEach(block => {
67
- if (block.tagName.toLowerCase() === tagName.toLowerCase()) {
68
- if (config.debug) console.log('[Lego HMR] Reloading', tagName);
69
- unsnap(block);
70
- snap(block);
71
- }
72
- });
73
-
74
- activeBlocks.forEach(block => {
75
- if (block._legoShadow) {
76
- block._legoShadow.querySelectorAll(tagName).forEach(instance => {
77
- if (!getPrivateData(instance).snapped) {
78
- if (config.debug) console.log('[Lego Debug] Lazy-initializing', tagName, 'in', block.tagName);
79
- snap(instance);
63
+ if (!customElements.get(tagName)) {
64
+ try {
65
+ customElements.define(tagName, class extends HTMLElement {
66
+ connectedCallback() {
67
+ // Defer if not yet registered (shouldn't happen via Lego.block, but good safety)
68
+ if (registry[tagName]) snap(this);
69
+ }
70
+ disconnectedCallback() {
71
+ unsnap(this);
80
72
  }
81
73
  });
74
+ } catch (e) {
75
+ console.warn(`[Lego] Failed to register web component ${tagName}:`, e);
82
76
  }
83
- });
77
+ } else {
78
+ // HMR or Re-definition: manually upgrade existing instances
79
+ document.querySelectorAll(tagName).forEach(el => {
80
+ unsnap(el);
81
+ snap(el);
82
+ });
83
+ // Also catch instances in shadow roots
84
+ activeBlocks.forEach(block => {
85
+ if (block._legoShadow) {
86
+ block._legoShadow.querySelectorAll(tagName).forEach(instance => {
87
+ unsnap(instance);
88
+ snap(instance);
89
+ });
90
+ }
91
+ });
92
+ }
84
93
  },
85
94
  getActiveBlocksCount: () => activeBlocks.size,
86
95
  getLegos: () => Object.keys(registry),
@@ -127,41 +136,195 @@ const Lego = {
127
136
  }
128
137
  }
129
138
 
139
+ // 5. Register inline templates
130
140
  document.querySelectorAll('template[b-id]').forEach(t => {
131
- registry[t.getAttribute('b-id')] = t;
141
+ const tagName = t.getAttribute('b-id');
142
+ registry[tagName] = t;
143
+
144
+ if (!customElements.get(tagName)) {
145
+ customElements.define(tagName, class extends HTMLElement {
146
+ connectedCallback() {
147
+ if (registry[tagName]) snap(this);
148
+ }
149
+ disconnectedCallback() {
150
+ unsnap(this);
151
+ }
152
+ });
153
+ }
132
154
  });
133
155
 
134
- const checkAndLoad = (n) => {
135
- if (n.nodeType !== Node.ELEMENT_NODE) return;
136
- snap(n);
137
- const tagName = n.tagName.toLowerCase();
138
- if (tagName.includes('-') && !registry[tagName] && config.loader && !activeBlocks.has(n)) {
139
- const result = config.loader(tagName);
140
- if (result) {
141
- const promise = (typeof result === 'string')
142
- ? fetch(result).then(r => r.text())
143
- : result;
144
-
145
- Promise.resolve(promise)
146
- .then(legoFile => Lego.defineLegoFile(legoFile, `${tagName}.lego`))
147
- .catch(e => console.error(`[Lego] Failed to load ${tagName}:`, e));
156
+ // 6. Process Manifest (Pre-registration for Shadow DOM support)
157
+ const resolveHeaders = (headers) => {
158
+ if (!headers) return {};
159
+ const resolved = {};
160
+ Object.entries(headers).forEach(([key, val]) => {
161
+ if (typeof val === 'function') {
162
+ resolved[key] = val();
163
+ } else if (typeof val === 'string' && val.startsWith('$db.')) {
164
+ // $db.auth.token
165
+ const path = val.slice(4);
166
+ // Simple get from persistence layer
167
+ resolved[key] = Lego.db(path).get();
168
+ } else if (typeof val === 'string' && val.startsWith('$globals.')) {
169
+ // $globals.user.token
170
+ const keyPath = val.slice(9);
171
+ resolved[key] = globalsTarget[keyPath];
172
+ } else {
173
+ resolved[key] = val;
148
174
  }
149
- }
175
+ });
176
+ return resolved;
177
+ };
178
+
179
+ const registerLazy = (tagName, url, config = {}) => {
180
+ if (customElements.get(tagName)) return;
181
+
182
+ customElements.define(tagName, class extends HTMLElement {
183
+ async connectedCallback() {
184
+ if (registry[tagName]) {
185
+ snap(this);
186
+ return;
187
+ }
188
+
189
+ if (!Lego._fetching) Lego._fetching = new Set();
190
+ if (Lego._fetching.has(tagName)) return;
191
+ Lego._fetching.add(tagName);
192
+
193
+ try {
194
+ const method = url.startsWith('POST:') ? 'POST' : 'GET';
195
+ const cleanUrl = url.replace(/^POST:/, '');
196
+
197
+ // Resolve headers at runtime (just-in-time)
198
+ const headers = resolveHeaders(config.headers);
199
+
200
+ const fetchOpts = {
201
+ method,
202
+ headers,
203
+ credentials: config.credentials
204
+ };
205
+
206
+ const req = await fetch(cleanUrl, fetchOpts);
207
+ const content = await req.text();
208
+
209
+ Lego.defineLegoFile(content, `${tagName}.lego`);
210
+
211
+ if (registry[tagName]) snap(this);
212
+ } catch (e) {
213
+ console.error(`[Lego] Failed to load manifest block ${tagName}:`, e);
214
+ } finally {
215
+ Lego._fetching.delete(tagName);
216
+ }
217
+ }
218
+ disconnectedCallback() {
219
+ unsnap(this);
220
+ }
221
+ });
150
222
  };
151
223
 
152
- const observer = new MutationObserver(m => m.forEach(r => {
153
- r.addedNodes.forEach(checkAndLoad);
154
- r.removedNodes.forEach(n => n.nodeType === Node.ELEMENT_NODE && unsnap(n));
155
- }));
156
- observer.observe(root, { childList: true, subtree: true });
224
+ if (options.manifest) {
225
+ let m = options.manifest;
226
+
227
+ // 1. Check for Object with URL (Auth Manifest)
228
+ if (m.url && typeof m.url === 'string') {
229
+ try {
230
+ const headers = resolveHeaders(m.headers);
231
+ const r = await fetch(m.url, { headers, credentials: m.credentials });
232
+ m = await r.json();
233
+ } catch (e) {
234
+ console.error('[Lego] Failed to load manifest:', e);
235
+ m = [];
236
+ }
237
+ }
238
+ // 2. Check for String URL (Public Manifest)
239
+ else if (typeof m === 'string') {
240
+ try {
241
+ const r = await fetch(m);
242
+ m = await r.json();
243
+ } catch (e) {
244
+ console.error('[Lego] Failed to load manifest:', e);
245
+ m = [];
246
+ }
247
+ }
248
+
249
+ // Normalize to array
250
+ const groups = Array.isArray(m) ? m : [m];
251
+
252
+ for (const group of groups) {
253
+ const base = group.base || '';
254
+ const suffix = group.suffix === true ? '.lego' : (group.suffix || '');
255
+
256
+ const config = {
257
+ headers: group.headers || {},
258
+ credentials: group.credentials
259
+ };
260
+
261
+ // 1. Array style: legos: ['name']
262
+ if (group.legos) {
263
+ group.legos.forEach(name => {
264
+ registerLazy(name, `${base}${name}${suffix}`, config);
265
+ });
266
+ }
267
+ // 2. Map style: map: { 'name': 'url' }
268
+ if (group.map) {
269
+ Object.entries(group.map).forEach(([name, url]) => {
270
+ const fullUrl = url.match(/^https?:|^\//) ? url : `${base}${url}`;
271
+ registerLazy(name, fullUrl, config);
272
+ });
273
+ }
274
+ }
275
+ }
276
+
277
+ // Auto-Discovery: Watch for unknown tags to lazy-load (HTMX-style / Server Blocks)
278
+ if (config.loader) {
279
+ const discover = (n) => {
280
+ if (n.nodeType !== Node.ELEMENT_NODE) return;
281
+ const tagName = n.tagName.toLowerCase();
282
+ if (tagName.includes('-') && !registry[tagName] && !activeBlocks.has(n)) {
283
+ // Check if we are already fetching this tag to avoid dupes
284
+ if (Lego._fetching && Lego._fetching.has(tagName)) return;
285
+
286
+ if (!Lego._fetching) Lego._fetching = new Set();
287
+ Lego._fetching.add(tagName);
288
+
289
+ const result = config.loader(tagName);
290
+ if (result) {
291
+ const promise = (typeof result === 'string')
292
+ ? fetch(result).then(r => r.text())
293
+ : result;
157
294
 
158
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
159
- checkAndLoad(root);
160
- while (walker.nextNode()) checkAndLoad(walker.currentNode);
295
+ Promise.resolve(promise)
296
+ .then(legoFile => {
297
+ Lego.defineLegoFile(legoFile, `${tagName}.lego`);
298
+ Lego._fetching.delete(tagName);
299
+ })
300
+ .catch(e => {
301
+ console.error(`[Lego] Failed to load ${tagName}:`, e);
302
+ Lego._fetching.delete(tagName);
303
+ });
304
+ }
305
+ }
306
+ // Recursively check children for other unknown blocks
307
+ if (n.children.length > 0) {
308
+ // Use lightweight iteration
309
+ let child = n.firstElementChild;
310
+ while (child) {
311
+ discover(child);
312
+ child = child.nextElementSibling;
313
+ }
314
+ }
315
+ };
161
316
 
162
- root._studs = globalState;
163
- bind(root, root);
164
- render(root);
317
+ const discoveryObserver = new MutationObserver(m => m.forEach(r => {
318
+ r.addedNodes.forEach(discover);
319
+ }));
320
+
321
+ // Observe with subtree to catch deep injections
322
+ discoveryObserver.observe(root, { childList: true, subtree: true });
323
+
324
+ // Initial scan
325
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
326
+ while (walker.nextNode()) discover(walker.currentNode);
327
+ }
165
328
 
166
329
  if (options.studio) {
167
330
  if (!registry['lego-studio']) {