@stacksjs/stx 0.2.82 → 0.2.84

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.
Files changed (62) hide show
  1. package/dist/app-shell.js +21 -11
  2. package/dist/build-assets.js +19 -9
  3. package/dist/build-mode-detector.js +22 -12
  4. package/dist/build-views.js +22 -12
  5. package/dist/build.js +21 -11
  6. package/dist/caching.js +19 -9
  7. package/dist/cli.js +22 -12
  8. package/dist/component-processing.js +21 -11
  9. package/dist/component-renderer.js +21 -11
  10. package/dist/components.js +22 -12
  11. package/dist/conditionals.js +1 -1
  12. package/dist/custom-directives.js +1 -1
  13. package/dist/dev-server/index.js +22 -12
  14. package/dist/dev-server/serve-app.js +21 -11
  15. package/dist/dev-server/serve-file.js +21 -11
  16. package/dist/dev-server/serve-markdown.js +22 -12
  17. package/dist/dev-server/serve-multi.js +21 -11
  18. package/dist/dev-server.js +21 -11
  19. package/dist/docs.js +22 -12
  20. package/dist/dynamic-components.js +21 -11
  21. package/dist/error-handling.js +1 -1
  22. package/dist/errors/formatter.js +1 -1
  23. package/dist/errors/index.js +1 -1
  24. package/dist/i18n.js +1 -1
  25. package/dist/includes.js +21 -11
  26. package/dist/index.js +21 -11
  27. package/dist/interactive.js +22 -12
  28. package/dist/lazy-loader.js +98 -88
  29. package/dist/misc-directives.js +1 -1
  30. package/dist/plugin.js +21 -11
  31. package/dist/process.js +21 -11
  32. package/dist/production-builder.js +21 -11
  33. package/dist/production-server.js +21 -11
  34. package/dist/pwa/index.js +22 -12
  35. package/dist/pwa/offline.js +22 -12
  36. package/dist/pwa.js +21 -11
  37. package/dist/reactive.js +1 -1
  38. package/dist/render.js +22 -12
  39. package/dist/runtime-injection.js +19 -9
  40. package/dist/seo.js +1 -1
  41. package/dist/serve.js +22 -12
  42. package/dist/signal-processing.js +41 -31
  43. package/dist/signals.js +19 -9
  44. package/dist/site-builder/build.js +22 -12
  45. package/dist/site-builder/index.js +22 -12
  46. package/dist/ssg.js +21 -11
  47. package/dist/ssr.js +22 -12
  48. package/dist/store-loader.js +18 -18
  49. package/dist/story/cli.js +22 -12
  50. package/dist/story/commands/dev.js +22 -12
  51. package/dist/story/commands/index.js +22 -12
  52. package/dist/story/index.js +22 -12
  53. package/dist/story/renderer.js +22 -12
  54. package/dist/story/server.js +22 -12
  55. package/dist/story/visual-testing.js +22 -12
  56. package/dist/streaming.js +21 -11
  57. package/dist/template-compiler.js +22 -12
  58. package/dist/template-hydrator.js +22 -12
  59. package/dist/testing.js +147 -137
  60. package/dist/utils.js +21 -11
  61. package/dist/web-components.js +22 -12
  62. package/package.json +5 -5
@@ -2424,7 +2424,7 @@ window.__stx_reactive = (function() {
2424
2424
 
2425
2425
  return { initScope: initScope, reactive: reactive };
2426
2426
  })();
2427
- `}function O8($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;return String(J)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;return JSON.stringify(J)}catch{return X}}),Y}function IG($,Z){if($.length===0)return"";let Y=$.map((X)=>{let Q=JSON.stringify(Object.fromEntries(X.refs)),J=O8(X.stateExpr,Z),G=X.initExpr?O8(X.initExpr,Z):null,K=JSON.stringify(J),q=G?JSON.stringify(G):"null";return`
2427
+ `}function O8($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;return String(J)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;if(typeof J==="string"){let G=J.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(J)}catch{return X}}),Y}function IG($,Z){if($.length===0)return"";let Y=$.map((X)=>{let Q=JSON.stringify(Object.fromEntries(X.refs)),J=O8(X.stateExpr,Z),G=X.initExpr?O8(X.initExpr,Z):null,K=JSON.stringify(J),q=G?JSON.stringify(G):"null";return`
2428
2428
  (function() {
2429
2429
  var scopeEl = document.querySelector('${X.selector}');
2430
2430
  if (!scopeEl) return;
@@ -4495,6 +4495,13 @@ catch (e2) {
4495
4495
 
4496
4496
  // Known directive names to exclude from generic :attr binding
4497
4497
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
4498
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
4499
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
4500
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
4501
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
4502
+ // a dead duplicate attribute and the real viewBox never updates.
4503
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
4504
+ var SVG_NS = 'http://www.w3.org/2000/svg';
4498
4505
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
4499
4506
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
4500
4507
 
@@ -4519,7 +4526,8 @@ catch (e2) {
4519
4526
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
4520
4527
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
4521
4528
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
4522
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
4529
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
4530
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
4523
4531
  effect(() => {
4524
4532
  const v = evalAttrExpr(value);
4525
4533
  if (v === false || v === null || v === undefined) {
@@ -4898,10 +4906,12 @@ else {
4898
4906
  });
4899
4907
  }
4900
4908
  else if (Array.isArray(value)) {
4901
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
4909
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
4910
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
4902
4911
  }
4903
4912
  else {
4904
- el.className = originalClasses + (value ? ' ' + value : '');
4913
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
4914
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
4905
4915
  }
4906
4916
  });
4907
4917
  }
@@ -7225,10 +7235,10 @@ else {
7225
7235
  var root = scriptEl ? scriptEl.nextElementSibling : null;
7226
7236
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
7227
7237
 
7228
- // SPA fallback: during router navigation, script is appended to <body>
7238
+ // SPA fallback: during router navigation, script is appended to body>
7229
7239
  // (not inside the content container), so nextElementSibling won't find the page content.
7230
7240
  // Only use fallback when we genuinely couldn't find a suitable root element.
7231
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
7241
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
7232
7242
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
7233
7243
  var needsFallback = !root || root === document.body
7234
7244
  || (root && root.tagName === 'SCRIPT');
@@ -7547,7 +7557,7 @@ else {
7547
7557
  mountCallbacks.forEach(fn => fn());
7548
7558
  });
7549
7559
 
7550
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
7560
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
7551
7561
  // top-level element with data-stx (signal-processing.ts marks one element),
7552
7562
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
7553
7563
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -7644,7 +7654,7 @@ else {
7644
7654
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
7645
7655
  });
7646
7656
 
7647
- // Process <head> elements (title, meta) that may contain {{ }} expressions
7657
+ // Process head> elements (title, meta) that may contain {{ }} expressions
7648
7658
  // Use componentScope which now contains variables from processed components
7649
7659
  const headElements = document.querySelectorAll('head title, head meta[content]');
7650
7660
  headElements.forEach(el => {
@@ -7840,7 +7850,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
7840
7850
 
7841
7851
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
7842
7852
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
7843
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
7853
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
7844
7854
  var usedLatestSetup = false;
7845
7855
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
7846
7856
  try {
@@ -7924,7 +7934,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
7924
7934
 
7925
7935
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
7926
7936
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
7927
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
7937
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
7928
7938
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
7929
7939
  if (!container.__stx_scope) {
7930
7940
  // Dispose previous effects on the container (from prior navigation)
@@ -8032,7 +8042,7 @@ ${_}${z}
8032
8042
  return { ${U} };
8033
8043
  }
8034
8044
  if(window.stx)window.stx._latestSetup=${G};
8035
- </script>`,j=$;for(let H of J)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(L,F,O)=>{if(H.includes(F.toLowerCase()))return L;return`<${F}${O} data-stx="${G}">`})}return{output:j,setupCode:B}}function C2($){let Z=$,Y=[],X=new Set,Q=0,J=0,G=Z.length,K="",q=()=>{J++;let j=!1;while(J<G){let H=Z[J];if(H==="\\"){J+=2;continue}if(H==="["&&!j){j=!0,J++;continue}if(H==="]"&&j){j=!1,J++;continue}if(H==="/"&&!j){J++;while(J<G&&/[gimsuyd]/.test(Z[J]))J++;return}if(H===`
8045
+ </script>`,j=$;for(let H of J)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],L=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,O,V)=>{if(L||H.includes(O.toLowerCase()))return F;return L=!0,`<${O}${V} data-stx="${G}">`})}return{output:j,setupCode:B}}function C2($){let Z=$,Y=[],X=new Set,Q=0,J=0,G=Z.length,K="",q=()=>{J++;let j=!1;while(J<G){let H=Z[J];if(H==="\\"){J+=2;continue}if(H==="["&&!j){j=!0,J++;continue}if(H==="]"&&j){j=!1,J++;continue}if(H==="/"&&!j){J++;while(J<G&&/[gimsuyd]/.test(Z[J]))J++;return}if(H===`
8036
8046
  `)return;J++}},W=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},z=(j)=>{J++;while(J<G){if(Z[J]==="\\"){J+=2;continue}if(Z[J]===j){J++;return}J++}},U=()=>{J++;while(J<G){if(Z[J]==="\\"){J+=2;continue}if(Z[J]==="`"){J++;return}if(Z[J]==="$"&&Z[J+1]==="{"){J+=2;let j=1;while(J<G&&j>0)if(Z[J]==="{")j++,J++;else if(Z[J]==="}")j--,J++;else if(Z[J]==="'"||Z[J]==='"')z(Z[J]);else if(Z[J]==="`")U();else J++;continue}J++}},_=()=>{if(Z[J]==="/"&&Z[J+1]==="/"){while(J<G&&Z[J]!==`
8037
8047
  `)J++;return!0}if(Z[J]==="/"&&Z[J+1]==="*"){J+=2;while(J<G-1&&!(Z[J]==="*"&&Z[J+1]==="/"))J++;return J+=2,!0}return!1},B=()=>{if(Q!==0)return;let j=Z.slice(J).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(J).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let w=V.trim();if(!w)return;let A=w.indexOf(":"),N=(A>=0?w.slice(A+1).trim():w).split(/[\s=]/)[0];if(N&&!X.has(N))Y.push(N),X.add(N)});return}let L=Z.slice(J).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(L){L[1].split(",").forEach((V)=>{let w=V.trim().replace(/^\.\.\./,"");if(!w)return;let A=w.split(/[\s=]/)[0];if(A&&!X.has(A))Y.push(A),X.add(A)});return}let F=Z.slice(J).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let O=Z.slice(J).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(O){let V=O[1];if(!X.has(V))Y.push(V),X.add(V)}};while(J<G){if(_())continue;if(Z[J]==="'"||Z[J]==='"'){z(Z[J]),K=Z[J-1];continue}if(Z[J]==="`"){U(),K="`";continue}if(Z[J]==="/"&&Z[J+1]!=="/"&&Z[J+1]!=="*"&&W()){q(),K="/";continue}if(Z[J]==="{"){Q++,K="{",J++;continue}if(Z[J]==="}"){Q--,K="}",J++;continue}if(Q===0&&/[a-z]/i.test(Z[J])&&(J===0||/\s|[;{}()]/.test(Z[J-1])))B();if(!/\s/.test(Z[J]))K=Z[J];J++}return Y.join(", ")}async function D3($,Z,Y,X){if(!X4($))return $;let Q=$;if(Z.skipSignalsRuntime)return Q;let{output:J,setupCode:G}=await y2(Q,Y,X);if(Q=J,Q=await M2(Q,Z),Q=T2(Q),G)if(Q.includes("</head>"))Q=Q.replace("</head>",`${G}
8038
8048
  </head>`);else if(Q.includes("<body"))Q=Q.replace(/<body([^>]*)>/,`<body$1>
@@ -16,7 +16,7 @@ ${I}`)}if(E.suggestion)G.push(`
16
16
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),G.join("")}function ZE(E,F,_){let M=E.split(`
17
17
  `),O=Math.max(0,F-_-1),U=Math.min(M.length-1,F+_-1),X=[];for(let V=O;V<=U;V++){let j=(V+1).toString().padStart(4),G=V===F-1?">":" ";X.push(`${G}${j} | ${M[V]}`)}return X.join(`
18
18
  `)}function $E(E,F,_){let M=E.split(`
19
- `),O=Math.max(0,F-_-1),U=Math.min(M.length-1,F+_-1),X="\x1B[90m",V="\x1B[31m",j="\x1B[0m",G=[];for(let q=O;q<=U;q++){let I=(q+1).toString().padStart(4),J=q===F-1,B=J?"\x1B[31m>\x1B[0m":" ",S=J?`\x1B[31m${M[q]}\x1B[0m`:`\x1B[90m${M[q]}`;G.push(`${B}${I}\x1B[0m | ${S}`)}return G.join(`
19
+ `),O=Math.max(0,F-_-1),U=Math.min(M.length-1,F+_-1),X="\x1B[90m",V="\x1B[31m",j="\x1B[0m",G=[];for(let q=O;q<=U;q++){let I=(q+1).toString().padStart(4),J=q===F-1,B=J?"\x1B[31m>\x1B[0m":" ",S=J?`\x1B[31m${M[q]}\x1B[0m`:`\x1B[90m${M[q]}\x1B[0m`;G.push(`${B}\x1B[90m${I}\x1B[0m | ${S}`)}return G.join(`
20
20
  `)}function s(E){return E.replace(/--/g,"- -").replace(/>/g,"&gt;")}function l(E,F){let M=E.substring(0,F).split(`
21
21
  `);return{line:M.length,column:M[M.length-1].length}}function BE(E,F,_){return L({type:E,message:F,code:_,format:"html"}).formatted}function TE(E,F,_,M,O){return L({type:E,message:F,code:O,filePath:_,line:M,format:"console"}).formatted}function AE(E,F,_){let M=_.template.split(`
22
22
  `),O=l(_.template,_.offset),U=`[${E} Error at line ${O.line} in ${_.filePath}]: ${F}
@@ -16,7 +16,7 @@ ${J}`)}if(_.suggestion)q.push(`
16
16
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),q.join("")}function D_(_,D,B){let V=_.split(`
17
17
  `),T=Math.max(0,D-B-1),U=Math.min(V.length-1,D+B-1),G=[];for(let X=T;X<=U;X++){let j=(X+1).toString().padStart(4),q=X===D-1?">":" ";G.push(`${q}${j} | ${V[X]}`)}return G.join(`
18
18
  `)}function V_(_,D,B){let V=_.split(`
19
- `),T=Math.max(0,D-B-1),U=Math.min(V.length-1,D+B-1),G="\x1B[90m",X="\x1B[31m",j="\x1B[0m",q=[];for(let I=T;I<=U;I++){let J=(I+1).toString().padStart(4),Q=I===D-1,$=Q?"\x1B[31m>\x1B[0m":" ",N=Q?`\x1B[31m${V[I]}\x1B[0m`:`\x1B[90m${V[I]}`;q.push(`${$}${J}\x1B[0m | ${N}`)}return q.join(`
19
+ `),T=Math.max(0,D-B-1),U=Math.min(V.length-1,D+B-1),G="\x1B[90m",X="\x1B[31m",j="\x1B[0m",q=[];for(let I=T;I<=U;I++){let J=(I+1).toString().padStart(4),Q=I===D-1,$=Q?"\x1B[31m>\x1B[0m":" ",N=Q?`\x1B[31m${V[I]}\x1B[0m`:`\x1B[90m${V[I]}\x1B[0m`;q.push(`${$}\x1B[90m${J}\x1B[0m | ${N}`)}return q.join(`
20
20
  `)}function P(_){return _.replace(/--/g,"- -").replace(/>/g,"&gt;")}function E(_,D){let V=_.substring(0,D).split(`
21
21
  `);return{line:V.length,column:V[V.length-1].length}}function k_(_,D,B){return L({type:_,message:D,code:B,format:"html"}).formatted}function A_(_,D,B,V,T){return L({type:_,message:D,code:T,filePath:B,line:V,format:"console"}).formatted}function M_(_,D,B){let V=B.template.split(`
22
22
  `),T=E(B.template,B.offset),U=`[${_} Error at line ${T.line} in ${B.filePath}]: ${D}
@@ -16,7 +16,7 @@ ${J}`)}if(_.suggestion)I.push(`
16
16
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),I.join("")}function Z_(_,O,F){let M=_.split(`
17
17
  `),U=Math.max(0,O-F-1),V=Math.min(M.length-1,O+F-1),j=[];for(let X=U;X<=V;X++){let q=(X+1).toString().padStart(4),I=X===O-1?">":" ";j.push(`${I}${q} | ${M[X]}`)}return j.join(`
18
18
  `)}function $_(_,O,F){let M=_.split(`
19
- `),U=Math.max(0,O-F-1),V=Math.min(M.length-1,O+F-1),j="\x1B[90m",X="\x1B[31m",q="\x1B[0m",I=[];for(let G=U;G<=V;G++){let J=(G+1).toString().padStart(4),K=G===O-1,B=K?"\x1B[31m>\x1B[0m":" ",S=K?`\x1B[31m${M[G]}\x1B[0m`:`\x1B[90m${M[G]}`;I.push(`${B}${J}\x1B[0m | ${S}`)}return I.join(`
19
+ `),U=Math.max(0,O-F-1),V=Math.min(M.length-1,O+F-1),j="\x1B[90m",X="\x1B[31m",q="\x1B[0m",I=[];for(let G=U;G<=V;G++){let J=(G+1).toString().padStart(4),K=G===O-1,B=K?"\x1B[31m>\x1B[0m":" ",S=K?`\x1B[31m${M[G]}\x1B[0m`:`\x1B[90m${M[G]}\x1B[0m`;I.push(`${B}\x1B[90m${J}\x1B[0m | ${S}`)}return I.join(`
20
20
  `)}function s(_){return _.replace(/--/g,"- -").replace(/>/g,"&gt;")}function l(_,O){let M=_.substring(0,O).split(`
21
21
  `);return{line:M.length,column:M[M.length-1].length}}function E_(_,O,F){return z({type:_,message:O,code:F,format:"html"}).formatted}function B_(_,O,F,M,U){return z({type:_,message:O,code:U,filePath:F,line:M,format:"console"}).formatted}function T_(_,O,F){let M=F.template.split(`
22
22
  `),U=l(F.template,F.offset),V=`[${_} Error at line ${U.line} in ${F.filePath}]: ${O}
package/dist/i18n.js CHANGED
@@ -58,7 +58,7 @@ ${H}`)}if(q.suggestion)B.push(`
58
58
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),B.join("")}function GJ(q,Q,J){let Z=q.split(`
59
59
  `),$=Math.max(0,Q-J-1),X=Math.min(Z.length-1,Q+J-1),W=[];for(let Y=$;Y<=X;Y++){let V=(Y+1).toString().padStart(4),B=Y===Q-1?">":" ";W.push(`${B}${V} | ${Z[Y]}`)}return W.join(`
60
60
  `)}function BJ(q,Q,J){let Z=q.split(`
61
- `),$=Math.max(0,Q-J-1),X=Math.min(Z.length-1,Q+J-1),W="\x1B[90m",Y="\x1B[31m",V="\x1B[0m",B=[];for(let G=$;G<=X;G++){let H=(G+1).toString().padStart(4),_=G===Q-1,N=_?"\x1B[31m>\x1B[0m":" ",F=_?`\x1B[31m${Z[G]}\x1B[0m`:`\x1B[90m${Z[G]}`;B.push(`${N}${H}\x1B[0m | ${F}`)}return B.join(`
61
+ `),$=Math.max(0,Q-J-1),X=Math.min(Z.length-1,Q+J-1),W="\x1B[90m",Y="\x1B[31m",V="\x1B[0m",B=[];for(let G=$;G<=X;G++){let H=(G+1).toString().padStart(4),_=G===Q-1,N=_?"\x1B[31m>\x1B[0m":" ",F=_?`\x1B[31m${Z[G]}\x1B[0m`:`\x1B[90m${Z[G]}\x1B[0m`;B.push(`${N}\x1B[90m${H}\x1B[0m | ${F}`)}return B.join(`
62
62
  `)}function Dq(q){return q.replace(/--/g,"- -").replace(/>/g,"&gt;")}function Nq(q,Q){let Z=q.substring(0,Q).split(`
63
63
  `);return{line:Z.length,column:Z[Z.length-1].length}}function h(q,Q,J){return s({type:q,message:Q,code:J,format:"html"}).formatted}function HJ(q,Q,J,Z,$){return s({type:q,message:Q,code:$,filePath:J,line:Z,format:"console"}).formatted}function VJ(q,Q,J){let Z=J.template.split(`
64
64
  `),$=Nq(J.template,J.offset),X=`[${q} Error at line ${$.line} in ${J.filePath}]: ${Q}
package/dist/includes.js CHANGED
@@ -2424,7 +2424,7 @@ window.__stx_reactive = (function() {
2424
2424
 
2425
2425
  return { initScope: initScope, reactive: reactive };
2426
2426
  })();
2427
- `}function B8($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;return String(J)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;return JSON.stringify(J)}catch{return X}}),Y}function NG($,Z){if($.length===0)return"";let Y=$.map((X)=>{let Q=JSON.stringify(Object.fromEntries(X.refs)),J=B8(X.stateExpr,Z),G=X.initExpr?B8(X.initExpr,Z):null,K=JSON.stringify(J),q=G?JSON.stringify(G):"null";return`
2427
+ `}function B8($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;return String(J)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,Q)=>{try{let J=x0(Q,Z,!0);if(J===void 0)return X;if(typeof J==="string"){let G=J.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(J)}catch{return X}}),Y}function NG($,Z){if($.length===0)return"";let Y=$.map((X)=>{let Q=JSON.stringify(Object.fromEntries(X.refs)),J=B8(X.stateExpr,Z),G=X.initExpr?B8(X.initExpr,Z):null,K=JSON.stringify(J),q=G?JSON.stringify(G):"null";return`
2428
2428
  (function() {
2429
2429
  var scopeEl = document.querySelector('${X.selector}');
2430
2430
  if (!scopeEl) return;
@@ -4203,6 +4203,13 @@ catch (e2) {
4203
4203
 
4204
4204
  // Known directive names to exclude from generic :attr binding
4205
4205
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
4206
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
4207
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
4208
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
4209
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
4210
+ // a dead duplicate attribute and the real viewBox never updates.
4211
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
4212
+ var SVG_NS = 'http://www.w3.org/2000/svg';
4206
4213
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
4207
4214
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
4208
4215
 
@@ -4227,7 +4234,8 @@ catch (e2) {
4227
4234
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
4228
4235
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
4229
4236
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
4230
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
4237
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
4238
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
4231
4239
  effect(() => {
4232
4240
  const v = evalAttrExpr(value);
4233
4241
  if (v === false || v === null || v === undefined) {
@@ -4606,10 +4614,12 @@ else {
4606
4614
  });
4607
4615
  }
4608
4616
  else if (Array.isArray(value)) {
4609
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
4617
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
4618
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
4610
4619
  }
4611
4620
  else {
4612
- el.className = originalClasses + (value ? ' ' + value : '');
4621
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
4622
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
4613
4623
  }
4614
4624
  });
4615
4625
  }
@@ -6933,10 +6943,10 @@ else {
6933
6943
  var root = scriptEl ? scriptEl.nextElementSibling : null;
6934
6944
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
6935
6945
 
6936
- // SPA fallback: during router navigation, script is appended to <body>
6946
+ // SPA fallback: during router navigation, script is appended to body>
6937
6947
  // (not inside the content container), so nextElementSibling won't find the page content.
6938
6948
  // Only use fallback when we genuinely couldn't find a suitable root element.
6939
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
6949
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
6940
6950
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
6941
6951
  var needsFallback = !root || root === document.body
6942
6952
  || (root && root.tagName === 'SCRIPT');
@@ -7255,7 +7265,7 @@ else {
7255
7265
  mountCallbacks.forEach(fn => fn());
7256
7266
  });
7257
7267
 
7258
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
7268
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
7259
7269
  // top-level element with data-stx (signal-processing.ts marks one element),
7260
7270
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
7261
7271
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -7352,7 +7362,7 @@ else {
7352
7362
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
7353
7363
  });
7354
7364
 
7355
- // Process <head> elements (title, meta) that may contain {{ }} expressions
7365
+ // Process head> elements (title, meta) that may contain {{ }} expressions
7356
7366
  // Use componentScope which now contains variables from processed components
7357
7367
  const headElements = document.querySelectorAll('head title, head meta[content]');
7358
7368
  headElements.forEach(el => {
@@ -7548,7 +7558,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
7548
7558
 
7549
7559
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
7550
7560
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
7551
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
7561
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
7552
7562
  var usedLatestSetup = false;
7553
7563
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
7554
7564
  try {
@@ -7632,7 +7642,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
7632
7642
 
7633
7643
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
7634
7644
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
7635
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
7645
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
7636
7646
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
7637
7647
  if (!container.__stx_scope) {
7638
7648
  // Dispose previous effects on the container (from prior navigation)
@@ -7740,7 +7750,7 @@ ${_}${z}
7740
7750
  return { ${U} };
7741
7751
  }
7742
7752
  if(window.stx)window.stx._latestSetup=${G};
7743
- </script>`,j=$;for(let H of J)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(L,F,O)=>{if(H.includes(F.toLowerCase()))return L;return`<${F}${O} data-stx="${G}">`})}return{output:j,setupCode:B}}function gZ($){let Z=$,Y=[],X=new Set,Q=0,J=0,G=Z.length,K="",q=()=>{J++;let j=!1;while(J<G){let H=Z[J];if(H==="\\"){J+=2;continue}if(H==="["&&!j){j=!0,J++;continue}if(H==="]"&&j){j=!1,J++;continue}if(H==="/"&&!j){J++;while(J<G&&/[gimsuyd]/.test(Z[J]))J++;return}if(H===`
7753
+ </script>`,j=$;for(let H of J)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],L=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,O,V)=>{if(L||H.includes(O.toLowerCase()))return F;return L=!0,`<${O}${V} data-stx="${G}">`})}return{output:j,setupCode:B}}function gZ($){let Z=$,Y=[],X=new Set,Q=0,J=0,G=Z.length,K="",q=()=>{J++;let j=!1;while(J<G){let H=Z[J];if(H==="\\"){J+=2;continue}if(H==="["&&!j){j=!0,J++;continue}if(H==="]"&&j){j=!1,J++;continue}if(H==="/"&&!j){J++;while(J<G&&/[gimsuyd]/.test(Z[J]))J++;return}if(H===`
7744
7754
  `)return;J++}},W=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},z=(j)=>{J++;while(J<G){if(Z[J]==="\\"){J+=2;continue}if(Z[J]===j){J++;return}J++}},U=()=>{J++;while(J<G){if(Z[J]==="\\"){J+=2;continue}if(Z[J]==="`"){J++;return}if(Z[J]==="$"&&Z[J+1]==="{"){J+=2;let j=1;while(J<G&&j>0)if(Z[J]==="{")j++,J++;else if(Z[J]==="}")j--,J++;else if(Z[J]==="'"||Z[J]==='"')z(Z[J]);else if(Z[J]==="`")U();else J++;continue}J++}},_=()=>{if(Z[J]==="/"&&Z[J+1]==="/"){while(J<G&&Z[J]!==`
7745
7755
  `)J++;return!0}if(Z[J]==="/"&&Z[J+1]==="*"){J+=2;while(J<G-1&&!(Z[J]==="*"&&Z[J+1]==="/"))J++;return J+=2,!0}return!1},B=()=>{if(Q!==0)return;let j=Z.slice(J).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(J).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let w=V.trim();if(!w)return;let A=w.indexOf(":"),N=(A>=0?w.slice(A+1).trim():w).split(/[\s=]/)[0];if(N&&!X.has(N))Y.push(N),X.add(N)});return}let L=Z.slice(J).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(L){L[1].split(",").forEach((V)=>{let w=V.trim().replace(/^\.\.\./,"");if(!w)return;let A=w.split(/[\s=]/)[0];if(A&&!X.has(A))Y.push(A),X.add(A)});return}let F=Z.slice(J).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let O=Z.slice(J).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(O){let V=O[1];if(!X.has(V))Y.push(V),X.add(V)}};while(J<G){if(_())continue;if(Z[J]==="'"||Z[J]==='"'){z(Z[J]),K=Z[J-1];continue}if(Z[J]==="`"){U(),K="`";continue}if(Z[J]==="/"&&Z[J+1]!=="/"&&Z[J+1]!=="*"&&W()){q(),K="/";continue}if(Z[J]==="{"){Q++,K="{",J++;continue}if(Z[J]==="}"){Q--,K="}",J++;continue}if(Q===0&&/[a-z]/i.test(Z[J])&&(J===0||/\s|[;{}()]/.test(Z[J-1])))B();if(!/\s/.test(Z[J]))K=Z[J];J++}return Y.join(", ")}async function d7($,Z,Y,X){if(!s$($))return $;let Q=$;if(Z.skipSignalsRuntime)return Q;let{output:J,setupCode:G}=await fZ(Q,Y,X);if(Q=J,Q=await SZ(Q,Z),Q=kZ(Q),G)if(Q.includes("</head>"))Q=Q.replace("</head>",`${G}
7746
7756
  </head>`);else if(Q.includes("<body"))Q=Q.replace(/<body([^>]*)>/,`<body$1>
package/dist/index.js CHANGED
@@ -3849,7 +3849,7 @@ window.__stx_reactive = (function() {
3849
3849
 
3850
3850
  return { initScope: initScope, reactive: reactive };
3851
3851
  })();
3852
- `}function PU($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;return JSON.stringify(Q)}catch{return X}}),Y}function Bw($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=PU(X.stateExpr,Z),G=X.initExpr?PU(X.initExpr,Z):null,K=JSON.stringify(Q),W=G?JSON.stringify(G):"null";return`
3852
+ `}function PU($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=o0(J,Z,!0);if(Q===void 0)return X;if(typeof Q==="string"){let G=Q.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(Q)}catch{return X}}),Y}function Bw($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=PU(X.stateExpr,Z),G=X.initExpr?PU(X.initExpr,Z):null,K=JSON.stringify(Q),W=G?JSON.stringify(G):"null";return`
3853
3853
  (function() {
3854
3854
  var scopeEl = document.querySelector('${X.selector}');
3855
3855
  if (!scopeEl) return;
@@ -5974,6 +5974,13 @@ catch (e2) {
5974
5974
 
5975
5975
  // Known directive names to exclude from generic :attr binding
5976
5976
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
5977
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
5978
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
5979
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
5980
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
5981
+ // a dead duplicate attribute and the real viewBox never updates.
5982
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
5983
+ var SVG_NS = 'http://www.w3.org/2000/svg';
5977
5984
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
5978
5985
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
5979
5986
 
@@ -5998,7 +6005,8 @@ catch (e2) {
5998
6005
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
5999
6006
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
6000
6007
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
6001
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6008
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6009
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
6002
6010
  effect(() => {
6003
6011
  const v = evalAttrExpr(value);
6004
6012
  if (v === false || v === null || v === undefined) {
@@ -6377,10 +6385,12 @@ else {
6377
6385
  });
6378
6386
  }
6379
6387
  else if (Array.isArray(value)) {
6380
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
6388
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
6389
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
6381
6390
  }
6382
6391
  else {
6383
- el.className = originalClasses + (value ? ' ' + value : '');
6392
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
6393
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
6384
6394
  }
6385
6395
  });
6386
6396
  }
@@ -8704,10 +8714,10 @@ else {
8704
8714
  var root = scriptEl ? scriptEl.nextElementSibling : null;
8705
8715
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
8706
8716
 
8707
- // SPA fallback: during router navigation, script is appended to <body>
8717
+ // SPA fallback: during router navigation, script is appended to body>
8708
8718
  // (not inside the content container), so nextElementSibling won't find the page content.
8709
8719
  // Only use fallback when we genuinely couldn't find a suitable root element.
8710
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
8720
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
8711
8721
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
8712
8722
  var needsFallback = !root || root === document.body
8713
8723
  || (root && root.tagName === 'SCRIPT');
@@ -9026,7 +9036,7 @@ else {
9026
9036
  mountCallbacks.forEach(fn => fn());
9027
9037
  });
9028
9038
 
9029
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
9039
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
9030
9040
  // top-level element with data-stx (signal-processing.ts marks one element),
9031
9041
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
9032
9042
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -9123,7 +9133,7 @@ else {
9123
9133
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
9124
9134
  });
9125
9135
 
9126
- // Process <head> elements (title, meta) that may contain {{ }} expressions
9136
+ // Process head> elements (title, meta) that may contain {{ }} expressions
9127
9137
  // Use componentScope which now contains variables from processed components
9128
9138
  const headElements = document.querySelectorAll('head title, head meta[content]');
9129
9139
  headElements.forEach(el => {
@@ -9319,7 +9329,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9319
9329
 
9320
9330
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
9321
9331
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
9322
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
9332
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
9323
9333
  var usedLatestSetup = false;
9324
9334
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
9325
9335
  try {
@@ -9403,7 +9413,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9403
9413
 
9404
9414
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
9405
9415
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
9406
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
9416
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
9407
9417
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
9408
9418
  if (!container.__stx_scope) {
9409
9419
  // Dispose previous effects on the container (from prior navigation)
@@ -9513,7 +9523,7 @@ ${z}${B}
9513
9523
  return { ${_} };
9514
9524
  }
9515
9525
  if(window.stx)window.stx._latestSetup=${G};
9516
- </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(O,F,L)=>{if(H.includes(F.toLowerCase()))return O;return`<${F}${L} data-stx="${G}">`})}return{output:j,setupCode:q}}function Wz($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",W=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9526
+ </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],O=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,L,V)=>{if(O||H.includes(L.toLowerCase()))return F;return O=!0,`<${L}${V} data-stx="${G}">`})}return{output:j,setupCode:q}}function Wz($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",W=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9517
9527
  `)return;Q++}},U=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},B=(j)=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]===j){Q++;return}Q++}},_=()=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]==="`"){Q++;return}if(Z[Q]==="$"&&Z[Q+1]==="{"){Q+=2;let j=1;while(Q<G&&j>0)if(Z[Q]==="{")j++,Q++;else if(Z[Q]==="}")j--,Q++;else if(Z[Q]==="'"||Z[Q]==='"')B(Z[Q]);else if(Z[Q]==="`")_();else Q++;continue}Q++}},z=()=>{if(Z[Q]==="/"&&Z[Q+1]==="/"){while(Q<G&&Z[Q]!==`
9518
9528
  `)Q++;return!0}if(Z[Q]==="/"&&Z[Q+1]==="*"){Q+=2;while(Q<G-1&&!(Z[Q]==="*"&&Z[Q+1]==="/"))Q++;return Q+=2,!0}return!1},q=()=>{if(J!==0)return;let j=Z.slice(Q).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(Q).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let N=V.trim();if(!N)return;let A=N.indexOf(":"),R=(A>=0?N.slice(A+1).trim():N).split(/[\s=]/)[0];if(R&&!X.has(R))Y.push(R),X.add(R)});return}let O=Z.slice(Q).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(O){O[1].split(",").forEach((V)=>{let N=V.trim().replace(/^\.\.\./,"");if(!N)return;let A=N.split(/[\s=]/)[0];if(A&&!X.has(A))Y.push(A),X.add(A)});return}let F=Z.slice(Q).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let L=Z.slice(Q).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(L){let V=L[1];if(!X.has(V))Y.push(V),X.add(V)}};while(Q<G){if(z())continue;if(Z[Q]==="'"||Z[Q]==='"'){B(Z[Q]),K=Z[Q-1];continue}if(Z[Q]==="`"){_(),K="`";continue}if(Z[Q]==="/"&&Z[Q+1]!=="/"&&Z[Q+1]!=="*"&&U()){W(),K="/";continue}if(Z[Q]==="{"){J++,K="{",Q++;continue}if(Z[Q]==="}"){J--,K="}",Q++;continue}if(J===0&&/[a-z]/i.test(Z[Q])&&(Q===0||/\s|[;{}()]/.test(Z[Q-1])))q();if(!/\s/.test(Z[Q]))K=Z[Q];Q++}return Y.join(", ")}async function W9($,Z,Y,X){if(!IZ($))return $;let J=$;if(Z.skipSignalsRuntime)return J;let{output:Q,setupCode:G}=await Kz(J,Y,X);if(J=Q,J=await $z(J,Z),J=e_(J),G)if(J.includes("</head>"))J=J.replace("</head>",`${G}
9519
9529
  </head>`);else if(J.includes("<body"))J=J.replace(/<body([^>]*)>/,`<body$1>
@@ -1783,7 +1783,7 @@ ${W}`)}if($.suggestion)z.push(`
1783
1783
  ${"\x1B[31m"}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${"\x1B[0m"}`),z.join("")}function nK($,Z,Y){let X=$.split(`
1784
1784
  `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G=[];for(let K=J;K<=Q;K++){let q=(K+1).toString().padStart(4),z=K===Z-1?">":" ";G.push(`${z}${q} | ${X[K]}`)}return G.join(`
1785
1785
  `)}function oK($,Z,Y){let X=$.split(`
1786
- `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G="\x1B[90m",K="\x1B[31m",q="\x1B[0m",z=[];for(let U=J;U<=Q;U++){let W=(U+1).toString().padStart(4),_=U===Z-1,B=_?"\x1B[31m>\x1B[0m":" ",j=_?`\x1B[31m${X[U]}\x1B[0m`:`\x1B[90m${X[U]}`;z.push(`${B}${W}\x1B[0m | ${j}`)}return z.join(`
1786
+ `),J=Math.max(0,Z-Y-1),Q=Math.min(X.length-1,Z+Y-1),G="\x1B[90m",K="\x1B[31m",q="\x1B[0m",z=[];for(let U=J;U<=Q;U++){let W=(U+1).toString().padStart(4),_=U===Z-1,B=_?"\x1B[31m>\x1B[0m":" ",j=_?`\x1B[31m${X[U]}\x1B[0m`:`\x1B[90m${X[U]}\x1B[0m`;z.push(`${B}\x1B[90m${W}\x1B[0m | ${j}`)}return z.join(`
1787
1787
  `)}function zZ($){return $.replace(/--/g,"- -").replace(/>/g,"&gt;")}function UZ($,Z){let X=$.substring(0,Z).split(`
1788
1788
  `);return{line:X.length,column:X[X.length-1].length}}function a($,Z,Y){return X3({type:$,message:Z,code:Y,format:"html"}).formatted}function sK($,Z,Y,X,J){return X3({type:$,message:Z,code:J,filePath:Y,line:X,format:"console"}).formatted}function rK($,Z,Y){let X=Y.template.split(`
1789
1789
  `),J=UZ(Y.template,Y.offset),Q=`[${$} Error at line ${J.line} in ${Y.filePath}]: ${Z}
@@ -3756,7 +3756,7 @@ window.__stx_reactive = (function() {
3756
3756
 
3757
3757
  return { initScope: initScope, reactive: reactive };
3758
3758
  })();
3759
- `}function oZ($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=d0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=d0(J,Z,!0);if(Q===void 0)return X;return JSON.stringify(Q)}catch{return X}}),Y}function Jz($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=oZ(X.stateExpr,Z),G=X.initExpr?oZ(X.initExpr,Z):null,K=JSON.stringify(Q),q=G?JSON.stringify(G):"null";return`
3759
+ `}function oZ($,Z){let Y=$.replace(/\{!!([\s\S]*?)!!\}/g,(X,J)=>{try{let Q=d0(J,Z,!0);if(Q===void 0)return X;return String(Q)}catch{return X}});return Y=Y.replace(/\{\{([\s\S]*?)\}\}/g,(X,J)=>{try{let Q=d0(J,Z,!0);if(Q===void 0)return X;if(typeof Q==="string"){let G=Q.trim();if(G.startsWith("{")&&G.endsWith("}")||G.startsWith("[")&&G.endsWith("]"))try{return JSON.parse(G),G}catch{}}return JSON.stringify(Q)}catch{return X}}),Y}function Jz($,Z){if($.length===0)return"";let Y=$.map((X)=>{let J=JSON.stringify(Object.fromEntries(X.refs)),Q=oZ(X.stateExpr,Z),G=X.initExpr?oZ(X.initExpr,Z):null,K=JSON.stringify(Q),q=G?JSON.stringify(G):"null";return`
3760
3760
  (function() {
3761
3761
  var scopeEl = document.querySelector('${X.selector}');
3762
3762
  if (!scopeEl) return;
@@ -5996,6 +5996,13 @@ catch (e2) {
5996
5996
 
5997
5997
  // Known directive names to exclude from generic :attr binding
5998
5998
  var DIRECTIVE_NAMES = {class:1, style:1, text:1, html:1, show:1, model:1, 'if':1, 'for':1, ref:1};
5999
+ // SVG attributes are case-sensitive, but the HTML parser lowercases
6000
+ // prefixed attribute names \u2014 ':viewBox' arrives as ':viewbox' because
6001
+ // the spec's "adjust SVG attributes" step only covers unprefixed names.
6002
+ // Without restoring the canonical casing, setAttribute('viewbox') creates
6003
+ // a dead duplicate attribute and the real viewBox never updates.
6004
+ var SVG_ATTR_CASE = {attributename:'attributeName', attributetype:'attributeType', basefrequency:'baseFrequency', baseprofile:'baseProfile', calcmode:'calcMode', clippathunits:'clipPathUnits', diffuseconstant:'diffuseConstant', edgemode:'edgeMode', filterunits:'filterUnits', glyphref:'glyphRef', gradienttransform:'gradientTransform', gradientunits:'gradientUnits', kernelmatrix:'kernelMatrix', kernelunitlength:'kernelUnitLength', keypoints:'keyPoints', keysplines:'keySplines', keytimes:'keyTimes', lengthadjust:'lengthAdjust', limitingconeangle:'limitingConeAngle', markerheight:'markerHeight', markerunits:'markerUnits', markerwidth:'markerWidth', maskcontentunits:'maskContentUnits', maskunits:'maskUnits', numoctaves:'numOctaves', pathlength:'pathLength', patterncontentunits:'patternContentUnits', patterntransform:'patternTransform', patternunits:'patternUnits', pointsatx:'pointsAtX', pointsaty:'pointsAtY', pointsatz:'pointsAtZ', preservealpha:'preserveAlpha', preserveaspectratio:'preserveAspectRatio', primitiveunits:'primitiveUnits', refx:'refX', refy:'refY', repeatcount:'repeatCount', repeatdur:'repeatDur', requiredextensions:'requiredExtensions', requiredfeatures:'requiredFeatures', specularconstant:'specularConstant', specularexponent:'specularExponent', spreadmethod:'spreadMethod', startoffset:'startOffset', stddeviation:'stdDeviation', stitchtiles:'stitchTiles', surfacescale:'surfaceScale', systemlanguage:'systemLanguage', tablevalues:'tableValues', targetx:'targetX', targety:'targetY', textlength:'textLength', viewbox:'viewBox', viewtarget:'viewTarget', xchannelselector:'xChannelSelector', ychannelselector:'yChannelSelector', zoomandpan:'zoomAndPan'};
6005
+ var SVG_NS = 'http://www.w3.org/2000/svg';
5999
6006
  var EVENT_RE = /^(click|dblclick|mousedown|mouseup|mousemove|mouseenter|mouseleave|keydown|keyup|keypress|input|change|submit|focus|blur|scroll|resize|touchstart|touchend|touchmove|contextmenu|wheel|pointerdown|pointerup|pointermove)/;
6000
6007
  var KEY_MAP = {enter:'Enter', tab:'Tab', escape:'Escape', space:' ', up:'ArrowUp', down:'ArrowDown', left:'ArrowLeft', right:'ArrowRight', 'delete':'Delete', backspace:'Backspace'};
6001
6008
 
@@ -6020,7 +6027,8 @@ catch (e2) {
6020
6027
  if (name.startsWith('@bind:') || name.startsWith('x-bind:')
6021
6028
  || (name.startsWith(':') && !name.startsWith('::') && !DIRECTIVE_NAMES[name.slice(1).split('.')[0]] && !EVENT_RE.test(name.slice(1)))
6022
6029
  || (name.startsWith('x-') && !X_HANDLED[name.split('.')[0]] && !X_HANDLED[name])) {
6023
- const attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6030
+ let attrName = name.startsWith('@bind:') ? name.slice(6) : name.startsWith('x-bind:') ? name.slice(7) : name.startsWith('x-') ? name.slice(2) : name.slice(1);
6031
+ if (el.namespaceURI === SVG_NS && SVG_ATTR_CASE[attrName]) attrName = SVG_ATTR_CASE[attrName];
6024
6032
  effect(() => {
6025
6033
  const v = evalAttrExpr(value);
6026
6034
  if (v === false || v === null || v === undefined) {
@@ -6399,10 +6407,12 @@ else {
6399
6407
  });
6400
6408
  }
6401
6409
  else if (Array.isArray(value)) {
6402
- el.className = originalClasses + ' ' + value.filter(Boolean).join(' ');
6410
+ var _clsArr = originalClasses + ' ' + value.filter(Boolean).join(' ');
6411
+ if (typeof el.className === 'string') el.className = _clsArr; else el.setAttribute('class', _clsArr);
6403
6412
  }
6404
6413
  else {
6405
- el.className = originalClasses + (value ? ' ' + value : '');
6414
+ var _clsStr = originalClasses + (value ? ' ' + value : '');
6415
+ if (typeof el.className === 'string') el.className = _clsStr; else el.setAttribute('class', _clsStr);
6406
6416
  }
6407
6417
  });
6408
6418
  }
@@ -8726,10 +8736,10 @@ else {
8726
8736
  var root = scriptEl ? scriptEl.nextElementSibling : null;
8727
8737
  if (!root && scriptEl) root = scriptEl.previousElementSibling || scriptEl.parentElement;
8728
8738
 
8729
- // SPA fallback: during router navigation, script is appended to <body>
8739
+ // SPA fallback: during router navigation, script is appended to body>
8730
8740
  // (not inside the content container), so nextElementSibling won't find the page content.
8731
8741
  // Only use fallback when we genuinely couldn't find a suitable root element.
8732
- // Do NOT fallback just because the script is in <body> \u2014 layout scripts in <body>
8742
+ // Do NOT fallback just because the script is in body> \u2014 layout scripts in body>
8733
8743
  // with valid siblings (e.g. sidebar <aside>) should use those siblings as root.
8734
8744
  var needsFallback = !root || root === document.body
8735
8745
  || (root && root.tagName === 'SCRIPT');
@@ -9048,7 +9058,7 @@ else {
9048
9058
  mountCallbacks.forEach(fn => fn());
9049
9059
  });
9050
9060
 
9051
- // Multi-root fragment fix: a no-<body> setup page tags only the FIRST
9061
+ // Multi-root fragment fix: a no-body> setup page tags only the FIRST
9052
9062
  // top-level element with data-stx (signal-processing.ts marks one element),
9053
9063
  // so sibling root elements were orphaned \u2014 their :if / :for / {{ }} / x-text
9054
9064
  // never hydrated, which read as "{{ }} doesn't work under :if/:for". The
@@ -9145,7 +9155,7 @@ else {
9145
9155
  el.querySelectorAll('[x-cloak]').forEach(function(c) { c.removeAttribute('x-cloak'); });
9146
9156
  });
9147
9157
 
9148
- // Process <head> elements (title, meta) that may contain {{ }} expressions
9158
+ // Process head> elements (title, meta) that may contain {{ }} expressions
9149
9159
  // Use componentScope which now contains variables from processed components
9150
9160
  const headElements = document.querySelectorAll('head title, head meta[content]');
9151
9161
  headElements.forEach(el => {
@@ -9341,7 +9351,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9341
9351
 
9342
9352
  // Apply new page's SFC setup function. During SPA navigation, re-executed page
9343
9353
  // scripts set window.stx._latestSetup to the new setup function. This takes priority
9344
- // over the stale data-stx attribute on <body> (which has the PREVIOUS page's function name).
9354
+ // over the stale data-stx attribute on body> (which has the PREVIOUS page's function name).
9345
9355
  var usedLatestSetup = false;
9346
9356
  if (window.stx._latestSetup && typeof window.stx._latestSetup === 'function') {
9347
9357
  try {
@@ -9425,7 +9435,7 @@ catch (e) { console.warn('[stx] destroy callback error:', e); }
9425
9435
 
9426
9436
  // Process the container content \u2014 bind {{ }}, :attr, @event directives.
9427
9437
  // Run synchronously (not in setTimeout) so componentScope is captured correctly.
9428
- // The DOMContentLoaded path processes <body> synchronously \u2014 the SPA path must match.
9438
+ // The DOMContentLoaded path processes body> synchronously \u2014 the SPA path must match.
9429
9439
  console.log('[stx:load] container:', container.tagName, '__stx_scope:', !!container.__stx_scope, 'scope keys:', Object.keys(componentScope).slice(0, 10));
9430
9440
  if (!container.__stx_scope) {
9431
9441
  // Dispose previous effects on the container (from prior navigation)
@@ -9535,7 +9545,7 @@ ${_}${U}
9535
9545
  return { ${W} };
9536
9546
  }
9537
9547
  if(window.stx)window.stx._latestSetup=${G};
9538
- </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"];j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/i,(L,F,O)=>{if(H.includes(F.toLowerCase()))return L;return`<${F}${O} data-stx="${G}">`})}return{output:j,setupCode:B}}function AX($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",q=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9548
+ </script>`,j=$;for(let H of Q)j=j.split(H.fullMatch).join("");if(j.includes("<body"))j=j.replace(/<body([^>]*)>/,`<body$1 data-stx="${G}">`);else{let H=["script","style","html","head","meta","link","title","!doctype"],L=!1;j=j.replace(/<([a-zA-Z][a-zA-Z0-9-]*)\b([^>]*)>/gi,(F,O,V)=>{if(L||H.includes(O.toLowerCase()))return F;return L=!0,`<${O}${V} data-stx="${G}">`})}return{output:j,setupCode:B}}function AX($){let Z=$,Y=[],X=new Set,J=0,Q=0,G=Z.length,K="",q=()=>{Q++;let j=!1;while(Q<G){let H=Z[Q];if(H==="\\"){Q+=2;continue}if(H==="["&&!j){j=!0,Q++;continue}if(H==="]"&&j){j=!1,Q++;continue}if(H==="/"&&!j){Q++;while(Q<G&&/[gimsuyd]/.test(Z[Q]))Q++;return}if(H===`
9539
9549
  `)return;Q++}},z=()=>{if(!K)return!0;if(/[\w)\]]/.test(K))return!1;return!0},U=(j)=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]===j){Q++;return}Q++}},W=()=>{Q++;while(Q<G){if(Z[Q]==="\\"){Q+=2;continue}if(Z[Q]==="`"){Q++;return}if(Z[Q]==="$"&&Z[Q+1]==="{"){Q+=2;let j=1;while(Q<G&&j>0)if(Z[Q]==="{")j++,Q++;else if(Z[Q]==="}")j--,Q++;else if(Z[Q]==="'"||Z[Q]==='"')U(Z[Q]);else if(Z[Q]==="`")W();else Q++;continue}Q++}},_=()=>{if(Z[Q]==="/"&&Z[Q+1]==="/"){while(Q<G&&Z[Q]!==`
9540
9550
  `)Q++;return!0}if(Z[Q]==="/"&&Z[Q+1]==="*"){Q+=2;while(Q<G-1&&!(Z[Q]==="*"&&Z[Q+1]==="/"))Q++;return Q+=2,!0}return!1},B=()=>{if(J!==0)return;let j=Z.slice(Q).match(/^(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*=/);if(j){let V=j[2];if(!X.has(V))Y.push(V),X.add(V);return}let H=Z.slice(Q).match(/^(?:const|let|var)\s+\{([^}]+)\}\s*=/);if(H){H[1].split(",").forEach((V)=>{let A=V.trim();if(!A)return;let w=A.indexOf(":"),N=(w>=0?A.slice(w+1).trim():A).split(/[\s=]/)[0];if(N&&!X.has(N))Y.push(N),X.add(N)});return}let L=Z.slice(Q).match(/^(?:const|let|var)\s+\[([^\]]+)\]\s*=/);if(L){L[1].split(",").forEach((V)=>{let A=V.trim().replace(/^\.\.\./,"");if(!A)return;let w=A.split(/[\s=]/)[0];if(w&&!X.has(w))Y.push(w),X.add(w)});return}let F=Z.slice(Q).match(/^function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(F){let V=F[1];if(!X.has(V))Y.push(V),X.add(V);return}let O=Z.slice(Q).match(/^async\s+function\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/);if(O){let V=O[1];if(!X.has(V))Y.push(V),X.add(V)}};while(Q<G){if(_())continue;if(Z[Q]==="'"||Z[Q]==='"'){U(Z[Q]),K=Z[Q-1];continue}if(Z[Q]==="`"){W(),K="`";continue}if(Z[Q]==="/"&&Z[Q+1]!=="/"&&Z[Q+1]!=="*"&&z()){q(),K="/";continue}if(Z[Q]==="{"){J++,K="{",Q++;continue}if(Z[Q]==="}"){J--,K="}",Q++;continue}if(J===0&&/[a-z]/i.test(Z[Q])&&(Q===0||/\s|[;{}()]/.test(Z[Q-1])))B();if(!/\s/.test(Z[Q]))K=Z[Q];Q++}return Y.join(", ")}async function r6($,Z,Y,X){if(!i4($))return $;let J=$;if(Z.skipSignalsRuntime)return J;let{output:Q,setupCode:G}=await wX(J,Y,X);if(J=Q,J=await _X(J,Z),J=WX(J),G)if(J.includes("</head>"))J=J.replace("</head>",`${G}
9541
9551
  </head>`);else if(J.includes("<body"))J=J.replace(/<body([^>]*)>/,`<body$1>