studiograph 1.3.48-next.261 → 1.3.48-next.263

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 (114) hide show
  1. package/dist/agent/prompts/system.md +2 -2
  2. package/dist/agent/skills/artifact-canvas/skill.md +25 -37
  3. package/dist/agent/skills/paged-documents/skill.md +74 -104
  4. package/dist/agent/tools/artifact-tools.js +1 -1
  5. package/dist/agent/tools/artifact-tools.js.map +1 -1
  6. package/dist/core/artifact-columns-css.d.ts +38 -0
  7. package/dist/core/artifact-columns-css.js +157 -0
  8. package/dist/core/artifact-columns-css.js.map +1 -0
  9. package/dist/core/artifact-frame-document.d.ts +57 -15
  10. package/dist/core/artifact-frame-document.js +396 -356
  11. package/dist/core/artifact-frame-document.js.map +1 -1
  12. package/dist/core/artifact-frame-model.d.ts +42 -1
  13. package/dist/core/artifact-frame-model.js +102 -1
  14. package/dist/core/artifact-frame-model.js.map +1 -1
  15. package/dist/mcp/tools.js +8 -8
  16. package/dist/mcp/tools.js.map +1 -1
  17. package/dist/server/routes/artifact-export-api.js +2 -3
  18. package/dist/server/routes/artifact-export-api.js.map +1 -1
  19. package/dist/server/routes/chat-turn-outcome.d.ts +36 -0
  20. package/dist/server/routes/chat-turn-outcome.js +17 -0
  21. package/dist/server/routes/chat-turn-outcome.js.map +1 -0
  22. package/dist/services/artifact-library-sources.d.ts +1 -6
  23. package/dist/services/artifact-library-sources.js +1 -9
  24. package/dist/services/artifact-library-sources.js.map +1 -1
  25. package/dist/services/artifact-render-export.d.ts +3 -3
  26. package/dist/services/artifact-render-export.js +57 -50
  27. package/dist/services/artifact-render-export.js.map +1 -1
  28. package/dist/web/_app/immutable/chunks/{Cg7m1gqN.js → 1Av0cjjM.js} +1 -1
  29. package/dist/web/_app/immutable/chunks/7C_XQ_V22.js +949 -0
  30. package/dist/web/_app/immutable/chunks/{Bpmx7Umc.js → 7dxFJmtT.js} +1 -1
  31. package/dist/web/_app/immutable/chunks/{CR1JY_cb.js → B3TQ2v3O.js} +1 -1
  32. package/dist/web/_app/immutable/chunks/{CZBW5wi82.js → BKJo_vcH2.js} +1 -1
  33. package/dist/web/_app/immutable/chunks/{Cx5IiiDO2.js → BLjaRsry2.js} +1 -1
  34. package/dist/web/_app/immutable/chunks/{snCOoD78.js → BWM7Fyds.js} +1 -1
  35. package/dist/web/_app/immutable/chunks/{CQl_RUVN2.js → BZrDj1Yc2.js} +1 -1
  36. package/dist/web/_app/immutable/chunks/{D0_Iu3Uj.js → B_EIjYsb.js} +1 -1
  37. package/dist/web/_app/immutable/chunks/{DaB0hU8_.js → BaVciYXp.js} +1 -1
  38. package/dist/web/_app/immutable/chunks/{CQW66fYJ.js → BkWTUZUm.js} +1 -1
  39. package/dist/web/_app/immutable/chunks/{BU5TCj7m.js → BzEpkiVx.js} +1 -1
  40. package/dist/web/_app/immutable/chunks/{CkivrILi.js → CFQ_EH_P.js} +1 -1
  41. package/dist/web/_app/immutable/chunks/CL_APTyv.js +1 -0
  42. package/dist/web/_app/immutable/chunks/{2z2ekE6D2.js → COK5qG3L2.js} +2 -2
  43. package/dist/web/_app/immutable/chunks/{BIeOkmiV.js → CRwWneZ-.js} +1 -1
  44. package/dist/web/_app/immutable/chunks/{1QRy7-wo.js → CW2H4JII.js} +1 -1
  45. package/dist/web/_app/immutable/chunks/{pPsy4008.js → CWeviCpk.js} +1 -1
  46. package/dist/web/_app/immutable/chunks/{DMFH9Cnt2.js → CXOqnNsj2.js} +1 -1
  47. package/dist/web/_app/immutable/chunks/{oIZupUnz.js → CX_WuP2f.js} +1 -1
  48. package/dist/web/_app/immutable/chunks/{BIwe25Lk.js → CY5xLE5F.js} +1 -1
  49. package/dist/web/_app/immutable/chunks/{D-vvXTU3.js → CeUT6lMf.js} +2 -2
  50. package/dist/web/_app/immutable/chunks/{B5UH1FNe.js → CgmH6rPv.js} +3 -3
  51. package/dist/web/_app/immutable/chunks/{-Tbr-96c2.js → CkOWeGhc2.js} +1 -1
  52. package/dist/web/_app/immutable/chunks/{K5YHt1WL2.js → CkPu5VTd2.js} +1 -1
  53. package/dist/web/_app/immutable/chunks/ClSRVrsW.js +1 -0
  54. package/dist/web/_app/immutable/chunks/{CcgYvk_3.js → Cmq7bKUh.js} +1 -1
  55. package/dist/web/_app/immutable/chunks/{F5xZdLlB.js → CnR_G-ce.js} +1 -1
  56. package/dist/web/_app/immutable/chunks/{CuYL65Bn.js → CzSx91mJ.js} +1 -1
  57. package/dist/web/_app/immutable/chunks/D-a94Hdg.js +1 -0
  58. package/dist/web/_app/immutable/chunks/DAcMjPms.js +2 -0
  59. package/dist/web/_app/immutable/chunks/{B06uE1qJ.js → DC2fTKy0.js} +1 -1
  60. package/dist/web/_app/immutable/chunks/{atFSAfcd2.js → DDfqLzbz2.js} +2 -2
  61. package/dist/web/_app/immutable/chunks/{DhD1HF7R.js → DFLuHkej.js} +1 -1
  62. package/dist/web/_app/immutable/chunks/{PwUOTfSv.js → DOZR4-gy.js} +1 -1
  63. package/dist/web/_app/immutable/chunks/DO_V9Cgc.js +1 -0
  64. package/dist/web/_app/immutable/chunks/{Cxdio_Al.js → DPI7dnke.js} +3 -3
  65. package/dist/web/_app/immutable/chunks/{CG8YKaqc.js → DVcmIzo2.js} +1 -1
  66. package/dist/web/_app/immutable/chunks/DZ2Zr5zb.js +1 -0
  67. package/dist/web/_app/immutable/chunks/{ChS3kWO-.js → DiGsqyRs.js} +1 -1
  68. package/dist/web/_app/immutable/chunks/{CKwV6HKc.js → DmzyKw-k.js} +1 -1
  69. package/dist/web/_app/immutable/chunks/Dvj33Rn2.js +1 -0
  70. package/dist/web/_app/immutable/chunks/{B9VQbssY.js → MDb5bFUr.js} +1 -1
  71. package/dist/web/_app/immutable/chunks/mYfi0ijf2.js +66 -0
  72. package/dist/web/_app/immutable/chunks/{CuatNdzp.js → nkOOikT2.js} +1 -1
  73. package/dist/web/_app/immutable/chunks/{CLninaDG2.js → qU6V8dVT2.js} +2 -2
  74. package/dist/web/_app/immutable/chunks/{DtXJCaQc2.js → qtwjrlYo2.js} +1 -1
  75. package/dist/web/_app/immutable/chunks/{B3u4QMoU.js → vR5HiNz9.js} +1 -1
  76. package/dist/web/_app/immutable/chunks/{7l950wkn.js → xhwwouQZ.js} +1 -1
  77. package/dist/web/_app/immutable/chunks/{BBrP9GiZ.js → yKBXs2Vl.js} +1 -1
  78. package/dist/web/_app/immutable/chunks/{sUAtda6y2.js → zMLQbXeR2.js} +1 -1
  79. package/dist/web/_app/immutable/entry/{app.1tcNTKI-.js → app.CRvuxoVJ.js} +2 -2
  80. package/dist/web/_app/immutable/entry/start.CRSlQSAo.js +1 -0
  81. package/dist/web/_app/immutable/nodes/{0.v0W5DL7W.js → 0.DCtO9hJz.js} +2 -2
  82. package/dist/web/_app/immutable/nodes/{1.81Rb3Ith.js → 1.CU0Xk0hX.js} +1 -1
  83. package/dist/web/_app/immutable/nodes/{10.CAlZNFOq.js → 10.BQ_I0U3h.js} +1 -1
  84. package/dist/web/_app/immutable/nodes/{11.CCfUginI.js → 11.D8W7J9oj.js} +1 -1
  85. package/dist/web/_app/immutable/nodes/{12.BJLboAyk.js → 12.shu8hSiJ.js} +1 -1
  86. package/dist/web/_app/immutable/nodes/{13.Cz4UTl2G.js → 13.CqSie9pj.js} +1 -1
  87. package/dist/web/_app/immutable/nodes/15.CRTNtmaK.js +1 -0
  88. package/dist/web/_app/immutable/nodes/{16.BjohAUt9.js → 16.CLnfWtVJ.js} +1 -1
  89. package/dist/web/_app/immutable/nodes/{18.DsOT0tDo.js → 18.L6u3xca6.js} +1 -1
  90. package/dist/web/_app/immutable/nodes/{19.BiJWLOUT.js → 19.BfT4fpP2.js} +1 -1
  91. package/dist/web/_app/immutable/nodes/{2.Cd72nG2V.js → 2.Cywkr3cW.js} +4 -4
  92. package/dist/web/_app/immutable/nodes/{3.BIT9mm9r.js → 3.C5-yIMEM.js} +1 -1
  93. package/dist/web/_app/immutable/nodes/{4.Cn7r0Poe.js → 4.LWwxRkzM.js} +3 -3
  94. package/dist/web/_app/immutable/nodes/{5.CkJNdCZG.js → 5.CwRllvWS.js} +1 -1
  95. package/dist/web/_app/immutable/nodes/{6.1rbIRQgQ.js → 6.BcR9vQIF.js} +1 -1
  96. package/dist/web/_app/immutable/nodes/{7.w17Zl36i.js → 7.Bm0Ie3c3.js} +1 -1
  97. package/dist/web/_app/immutable/nodes/{8.DqTsYuU-.js → 8.Dj0JJcTw.js} +1 -1
  98. package/dist/web/_app/immutable/nodes/{9.BJhYZPfc.js → 9.9MiRRKIu.js} +1 -1
  99. package/dist/web/_app/version.json +1 -1
  100. package/dist/web/index.html +14 -14
  101. package/package.json +1 -2
  102. package/dist/web/_app/immutable/chunks/9Sn2PwSn2.js +0 -1025
  103. package/dist/web/_app/immutable/chunks/AFZSy-Vk.js +0 -2
  104. package/dist/web/_app/immutable/chunks/B4PrlkmE.js +0 -1
  105. package/dist/web/_app/immutable/chunks/C85NG5lS.js +0 -1
  106. package/dist/web/_app/immutable/chunks/CJbr-v9X.js +0 -1
  107. package/dist/web/_app/immutable/chunks/D4vfNy_f.js +0 -1
  108. package/dist/web/_app/immutable/chunks/DG7uGoZb2.js +0 -58
  109. package/dist/web/_app/immutable/chunks/DTOO9nUj.js +0 -1
  110. package/dist/web/_app/immutable/chunks/Dav8Lgyy2.js +0 -5
  111. package/dist/web/_app/immutable/chunks/DjXtgWTP.js +0 -1
  112. package/dist/web/_app/immutable/entry/start.BJMsySI1.js +0 -1
  113. package/dist/web/_app/immutable/nodes/15.D2mNE6C-.js +0 -1
  114. /package/dist/web/_app/immutable/chunks/{Oglnp7sm.js → Oglnp7sm2.js} +0 -0
@@ -0,0 +1,949 @@
1
+ import{B as e,Ft as t,G as n,Ht as r,I as i,J as a,K as o,P as s,Pt as c,R as l,S as u,T as d,V as f,Vt as p,W as m,X as h,Z as g,_,a as v,at as y,ct as b,d as ee,et as te,ft as ne,g as re,gt as x,ht as S,j as ie,mt as ae,n as oe,o as C,ot as w,p as se,pt as T,st as E,u as ce,v as D,vt as O,wt as k,x as le,xt as A,yt as j,z as ue}from"./FISIvbqq.js";import{t as M}from"./kNaey6uv.js";import"./xihTtKlq.js";import{R as de,o as fe,z as pe}from"./nqo2e2Yv.js";import{t as me}from"./BWM7Fyds.js";import{n as he}from"./BEyPhM3C.js";import{t as ge}from"./CgOgBK5j.js";import"./CWIHttTH.js";import{n as N,r as _e,t as P}from"./DAcMjPms.js";import{t as ve}from"./DIsSxB_C.js";import{i as ye,n as be,r as xe,t as Se}from"./DPLkAijI2.js";var Ce=f(`<title> </title>`),we=f(`<svg><!><path d="M27.34,12.06l-22-8A1,1,0,0,0,4.06,5.34l8,22A1,1,0,0,0,13,28h0a1,1,0,0,0,.93-.63l3.84-9.6,9.6-3.84a1,1,0,0,0,0-1.87Zm-10.71,4h0l-.4.16-.16.4h0L13,24.2,6.67,6.67,24.2,13Z"></path></svg>`);function Te(e,n){let a=v(n,[`children`,`$$slots`,`$$events`,`$$legacy`]),o=v(a,[`size`,`title`]);t(n,!1);let u=O(),d=O(),f=C(n,`size`,8,16),m=C(n,`title`,8,void 0);y(()=>(h(a),h(m())),()=>{j(u,a[`aria-label`]||a[`aria-labelledby`]||m())}),y(()=>(g(u),h(a)),()=>{j(d,{"aria-hidden":g(u)?void 0:!0,role:g(u)?`img`:void 0,focusable:Number(a.tabindex)===0?!0:void 0})}),w(),ce();var _=we();re(_,()=>({xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 32`,fill:`currentColor`,preserveAspectRatio:`xMidYMid meet`,width:f(),height:f(),...g(d),...o}));var b=T(_),ee=e=>{var t=Ce(),n=T(t,!0);r(t),E(()=>i(n,m())),l(e,t)};s(b,e=>{m()&&e(ee)}),p(),r(_),l(e,_),c()}var Ee=f(`<title> </title>`),De=f(`<svg><!><path d="M27.01 12 25.6 13.41 28.18 16 25.59 18.59 27.01 20 31.01 16 27.01 12z"></path><path d="M6.41 13.42 5 12 1 16 5 20 6.42 18.59 3.83 16 6.41 13.42z"></path><path d="M16 28.17 13.41 25.58 12 27 16 31 20 27 18.59 25.59 16 28.17z"></path><path d="M16 3.83 18.58 6.41 20 5 16 1 12 5 13.41 6.42 16 3.83z"></path><path d="M22,16a6,6,0,1,0-2.53,4.89l3.82,3.82,1.42-1.42-3.82-3.82A6,6,0,0,0,22,16Zm-6,4a4,4,0,1,1,4-4A4,4,0,0,1,16,20Z"></path></svg>`);function Oe(e,n){let a=v(n,[`children`,`$$slots`,`$$events`,`$$legacy`]),o=v(a,[`size`,`title`]);t(n,!1);let u=O(),d=O(),f=C(n,`size`,8,16),m=C(n,`title`,8,void 0);y(()=>(h(a),h(m())),()=>{j(u,a[`aria-label`]||a[`aria-labelledby`]||m())}),y(()=>(g(u),h(a)),()=>{j(d,{"aria-hidden":g(u)?void 0:!0,role:g(u)?`img`:void 0,focusable:Number(a.tabindex)===0?!0:void 0})}),w(),ce();var _=De();re(_,()=>({xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 32`,fill:`currentColor`,preserveAspectRatio:`xMidYMid meet`,width:f(),height:f(),...g(d),...o}));var b=T(_),ee=e=>{var t=Ee(),n=T(t,!0);r(t),E(()=>i(n,m())),l(e,t)};s(b,e=>{m()&&e(ee)}),p(5),r(_),l(e,_),c()}var ke=f(`<title> </title>`),F=f(`<svg><!><path d="M18,28A12,12,0,1,0,6,16v6.2L2.4,18.6,1,20l6,6,6-6-1.4-1.4L8,22.2V16H8A10,10,0,1,1,18,26Z"></path></svg>`);function Ae(e,n){let a=v(n,[`children`,`$$slots`,`$$events`,`$$legacy`]),o=v(a,[`size`,`title`]);t(n,!1);let u=O(),d=O(),f=C(n,`size`,8,16),m=C(n,`title`,8,void 0);y(()=>(h(a),h(m())),()=>{j(u,a[`aria-label`]||a[`aria-labelledby`]||m())}),y(()=>(g(u),h(a)),()=>{j(d,{"aria-hidden":g(u)?void 0:!0,role:g(u)?`img`:void 0,focusable:Number(a.tabindex)===0?!0:void 0})}),w(),ce();var _=F();re(_,()=>({xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 32`,fill:`currentColor`,preserveAspectRatio:`xMidYMid meet`,width:f(),height:f(),...g(d),...o}));var b=T(_),ee=e=>{var t=ke(),n=T(t,!0);r(t),E(()=>i(n,m())),l(e,t)};s(b,e=>{m()&&e(ee)}),p(),r(_),l(e,_),c()}var je=f(`<title> </title>`),I=f(`<svg><!><path d="M18 12 14 12 14 8 12 8 12 12 8 12 8 14 12 14 12 18 14 18 14 14 18 14 18 12z"></path><path d="M21.4479,20A10.856,10.856,0,0,0,24,13,11,11,0,1,0,13,24a10.856,10.856,0,0,0,7-2.5521L27.5859,29,29,27.5859ZM13,22a9,9,0,1,1,9-9A9.01,9.01,0,0,1,13,22Z"></path></svg>`);function Me(e,n){let a=v(n,[`children`,`$$slots`,`$$events`,`$$legacy`]),o=v(a,[`size`,`title`]);t(n,!1);let u=O(),d=O(),f=C(n,`size`,8,16),m=C(n,`title`,8,void 0);y(()=>(h(a),h(m())),()=>{j(u,a[`aria-label`]||a[`aria-labelledby`]||m())}),y(()=>(g(u),h(a)),()=>{j(d,{"aria-hidden":g(u)?void 0:!0,role:g(u)?`img`:void 0,focusable:Number(a.tabindex)===0?!0:void 0})}),w(),ce();var _=I();re(_,()=>({xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 32`,fill:`currentColor`,preserveAspectRatio:`xMidYMid meet`,width:f(),height:f(),...g(d),...o}));var b=T(_),ee=e=>{var t=je(),n=T(t,!0);r(t),E(()=>i(n,m())),l(e,t)};s(b,e=>{m()&&e(ee)}),p(2),r(_),l(e,_),c()}var L=f(`<title> </title>`),R=f(`<svg><!><path d="M8 12H18V14H8z"></path><path d="M21.4479,20A10.856,10.856,0,0,0,24,13,11,11,0,1,0,13,24a10.856,10.856,0,0,0,7-2.5521L27.5859,29,29,27.5859ZM13,22a9,9,0,1,1,9-9A9.01,9.01,0,0,1,13,22Z"></path></svg>`);function Ne(e,n){let a=v(n,[`children`,`$$slots`,`$$events`,`$$legacy`]),o=v(a,[`size`,`title`]);t(n,!1);let u=O(),d=O(),f=C(n,`size`,8,16),m=C(n,`title`,8,void 0);y(()=>(h(a),h(m())),()=>{j(u,a[`aria-label`]||a[`aria-labelledby`]||m())}),y(()=>(g(u),h(a)),()=>{j(d,{"aria-hidden":g(u)?void 0:!0,role:g(u)?`img`:void 0,focusable:Number(a.tabindex)===0?!0:void 0})}),w(),ce();var _=R();re(_,()=>({xmlns:`http://www.w3.org/2000/svg`,viewBox:`0 0 32 32`,fill:`currentColor`,preserveAspectRatio:`xMidYMid meet`,width:f(),height:f(),...g(d),...o}));var b=T(_),ee=e=>{var t=L(),n=T(t,!0);r(t),E(()=>i(n,m())),l(e,t)};s(b,e=>{m()&&e(ee)}),p(2),r(_),l(e,_),c()}var z=6,Pe=720,Fe=1280,Ie=800;function Le(e,t){return e.geometry.width===`fill`?Math.round(t?.width||Fe):e.geometry.width}function Re(e,t,n=Pe,r){if(e.geometry.height===`fill`)return Math.round(r?.height||Ie);if(e.geometry.height!==`auto`)return e.geometry.height;let i=t?.[e.id];return i&&i>0?Math.round(i):n}function ze(e,t={}){let n=t.gap??64,r=Math.max(1,t.maxColumns??z),i=e.length;if(i===0)return{rects:[],width:0,height:0,columns:0};let a=Math.min(r,Math.max(1,Math.ceil(Math.sqrt(i)))),o=Math.ceil(i/a),s=e.map(e=>Le(e,t.viewport)),c=e.map(e=>Re(e,t.measuredHeights,t.autoHeightFallback,t.viewport)),l=Array(a).fill(0),u=Array(o).fill(0);for(let e=0;e<i;e+=1){let t=e%a,n=Math.floor(e/a);l[t]=Math.max(l[t],s[e]),u[n]=Math.max(u[n],c[e])}let d=Array(a).fill(0);for(let e=1;e<a;e+=1)d[e]=d[e-1]+l[e-1]+n;let f=Array(o).fill(0);for(let e=1;e<o;e+=1)f[e]=f[e-1]+u[e-1]+n;let p=e.map((e,t)=>{let n=t%a,r=Math.floor(t/a),i=s[t],o=c[t],l=d[n],u=f[r];return{id:e.id,x:Math.round(l),y:Math.round(u),width:i,height:o}}),m=d[a-1]+l[a-1],h=f[o-1]+u[o-1];return{rects:p,width:Math.round(m),height:Math.round(h),columns:a}}function Be(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function B(e){return Be(e).replace(/'/g,`&#39;`)}function Ve(e){return e.replace(/<\/script/gi,`<\\/script`)}function He(e){return e.replace(/<\/style/gi,`<\\/style`)}function Ue(e){let t=new TextEncoder().encode(e),n=``,r=32768;for(let e=0;e<t.length;e+=r)n+=String.fromCharCode(...t.slice(e,e+r));return btoa(n)}var V=/(https?:\/\/[^\s"'()<>\/]+)?\/api\/assets\/([A-Za-z0-9._%-]+)\/([A-Za-z0-9._%-]+)(?![A-Za-z0-9._%/-])(\?[^\s"'()<>]*)?/g;function H(e){try{return decodeURIComponent(e)}catch{return e}}function We(e){return encodeURIComponent(e).replace(/[!~*'()]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}function Ge(e){let t=new Map;for(let n of e.matchAll(V)){let e=n[2],r=H(n[3]),i=`${e}/${r}`;t.has(i)||t.set(i,{key:i,assetId:e,filename:r})}return[...t.values()]}function Ke(e,t){let n=encodeURIComponent(t);return e.replace(V,(e,t,r,i,a)=>{let o=`${t??``}/api/assets/${r}/${i}`,s=a?a.slice(1).split(`&`).filter(e=>e&&!/^at=/i.test(e)):[];return s.push(`at=${n}`),`${o}?${s.join(`&`)}`})}function qe(e,t){return e.replace(V,(e,n,r,i)=>{let a=H(i);return t({key:`${r}/${a}`,assetId:r,filename:a},i)??e})}function Je(e,t){return e.replace(V,(e,n,r,i)=>`/api/share/${t}/asset/${r}/${i}`)}function Ye(e){return e.replace(/[&<>"']/g,e=>e===`&`?`&amp;`:e===`<`?`&lt;`:e===`>`?`&gt;`:e===`"`?`&quot;`:`&#39;`)}function Xe(e){return`data:image/svg+xml,${We(`<svg xmlns="http://www.w3.org/2000/svg" width="640" height="360" viewBox="0 0 640 360"><rect width="640" height="360" fill="#f4f4f4"/><rect x="0.5" y="0.5" width="639" height="359" fill="none" stroke="#d0d0d0"/><g fill="#8a8a8a" font-family="system-ui, -apple-system, sans-serif" text-anchor="middle"><text x="320" y="168" font-size="15">Image not included in export</text><text x="320" y="196" font-size="13">${Ye(e.length>48?`${e.slice(0,45)}…`:e)}</text></g></svg>`)}`}function Ze(e,t=`./assets`,n={}){let r=t.replace(/\/+$/,``);return e.replace(V,(e,t,i,a)=>{let o=H(a);return!n.bundledKeys||n.bundledKeys.has(`${i}/${o}`)?`${r}/${i}/${a}`:Xe(o)})}function Qe(e){try{let t=new URL(e);return t.protocol!==`http:`&&t.protocol!==`https:`?null:t.origin}catch{return null}}var U=/^[A-Za-z0-9._-]+$/;function $e(e){return e.length>0&&U.test(e)}function et(e){switch(e.mode){case`token`:{let t=Qe(e.origin);return t?[`${t}/api/assets/`]:[]}case`share`:{let t=Qe(e.origin);return!t||!$e(e.shareToken)?[]:[`${t}/api/share/${e.shareToken}/asset/`]}case`relative`:return[`file:`];case`none`:return[]}}function tt(e={mode:`none`},t={}){let n=et(e),r=e=>n.length?`${e} ${n.join(` `)}`:e,i=t.allowBaseOrigin?Qe(t.allowBaseOrigin):null;return[`default-src 'none'`,i?`base-uri ${i}`:`base-uri 'none'`,`connect-src 'none'`,r(`font-src data: blob:`),`form-action 'none'`,`frame-src 'none'`,r(`img-src data: blob:`),r(`media-src data: blob:`),`object-src 'none'`,`script-src 'unsafe-inline' blob:`,`style-src 'unsafe-inline'`].join(`; `)}function nt(e,t={mode:`none`}){switch(t.mode){case`token`:return t.token?Ke(e,t.token):e;case`share`:return $e(t.shareToken)?Je(e,t.shareToken):e;case`relative`:return Ze(e,`./assets`,{bundledKeys:t.bundledKeys});case`none`:return e}}function rt(e,t={}){if(e.length===0)return``;let n=[];for(let r of e)if(r===`d3`||r===`motion`){let e=t[r];if(!e)continue;n.push(`<script data-artifact-library="${r}">\n${Ve(e)}\n<\/script>`)}let r=[];return e.includes(`three`)&&t.three&&r.push(`
2
+ const decodeLibrarySource = (base64) => {
3
+ const binary = atob(base64);
4
+ const bytes = new Uint8Array(binary.length);
5
+ for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);
6
+ return new TextDecoder().decode(bytes);
7
+ };
8
+ const threeSource = decodeLibrarySource(${JSON.stringify(Ue(t.three))});
9
+ const threeCoreSource = ${t.threeCore?`decodeLibrarySource(${JSON.stringify(Ue(t.threeCore))})`:`''`};
10
+ const threeCoreUrl = threeCoreSource
11
+ ? URL.createObjectURL(new Blob([threeCoreSource], { type: 'text/javascript' }))
12
+ : null;
13
+ const threeModuleSource = threeCoreUrl
14
+ ? threeSource.replace(/from\\s*(['"])\\.\\/three\\.core\\.min\\.js\\1/g, 'from ' + JSON.stringify(threeCoreUrl))
15
+ : threeSource;
16
+ const threeUrl = URL.createObjectURL(new Blob([threeModuleSource], { type: 'text/javascript' }));
17
+ try {
18
+ window.THREE = await import(threeUrl);
19
+ } finally {
20
+ URL.revokeObjectURL(threeUrl);
21
+ if (threeCoreUrl) URL.revokeObjectURL(threeCoreUrl);
22
+ }
23
+ `),n.push(`<script data-artifact-libraries-ready>
24
+ window.__STUDIOGRAPH_ARTIFACT_LIBRARIES__ = ${JSON.stringify(e)};
25
+ window.__STUDIOGRAPH_ARTIFACT_LIBRARIES_READY__ = (async () => {
26
+ ${r.join(`
27
+ `)}
28
+ return true;
29
+ })().catch((error) => {
30
+ console.error('Artifact library load failed', error);
31
+ throw error;
32
+ });
33
+ <\/script>`),n.join(`
34
+ `)}function it(){return`<script data-artifact-broken-image>${Ve(`
35
+ (() => {
36
+ var MESSAGE = 'Original asset is no longer available';
37
+ var GLYPH = [
38
+ 'M16,30H8a2,2,0,0,1-2-2V4A2,2,0,0,1,8,2h10a1,1,0,0,1,.71.29l5,5A1,1,0,0,1,24,8v6H22V9H17a1,1,0,0,1-1-1V4H8V28h8Z',
39
+ 'M24.5,29A2.5,2.5,0,1,1,27,26.5,2.5,2.5,0,0,1,24.5,29Zm0-3.5a1,1,0,1,0,1,1A1,1,0,0,0,24.5,25.5Z',
40
+ 'M24.5,23a1,1,0,0,1-1-1V21a2.5,2.5,0,1,0-2.5-2.5,1,1,0,0,1-2,0A4.5,4.5,0,1,1,25,22.79V22A1,1,0,0,1,24.5,23Z'
41
+ ];
42
+ var NS = 'http://www.w3.org/2000/svg';
43
+ function replace(img) {
44
+ try {
45
+ if (!img || img.tagName !== 'IMG' || img.hasAttribute('data-sg-broken')) return;
46
+ if (img.complete && img.naturalWidth > 0) return; // recovered (e.g. a retry swapped src)
47
+ img.setAttribute('data-sg-broken', '');
48
+ var cs = window.getComputedStyle ? getComputedStyle(img) : null;
49
+ var rect = img.getBoundingClientRect();
50
+ // getComputedStyle returns a USED px length ("695px") only for a laid-out
51
+ // element. Inside a display:none subtree — an INACTIVE FRAME in present /
52
+ // fullscreen mode — it returns the COMPUTED value verbatim ("100%"),
53
+ // which is not a pixel box; parseFloat("100%") === 100 would bake a bogus
54
+ // 100x100 footprint (the small glyph-only box seen in present mode). So
55
+ // accept a computed length ONLY when it is in px; it still dodges the
56
+ // collapsed broken-img rendered box and the "numeric width attr that CSS
57
+ // overrides" trap. Then a unitless pixel attribute, the rendered box, a
58
+ // default. A percentage means the image fills its slot — mirrored below.
59
+ var pxLen = function (cssVal) {
60
+ if (typeof cssVal === 'string' && /px$/.test(cssVal)) {
61
+ var c = parseFloat(cssVal);
62
+ if (isFinite(c) && c > 1) return Math.round(c);
63
+ }
64
+ return null;
65
+ };
66
+ var dim = function (cssVal, attr, rectVal, dflt) {
67
+ var c = pxLen(cssVal);
68
+ if (c != null) return c;
69
+ if (attr && /^\\s*\\d+(?:\\.\\d+)?\\s*$/.test(attr)) return parseFloat(attr);
70
+ if (rectVal > 1) return Math.round(rectVal);
71
+ return dflt;
72
+ };
73
+ var w = dim(cs && cs.width, img.getAttribute('width'), rect.width, 240);
74
+ var h = dim(cs && cs.height, img.getAttribute('height'), rect.height, 160);
75
+ // Fill case: the computed size is a percentage we could NOT resolve to px
76
+ // (the img lives in a display:none present-mode frame). Mirror the
77
+ // percentage onto the placeholder so it fills the same slot once the frame
78
+ // is revealed + self-fit-scaled, instead of the default box. w/h keep
79
+ // their defaults purely to select the large (glyph+label) tier, since a
80
+ // fill image is content-sized.
81
+ var fillW = (pxLen(cs && cs.width) == null && cs && /%$/.test(cs.width)) ? cs.width : null;
82
+ var fillH = (pxLen(cs && cs.height) == null && cs && /%$/.test(cs.height)) ? cs.height : null;
83
+ var radius = (cs && cs.borderRadius && cs.borderRadius !== '0px') ? cs.borderRadius : '4px';
84
+ // Degrade by available footprint so a tiny broken embed stays tiny instead
85
+ // of blowing out the layout with text it can't hold: large -> glyph +
86
+ // label; small -> glyph only; tiny -> just the box. The aria-label always
87
+ // carries the full message regardless of what is drawn.
88
+ var minDim = w < h ? w : h;
89
+ var showGlyph = minDim >= 40;
90
+ var showText = w >= 130 && h >= 70;
91
+ var pad = showText ? 12 : (showGlyph ? 6 : 0);
92
+ // Block-level images (incl. flex/grid items) get a block-level flex box so
93
+ // full-width layout and margin:auto centering survive; inline images stay
94
+ // inline-flex.
95
+ var disp = (cs && /^inline/.test(cs.display)) ? 'inline-flex' : 'flex';
96
+ var note = document.createElement('div');
97
+ note.setAttribute('data-sg-broken-image', '');
98
+ note.setAttribute('role', 'img');
99
+ var alt = (img.getAttribute('alt') || '').trim();
100
+ note.setAttribute('aria-label', alt ? alt + ' \\u2014 ' + MESSAGE : MESSAGE);
101
+ // width holds the footprint; the text tier uses min-height (not a fixed
102
+ // height) so the label can grow rather than clip, while the glyph/box
103
+ // tiers keep the exact footprint. overflow:hidden only rounds the corners
104
+ // (the grown/exact height always fits whatever is drawn).
105
+ var widthCss = 'width:' + (fillW || (w + 'px')) + ';';
106
+ var heightCss = fillH ? 'height:' + fillH + ';' : (showText ? 'min-height:' + h + 'px;' : 'height:' + h + 'px;');
107
+ note.style.cssText = 'box-sizing:border-box;display:' + disp + ';flex-direction:column;align-items:center;justify-content:center;gap:8px;' + widthCss + heightCss + 'padding:' + pad + 'px;background:rgba(128,128,128,0.12);border:1px solid rgba(128,128,128,0.25);border-radius:' + radius + ';color:rgba(120,120,120,0.95);font:500 13px/1.35 system-ui,-apple-system,sans-serif;text-align:center;overflow:hidden';
108
+ // Preserve the image's placement so a broken absolutely-positioned,
109
+ // floated, centered, or grid/flex-placed image keeps its slot instead of
110
+ // dropping into normal flow and shifting the whole artifact.
111
+ if (cs) {
112
+ var keep = ['position','top','right','bottom','left','transform','transformOrigin','float','marginTop','marginRight','marginBottom','marginLeft','verticalAlign','alignSelf','justifySelf','gridColumn','gridRow'];
113
+ for (var k = 0; k < keep.length; k++) {
114
+ var val = cs[keep[k]];
115
+ if (val && val !== 'auto' && val !== 'normal' && val !== 'static' && val !== 'none' && val !== '0px') {
116
+ try { note.style[keep[k]] = val; } catch (e) {}
117
+ }
118
+ }
119
+ }
120
+ if (showGlyph) {
121
+ var svg = document.createElementNS(NS, 'svg');
122
+ svg.setAttribute('viewBox', '0 0 32 32');
123
+ svg.setAttribute('width', '20');
124
+ svg.setAttribute('height', '20');
125
+ svg.setAttribute('fill', 'currentColor');
126
+ svg.setAttribute('aria-hidden', 'true');
127
+ svg.style.cssText = 'flex:none;opacity:0.85';
128
+ for (var i = 0; i < GLYPH.length; i++) {
129
+ var p = document.createElementNS(NS, 'path');
130
+ p.setAttribute('d', GLYPH[i]);
131
+ svg.appendChild(p);
132
+ }
133
+ note.appendChild(svg);
134
+ }
135
+ if (showText) {
136
+ var label = document.createElement('span');
137
+ label.textContent = MESSAGE;
138
+ label.style.maxWidth = '100%';
139
+ note.appendChild(label);
140
+ }
141
+ var prevDisplay = img.style.display;
142
+ img.style.display = 'none';
143
+ if (img.parentNode) img.parentNode.insertBefore(note, img.nextSibling);
144
+ // Self-heal: if the same <img> later loads (an artifact's own onerror
145
+ // retry swapped src to a working URL), drop the placeholder and restore
146
+ // the image to its PRIOR inline display rather than leave a valid image
147
+ // hidden behind the note.
148
+ img.addEventListener('load', function onload() {
149
+ if (img.naturalWidth > 0) {
150
+ img.removeEventListener('load', onload);
151
+ if (note.parentNode) note.parentNode.removeChild(note);
152
+ img.style.display = prevDisplay;
153
+ img.removeAttribute('data-sg-broken');
154
+ }
155
+ });
156
+ } catch (e) {}
157
+ }
158
+ // Schedule on the window receiver (a detached rAF call can throw in strict
159
+ // contexts) and never let scheduling throw out of the capture listener.
160
+ function defer(fn) {
161
+ try { if (window.requestAnimationFrame) { window.requestAnimationFrame(fn); return; } } catch (e) {}
162
+ try { window.setTimeout(fn, 0); } catch (e) {}
163
+ }
164
+ document.addEventListener('error', function (e) {
165
+ var t = e && e.target;
166
+ // Defer a frame so an artifact's own onerror retry can swap src first; the
167
+ // load-time sweep below still inserts the note synchronously before a
168
+ // headless capture (which waits for load + rAF), so the export never races.
169
+ if (t && t.tagName === 'IMG') defer(function () { replace(t); });
170
+ }, true);
171
+ // Sweep images already broken before the listener registered (cached 404s, or
172
+ // the standalone tag running at body end after parse).
173
+ function sweep() {
174
+ try {
175
+ var imgs = document.querySelectorAll('img');
176
+ for (var i = 0; i < imgs.length; i++) {
177
+ var im = imgs[i];
178
+ if (im.complete && im.naturalWidth === 0 && im.getAttribute('src')) replace(im);
179
+ }
180
+ } catch (e) {}
181
+ }
182
+ // Run once now — catches images already parsed + broken when this tag
183
+ // executes (the standalone tag sits at body end, after the markup), so a
184
+ // user/library script running next sees the placeholder, not the raw broken
185
+ // img. Run again on load for cached 404s that completed before the capture
186
+ // listener registered.
187
+ sweep();
188
+ window.addEventListener('load', sweep);
189
+ })();`)}<\/script>`}var at=/[A-Za-z0-9_-]/,ot=/\s/;function st(e){let t=e=>e.toLowerCase();return e.replace(/(?<![\w-])position\s*:\s*running\([^)]*\)/gi,`display:none`).replace(/(?<![\w-])break-(inside|before|after)\s*:\s*avoid-page\b/gi,(e,n)=>`break-${t(n)}:avoid`).replace(/(?<![\w-])page-break-(before|after)\s*:\s*(?:always|left|right|recto|verso|page)\b/gi,(e,n)=>`break-${t(n)}:column`).replace(/(?<![\w-])page-break-(before|after)\s*:\s*avoid\b/gi,(e,n)=>`break-${t(n)}:avoid`).replace(/(?<![\w-])page-break-inside\s*:\s*avoid\b/gi,`break-inside:avoid`).replace(/(?<![\w-])break-(before|after)\s*:\s*(?:page|always|left|right|recto|verso)\b/gi,(e,n)=>`break-${t(n)}:column`)}function ct(e){if(!e)return e;let t=e.length,n=e=>e!==void 0&&at.test(e),r=e=>e!==void 0&&ot.test(e),i=``,a=``,o=()=>{a&&=(i+=st(a),``)},s=0;for(;s<t;){let c=e[s];if(c===`/`&&e[s+1]===`*`){o();let n=e.indexOf(`*/`,s+2),r=n===-1?t:n+2;i+=e.slice(s,r),s=r;continue}if(c===`"`||c===`'`){o();let n=s+1;for(;n<t;){if(e[n]===`\\`){n+=2;continue}if(e[n]===c){n++;break}n++}i+=e.slice(s,n),s=n;continue}if((c===`u`||c===`U`)&&e.slice(s,s+4).toLowerCase()===`url(`&&!n(e[s-1])){o();let n=s+4;for(;n<t&&r(e[n]);)n++;if(e[n]===`"`||e[n]===`'`){let i=e[n];for(n++;n<t;){if(e[n]===`\\`){n+=2;continue}if(e[n]===i){n++;break}n++}for(;n<t&&r(e[n]);)n++;e[n]===`)`&&n++}else for(;n<t;){if(e[n]===`\\`){n+=2;continue}if(e[n]===`)`){n++;break}n++}i+=e.slice(s,n),s=n;continue}a+=c,s++}return o(),i}var lt=2e3,ut=`#ffffff`,dt=`#fbfaf8`,ft=`#1c1a17`,pt=`${dt} radial-gradient(circle, rgba(20,18,16,0.11) 1px, transparent 1.2px) 0 0 / 14px 14px`,mt=`${ft} radial-gradient(circle, rgba(240,238,233,0.10) 1px, transparent 1.2px) 0 0 / 14px 14px`;function ht(e){return e===`dark`?mt:pt}var gt={light:`#1c1a18`,dark:`#f0eee9`},_t={light:`#6b675f`,dark:`#a8a39a`},vt={light:dt,dark:ft};function yt(e){return`--sg-ink:${gt[e]};--sg-ink-muted:${_t[e]};--sg-surface:${vt[e]};`}function bt(e,t,n){return t===`iframe`?`:root{${yt(e===`dark`?`dark`:`light`)}}`:n?`:root{${yt(`light`)}}\n@media (prefers-color-scheme: dark){:root{${yt(`dark`)}}}`:`:root{${yt(`light`)}}`}var xt=`#f4f2ef`,St=`#121110`;function Ct(e){if(e===void 0)return null;let t=e.trim();return t===`transparent`?`transparent`:t===`neutral`?ut:N(t)?t:null}function wt(e,t,n){return Ct(t??n??(e===`pages`||e===`app`?`neutral`:`transparent`))??`transparent`}function Tt(e){if(!e)return``;let t=Object.entries(e).map(([e,t])=>` ${e.startsWith(`--`)?e:`--${e.replace(/^-+/,``)}`}: ${He(t.replace(/[;{}]/g,` `))};`).join(`
190
+ `);return t?`<style data-artifact-tokens>:root {\n${t}\n}</style>`:``}function W(e){let t=e.shared?.files;return t?Object.entries(t).filter(([e])=>e.toLowerCase().endsWith(`.css`)).map(([e,t])=>`<style data-artifact-file="${B(e)}">\n${He(t)}\n</style>`).join(`
191
+ `):``}function Et(e,t,n){let r=t.rects.map((t,r)=>{let i=e.frames[r],a=i.geometry.height===`auto`?`min-height:${t.height}px;height:auto;`:`height:${t.height}px;`,o=i.layout===`whiteboard`?`background:${ht(n)};`:`background:${wt(i.layout,i.background,e.display?.background)};`;return`[data-sg-frame-id="${i.id}"]{left:${t.x}px;top:${t.y}px;width:${t.width}px;${a}${o}}`}).join(`
192
+ `);return`html,body{margin:0;padding:0;background:transparent;}
193
+ body{position:relative;width:${t.width}px;height:${t.height}px;overflow:hidden;}
194
+ [data-sg-frame]{position:absolute;box-sizing:border-box;overflow:hidden;}
195
+ ${r}`}function Dt(e,t=!1){return e.frames.map((e,n)=>{let r=e.title||`Frame ${n+1}`,i=e.background?` data-sg-bg="${B(e.background)}"`:``,a=t&&n===0?` data-sg-present-active=""`:``;return`<section data-sg-frame data-sg-frame-id="${B(e.id)}" data-frame-index="${n}" data-frame-layout="${e.layout}"${i}${a} role="group" aria-label="${B(r)}">${e.content}</section>`}).join(`
196
+ `)}function Ot(e){let t=Object.entries(e.shared?.files??{}).filter(([e])=>/\.(m?js)$/i.test(e)).map(([e,t])=>({path:e,js:t,module:e.toLowerCase().endsWith(`.mjs`)}));return t.length===0?``:(e.libraries??[]).length===0?t.map(({path:e,js:t,module:n})=>`<script${n?` type="module"`:``} data-artifact-file="${B(e)}">\n${Ve(t)}\n<\/script>`).join(`
197
+ `):`<script data-artifact-user-scripts>
198
+ (async () => {
199
+ await (window.__STUDIOGRAPH_ARTIFACT_LIBRARIES_READY__ || Promise.resolve());
200
+ const scripts = ${Ve(JSON.stringify(t.map(e=>({path:e.path,js:e.js,kind:e.module?`module`:`classic`}))))};
201
+ for (const script of scripts) {
202
+ await new Promise((resolve, reject) => {
203
+ const url = URL.createObjectURL(new Blob([String(script.js) + '\\n//# sourceURL=studiograph-artifact://' + String(script.path)], { type: 'text/javascript' }));
204
+ if (script.kind === 'module') { import(url).then(resolve, reject); return; }
205
+ const element = document.createElement('script');
206
+ element.src = url; element.async = false;
207
+ element.onload = () => resolve(); element.onerror = () => reject(new Error('Could not load artifact script: ' + String(script.path)));
208
+ document.head.appendChild(element);
209
+ });
210
+ }
211
+ })().catch((error) => { console.error('Artifact script error', error); throw error; });
212
+ <\/script>`}function kt(e,t,n=!1,r=!1){return`
213
+ (() => {
214
+ const artifactId = ${JSON.stringify(e)};
215
+ const surface = ${JSON.stringify(t)};
216
+ const fullBleed = ${JSON.stringify(n)};
217
+ const whiteboard = ${JSON.stringify(r)};
218
+ // A whiteboard pans/zooms in BOTH editor and present (it is a large pannable
219
+ // surface, not a stepped deck), so wheel AND hand-drag pan are forwarded to the
220
+ // host in either mode; elsewhere only the editor navigates. In a whiteboard
221
+ // present there is no pointer/hand toolbar, so the hand tool is the default —
222
+ // the surface pans on a plain drag. A whiteboard EDITOR keeps the pointer default
223
+ // (it has the Select / Pan toggle) and the host syncs the active tool.
224
+ const canNavigate = surface === 'editor' || whiteboard;
225
+ let tool = ${JSON.stringify(r&&t!==`editor`?`hand`:`pointer`)};
226
+ const send = (payload) => { try { parent.postMessage({ channel: 'studiograph-artifact', artifactId, ...payload }, '*'); } catch {} };
227
+ // Show the grab cursor over the canvas (the iframe content) whenever the hand
228
+ // tool is active — the host stage cursor doesn't reach inside the iframe. The
229
+ // pan handlers below swap to 'grabbing' while dragging.
230
+ const applyCursor = () => { try { document.body.style.cursor = (canNavigate && tool === 'hand') ? 'grab' : ''; } catch {} };
231
+ applyCursor();
232
+ const frames = () => Array.from(document.querySelectorAll('[data-sg-frame]'));
233
+ const cssEscape = (value) => (window.CSS && CSS.escape) ? CSS.escape(value) : String(value);
234
+ const frameById = (id) => document.querySelector('[data-sg-frame-id="' + cssEscape(id) + '"]');
235
+
236
+ // --- per-frame size reporting (auto frames; host reflows from these) ---
237
+ const measure = () => frames().map((el) => ({
238
+ id: el.getAttribute('data-sg-frame-id'),
239
+ width: el.offsetWidth,
240
+ height: Math.max(el.scrollHeight, el.offsetHeight),
241
+ }));
242
+ let sizeTimer = null;
243
+ const reportSizes = () => send({ type: 'frame-sizes', sizes: measure() });
244
+ const queueSizes = () => { if (sizeTimer) clearTimeout(sizeTimer); sizeTimer = setTimeout(reportSizes, 150); };
245
+
246
+ // --- apply host-computed layout rects + extent ---
247
+ // The host recomputes the analytic layout when an auto-height frame measures,
248
+ // then sends the new rects AND the new total extent. Frame width comes from
249
+ // the rect; auto frames keep height:auto (content-driven). The body is resized
250
+ // to the extent so a grown auto frame isn't clipped by the baked body box
251
+ // (the host resizes the iframe element to the same extent in lockstep).
252
+ const applyLayout = (rects, width, height) => {
253
+ for (const rect of (rects || [])) {
254
+ const el = frameById(rect.id);
255
+ if (!el) continue;
256
+ el.style.left = rect.x + 'px';
257
+ el.style.top = rect.y + 'px';
258
+ el.style.width = rect.width + 'px';
259
+ }
260
+ if (typeof width === 'number' && width > 0) document.body.style.width = width + 'px';
261
+ if (typeof height === 'number' && height > 0) document.body.style.height = height + 'px';
262
+ };
263
+
264
+ window.addEventListener('message', (event) => {
265
+ const data = event.data;
266
+ if (!data || data.channel !== 'studiograph-artifact-host' || data.artifactId !== artifactId) return;
267
+ if (data.type === 'apply-layout') applyLayout(data.rects, data.width, data.height);
268
+ if (data.type === 'set-tool' && (data.tool === 'pointer' || data.tool === 'hand')) { tool = data.tool; applyCursor(); }
269
+ if (data.type === 'clear-selection') clearSelection();
270
+ if (data.type === 'select-ancestor' && typeof data.index === 'number') selectAncestor(data.index);
271
+ });
272
+
273
+ window.addEventListener('error', (event) => send({ status: 'error', message: String((event && event.message) || 'Artifact error') }));
274
+ window.addEventListener('unhandledrejection', (event) => send({ status: 'error', message: String((event && event.reason && event.reason.message) || (event && event.reason) || 'Artifact promise rejection') }));
275
+ // Observe frames for size changes. The observer is set up AFTER the body has
276
+ // parsed (frames exist) — at head-parse time querySelectorAll is empty — so
277
+ // async content growth (fonts, images, and document pagination, which only
278
+ // settles after load) is reported, not just the one-shot load measure.
279
+ let resizeObserver = null;
280
+ const observeFrames = () => {
281
+ try {
282
+ if (!resizeObserver) resizeObserver = new ResizeObserver(queueSizes);
283
+ else resizeObserver.disconnect();
284
+ for (const el of frames()) resizeObserver.observe(el);
285
+ } catch {}
286
+ };
287
+ // applyCursor() at init is a no-op (it runs in <head>, before <body> exists), so
288
+ // set the cursor again on load — otherwise a present whiteboard (default hand
289
+ // tool) shows the grab cursor only after the first pointer interaction.
290
+ window.addEventListener('load', () => { send({ status: 'ready' }); observeFrames(); reportSizes(); applyCursor(); });
291
+ try { if (document.fonts && document.fonts.ready) document.fonts.ready.then(() => { observeFrames(); reportSizes(); }); } catch {}
292
+
293
+ // --- selection (editor only) ---
294
+ const safeText = (value, limit = 160) => String(value || '').replace(/\\s+/g, ' ').trim().slice(0, limit);
295
+ // Content/interactive elements snap selection to themselves (a click on a
296
+ // heading's text selects the heading, on a button's label the button); any other
297
+ // element selects exactly as itself (see selectionTarget).
298
+ const specificContent = 'h1,h2,h3,h4,h5,h6,p,li,td,th,blockquote,figure,figcaption,label,svg,path,g,rect,circle,text,img,video,a,button,[role="button"]';
299
+ const selectorFor = (el) => {
300
+ if (!(el instanceof Element)) return '';
301
+ if (el.id) return '#' + cssEscape(el.id);
302
+ const parts = [];
303
+ let node = el;
304
+ while (node && node.nodeType === 1 && parts.length < 5 && !node.hasAttribute('data-sg-frame')) {
305
+ let part = node.tagName.toLowerCase();
306
+ const parent = node.parentElement;
307
+ if (parent) {
308
+ const twins = Array.from(parent.children).filter((child) => child.tagName === node.tagName);
309
+ if (twins.length > 1) part += ':nth-of-type(' + (twins.indexOf(node) + 1) + ')';
310
+ }
311
+ parts.unshift(part);
312
+ node = parent;
313
+ }
314
+ return parts.join(' > ');
315
+ };
316
+ const selected = new Map();
317
+ const clearSelection = (publish = true) => {
318
+ for (const entry of selected.values()) entry.el && entry.el.removeAttribute && entry.el.removeAttribute('data-sg-selected');
319
+ selected.clear();
320
+ if (publish) publishSelection();
321
+ };
322
+ // Human label for a breadcrumb segment: data-sg-name if authored, else a
323
+ // CSS-ish token (tag, tag#id, or tag.firstClass); the frame shows its name.
324
+ const labelFor = (el) => {
325
+ if (el.hasAttribute('data-sg-frame')) {
326
+ return el.getAttribute('data-sg-name') || ('Frame ' + ((parseInt(el.getAttribute('data-frame-index'), 10) || 0) + 1));
327
+ }
328
+ const name = el.getAttribute('data-sg-name');
329
+ if (name) return name;
330
+ const tag = el.tagName.toLowerCase();
331
+ if (el.id) return tag + '#' + el.id;
332
+ const cls = (el.getAttribute('class') || '').trim().split(/\\s+/).filter(Boolean)[0];
333
+ return cls ? tag + '.' + cls : tag;
334
+ };
335
+ // The selected element's ancestor chain within its frame: frame-first → el-last.
336
+ const ancestorChain = (el) => {
337
+ const frame = el.closest('[data-sg-frame]');
338
+ if (!frame) return [];
339
+ const chain = [];
340
+ let n = el;
341
+ while (n) { chain.unshift(n); if (n === frame) break; n = n.parentElement; }
342
+ return chain;
343
+ };
344
+ const publishSelection = () => {
345
+ const entries = Array.from(selected.values());
346
+ // Recompute each target's descriptor from the LIVE element so the rects reflect
347
+ // current geometry — a scroll/resize re-emit must carry where the element is NOW,
348
+ // not where it was when first selected (the targetId/selector stay stable, so the
349
+ // host repositions its overlay in place rather than treating it as a new target).
350
+ const targets = entries.map((entry) => { entry.target = descriptorFor(entry.el); return entry.target; });
351
+ // A single selection carries its ancestor labels for the host breadcrumb;
352
+ // a multi-selection has no single path.
353
+ const path = entries.length === 1 ? ancestorChain(entries[0].el).map(labelFor) : null;
354
+ send({ type: 'selection-change', primaryTargetId: (targets[targets.length - 1] || {}).targetId || '', targets, ...(path ? { path: path } : {}) });
355
+ if (targets.length === 0) send({ type: 'clear-selection' });
356
+ };
357
+ // Breadcrumb drill-out: re-select the ancestor at the given index of the current
358
+ // single selection's chain. The selected element itself (last) is a no-op.
359
+ const selectAncestor = (index) => {
360
+ const entries = Array.from(selected.values());
361
+ if (entries.length !== 1) return;
362
+ const chain = ancestorChain(entries[0].el);
363
+ const target = chain[index];
364
+ if (!(target instanceof Element) || target === entries[0].el) return;
365
+ clearSelection(false);
366
+ const t = descriptorFor(target);
367
+ target.setAttribute('data-sg-selected', 'true');
368
+ selected.set(t.targetId, { el: target, target: t });
369
+ publishSelection();
370
+ };
371
+ // Clip an element rect to a box (both in iframe viewport coords), returning the
372
+ // visible intersection as a plain {x,y,width,height}. A paginated document renders
373
+ // each page as a [data-sg-page-window] (overflow:hidden) onto ONE column of a single
374
+ // native multi-column flow; a block that fragments across a column (= page) boundary
375
+ // has a getBoundingClientRect spanning BOTH pages, and getBoundingClientRect ignores
376
+ // the window's clip — so a selection of it would draw ACROSS pages. Clipping to the
377
+ // page window keeps the overlay on the current page (its only visible part there).
378
+ const clipRectToBox = (rect, box) => {
379
+ const left = Math.max(rect.left, box.left);
380
+ const top = Math.max(rect.top, box.top);
381
+ const right = Math.min(rect.right, box.right);
382
+ const bottom = Math.min(rect.bottom, box.bottom);
383
+ return { x: left, y: top, width: Math.max(0, right - left), height: Math.max(0, bottom - top) };
384
+ };
385
+ const descriptorFor = (el) => {
386
+ const frame = el.closest('[data-sg-frame]');
387
+ // Only content inside a paginated page window is clipped; furniture and a bare
388
+ // frame/tile selection (not inside a window) keep their full rect.
389
+ const pageWindow = el.closest('[data-sg-page-window]');
390
+ const elRect = el.getBoundingClientRect();
391
+ const rect = pageWindow ? clipRectToBox(elRect, pageWindow.getBoundingClientRect()) : elRect;
392
+ const frameId = frame ? frame.getAttribute('data-sg-frame-id') : '';
393
+ // Never emit an empty selector (the host drops empty-selector targets): the
394
+ // frame element addresses by its frame id, anything else by its DOM path,
395
+ // falling back to the tag name.
396
+ const isFrame = el.hasAttribute('data-sg-frame');
397
+ const selector = isFrame
398
+ ? '[data-sg-frame-id="' + frameId + '"]'
399
+ : (selectorFor(el) || el.tagName.toLowerCase());
400
+ return {
401
+ frameId,
402
+ frameIndex: frame ? Number(frame.getAttribute('data-frame-index')) : -1,
403
+ selector,
404
+ tagName: el.tagName.toLowerCase(),
405
+ text: safeText(el.textContent),
406
+ rect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },
407
+ targetId: (frameId || '') + '::' + selector,
408
+ };
409
+ };
410
+ const selectionTarget = (node) => {
411
+ if (!(node instanceof Element)) return null;
412
+ const frame = node.closest('[data-sg-frame]');
413
+ if (!frame) return null; // bare stage → clears the selection
414
+ const explicit = node.closest('[data-sg-selectable]');
415
+ if (explicit) return explicit;
416
+ // EVERYTHING is selectable. Snap a click that lands inside a meaningful
417
+ // content/interactive element up to that element (clicking a heading's text
418
+ // selects the heading; a button's label selects the button); otherwise select
419
+ // the EXACT element clicked — a structural wrapper (header bar, nav rail, logo)
420
+ // selects as itself, never silently collapsing to the whole frame. The frame is
421
+ // selected only by clicking its own bare background. Use the breadcrumb to drill
422
+ // OUT to a container.
423
+ const specific = node.closest(specificContent);
424
+ if (specific && specific !== frame && frame.contains(specific)) return specific;
425
+ return node;
426
+ };
427
+ window.addEventListener('click', (event) => {
428
+ if (surface !== 'editor' || tool !== 'pointer') return;
429
+ if (handleLinkClick(event)) { /* still select the link element */ }
430
+ const el = selectionTarget(event.target);
431
+ if (!(el instanceof Element)) { clearSelection(); return; }
432
+ const target = descriptorFor(el);
433
+ const additive = event.shiftKey || event.metaKey || event.ctrlKey;
434
+ if (!additive) clearSelection(false);
435
+ if (additive && selected.has(target.targetId)) {
436
+ const prev = selected.get(target.targetId);
437
+ prev && prev.el && prev.el.removeAttribute('data-sg-selected');
438
+ selected.delete(target.targetId);
439
+ } else {
440
+ el.setAttribute('data-sg-selected', 'true');
441
+ selected.set(target.targetId, { el, target });
442
+ }
443
+ publishSelection();
444
+ }, { capture: true });
445
+ window.addEventListener('keydown', (event) => {
446
+ if (surface !== 'editor' || event.key !== 'Escape' || selected.size === 0) return;
447
+ clearSelection();
448
+ event.preventDefault();
449
+ }, { capture: true });
450
+
451
+ // Selection chrome lives in the HOST overlay, positioned from element rects. A
452
+ // scroll (the page or any inner scroll container) moves those elements, so re-emit
453
+ // the selection with fresh rects while a selection exists — rAF-throttled, mirroring
454
+ // the pan/zoom flush — or the overlay would lag behind the content it frames.
455
+ // Capture-phase catches non-bubbling scroll events from nested scrollers; passive
456
+ // keeps scrolling smooth.
457
+ let selectionReflowFrame = null;
458
+ const flushSelectionReflow = () => { selectionReflowFrame = null; if (selected.size > 0) publishSelection(); };
459
+ window.addEventListener('scroll', () => {
460
+ if (selected.size === 0 || selectionReflowFrame !== null) return;
461
+ selectionReflowFrame = requestAnimationFrame(flushSelectionReflow);
462
+ }, { capture: true, passive: true });
463
+
464
+ // Swallow in-sandbox navigation (a relative/external href would blank the frame).
465
+ const handleLinkClick = (event) => {
466
+ if (event.defaultPrevented || event.button) return false;
467
+ const anchor = event.target instanceof Element ? event.target.closest('a[href]') : null;
468
+ if (!anchor) return false;
469
+ const href = anchor.getAttribute('href') || '';
470
+ if (!href || /^javascript:/i.test(href)) return false;
471
+ event.preventDefault();
472
+ if (href.charAt(0) === '#') {
473
+ try { const dest = document.getElementById(href.slice(1)); dest && dest.scrollIntoView({ block: 'start', behavior: 'smooth' }); } catch {}
474
+ }
475
+ return true;
476
+ };
477
+ // Non-editor surfaces (a present document scrolls like a PDF): swallow in-frame
478
+ // navigation here too, so a relative/external href can't blank the sandboxed
479
+ // frame, and an in-document #anchor smooth-scrolls to its section while reading.
480
+ // Editor runs handleLinkClick from its own click handler above.
481
+ window.addEventListener('click', (event) => {
482
+ if (surface === 'editor') return;
483
+ handleLinkClick(event);
484
+ }, { capture: true });
485
+
486
+ // --- pan/zoom forwarding (the host owns the transform) ---
487
+ let panDelta = null, panFrame = null, zoomDelta = null, zoomFrame = null;
488
+ const flushPan = () => { panFrame = null; if (!panDelta) return; const d = panDelta; panDelta = null; send({ type: 'pan-delta', dx: d.dx, dy: d.dy }); };
489
+ const queuePan = (dx, dy) => { panDelta = panDelta ? { dx: panDelta.dx + dx, dy: panDelta.dy + dy } : { dx, dy }; if (panFrame === null) panFrame = requestAnimationFrame(flushPan); };
490
+ const flushZoom = () => { zoomFrame = null; if (!zoomDelta) return; const z = zoomDelta; zoomDelta = null; send({ type: 'zoom-delta', delta: z.delta, x: z.x, y: z.y }); };
491
+ const queueZoom = (delta, x, y) => { zoomDelta = zoomDelta ? { delta: zoomDelta.delta + delta, x, y } : { delta, x, y }; if (zoomFrame === null) zoomFrame = requestAnimationFrame(flushZoom); };
492
+ window.addEventListener('wheel', (event) => {
493
+ if (!canNavigate || fullBleed) return; // full-bleed: let the app scroll natively
494
+ const unit = event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? window.innerHeight : 1;
495
+ const dx = event.deltaX * unit, dy = event.deltaY * unit;
496
+ if (Math.abs(dx) < 0.01 && Math.abs(dy) < 0.01) return;
497
+ if (event.ctrlKey || event.metaKey) { queueZoom(dy, event.clientX, event.clientY); event.preventDefault(); return; }
498
+ queuePan(dx, dy);
499
+ event.preventDefault();
500
+ }, { capture: true, passive: false });
501
+ let panPointer = null;
502
+ window.addEventListener('pointerdown', (event) => {
503
+ if (!canNavigate || fullBleed || tool !== 'hand' || event.button !== 0) return;
504
+ panPointer = event.pointerId;
505
+ try { event.target.setPointerCapture && event.target.setPointerCapture(event.pointerId); } catch {}
506
+ try { document.body.style.cursor = 'grabbing'; } catch {}
507
+ send({ type: 'pan', phase: 'start', x: event.screenX, y: event.screenY });
508
+ event.preventDefault();
509
+ }, { capture: true });
510
+ window.addEventListener('pointermove', (event) => {
511
+ if (panPointer !== event.pointerId) return;
512
+ send({ type: 'pan', phase: 'move', x: event.screenX, y: event.screenY });
513
+ }, { capture: true });
514
+ const endPan = (event) => { if (panPointer !== event.pointerId) return; send({ type: 'pan', phase: 'end', x: event.screenX, y: event.screenY }); panPointer = null; applyCursor(); };
515
+ window.addEventListener('pointerup', endPan, { capture: true });
516
+ window.addEventListener('pointercancel', endPan, { capture: true });
517
+ // If capture is stolen mid-drag (system gesture, target removed), end the pan so
518
+ // the 'grabbing' cursor doesn't stick.
519
+ window.addEventListener('lostpointercapture', endPan, { capture: true });
520
+ })();`}function G(e){return`html,body{margin:0;padding:0;background:transparent;}
521
+ body{position:relative;margin:0;}
522
+ [data-sg-frame]{position:absolute;left:0 !important;top:0 !important;box-sizing:border-box;overflow:hidden;display:none;}
523
+ [data-sg-frame][data-sg-present-active]{display:block;}
524
+ ${e.frames.map(t=>{let n=t.geometry.height===`auto`?`height:auto;`:`height:${t.geometry.height}px;`,r=`background:${wt(t.layout,t.background,e.display?.background)};`;return`[data-sg-frame-id="${t.id}"]{width:${t.geometry.width}px;${n}${r}}`}).join(`
525
+ `)}`}function At(e){return`
526
+ (() => {
527
+ const artifactId = ${JSON.stringify(e)};
528
+ const send = (payload) => { try { parent.postMessage({ channel: 'studiograph-artifact', artifactId, ...payload }, '*'); } catch {} };
529
+ const frames = () => Array.from(document.querySelectorAll('[data-sg-frame]'));
530
+ let active = 0;
531
+ const sendState = () => { const all = frames(); if (all.length) send({ type: 'frame-state', index: active, count: all.length }); };
532
+ const sendSizes = () => send({ type: 'frame-sizes', sizes: frames().map((el) => ({ id: el.getAttribute('data-sg-frame-id'), width: el.offsetWidth, height: Math.max(el.scrollHeight, el.offsetHeight) })) });
533
+ const setActive = (index) => {
534
+ const all = frames();
535
+ if (!all.length) return;
536
+ active = Math.max(0, Math.min(all.length - 1, Number.isFinite(index) ? Math.round(index) : 0));
537
+ all.forEach((el, i) => { const on = i === active; el.toggleAttribute('data-sg-present-active', on); el.setAttribute('aria-hidden', on ? 'false' : 'true'); });
538
+ sendState();
539
+ sendSizes();
540
+ };
541
+ const step = (dir) => { const all = frames(); if (all.length) setActive((active + dir + all.length) % all.length); };
542
+ window.addEventListener('message', (event) => {
543
+ const data = event.data;
544
+ if (!data || data.channel !== 'studiograph-artifact-host' || data.artifactId !== artifactId) return;
545
+ if (data.type === 'set-frame') setActive(Number(data.index));
546
+ if (data.type === 'reset-frames') setActive(0);
547
+ });
548
+ window.addEventListener('error', (event) => send({ status: 'error', message: String((event && event.message) || 'Artifact error') }));
549
+ window.addEventListener('keydown', (event) => {
550
+ if (event.altKey || event.ctrlKey || event.metaKey) return;
551
+ if (event.key === 'ArrowRight' || event.key === 'PageDown' || event.key === ' ') { step(1); event.preventDefault(); return; }
552
+ if (event.key === 'ArrowLeft' || event.key === 'PageUp' || event.key === 'Backspace') { step(-1); event.preventDefault(); return; }
553
+ if (event.key === 'Home') { setActive(0); event.preventDefault(); return; }
554
+ if (event.key === 'End') { setActive(frames().length - 1); event.preventDefault(); return; }
555
+ });
556
+ // Navigation is via the host stepper controls + keyboard only — clicking a slide
557
+ // does NOT advance (the stepper is the clearer affordance; click-to-step was
558
+ // easy to trigger by accident). But pointer activity over the iframe (which the
559
+ // host can't see) must still re-reveal the auto-hiding controls: re-post the
560
+ // current frame-state (the host reveals on it) without changing the slide.
561
+ let activityRaf = null;
562
+ const signalActivity = () => { if (activityRaf !== null) return; activityRaf = requestAnimationFrame(() => { activityRaf = null; sendState(); }); };
563
+ window.addEventListener('pointermove', signalActivity, { passive: true });
564
+ window.addEventListener('click', signalActivity);
565
+ window.addEventListener('load', () => { send({ status: 'ready' }); setActive(0); });
566
+ try { if (document.fonts && document.fonts.ready) document.fonts.ready.then(sendSizes); } catch {}
567
+ })();`}function jt(e){return e.frames.length===1&&e.frames[0].layout!==`whiteboard`&&(e.frames[0].geometry.width===`fill`||e.frames[0].geometry.height===`fill`)}function Mt(e){let t=e.frames[0],n=wt(t.layout,t.background,e.display?.background),r=t.geometry.width;return`html,body{margin:0;padding:0;background:transparent;height:100%;}
568
+ body{position:relative;width:100%;height:100%;}
569
+ [data-sg-frame]{position:absolute;top:0;bottom:0;${typeof r==`number`?`left:50%;transform:translateX(-50%);width:${r}px;max-width:100%;`:`left:0;right:0;`}box-sizing:border-box;overflow:auto;background:${n};}`}function Nt(e){return e.frames.length>0&&e.frames.every(e=>e.layout===`pages`)}function Pt(e){return e.frames.length===1&&e.frames[0].layout===`whiteboard`}function Ft(e){let t=e.frames[0].geometry;return{width:typeof t.width==`number`?t.width:1280,height:typeof t.height==`number`?t.height:800}}function K(){return`.sg-bar{position:fixed;left:50%;bottom:16px;transform:translateX(-50%);display:flex;align-items:center;gap:3px;padding:4px;background:#fff;border:1px solid #e5e2dd;border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,0.08),0 1px 2px rgba(0,0,0,0.04);z-index:10;cursor:default;font:13px system-ui,-apple-system,sans-serif;}
570
+ .sg-bar-btn{width:28px;height:28px;display:flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:6px;color:#6b675f;background:transparent;cursor:pointer;transition:background 0.15s,color 0.15s;}
571
+ .sg-bar-btn:hover{background:#f2efea;color:#1c1a18;}
572
+ .sg-bar-btn svg{width:16px;height:16px;display:block;}
573
+ .sg-bar-sep{width:1px;height:16px;background:#e5e2dd;margin:0 3px;}
574
+ .sg-bar-zoom,.sg-bar-count{display:flex;align-items:center;justify-content:flex-end;min-width:44px;padding:0 6px;color:#6b675f;font-variant-numeric:tabular-nums;}
575
+ .sg-bar-count{justify-content:center;min-width:54px;}`}function It(e){let{width:t,height:n}=Ft(e);return`html,body{margin:0;padding:0;height:100%;overflow:hidden;background:${xt};}
576
+ body{position:relative;cursor:grab;}
577
+ body.sg-grabbing{cursor:grabbing;}
578
+ [data-sg-frame]{position:absolute;left:0;top:0;width:${t}px;height:${n}px;transform-origin:0 0;box-sizing:border-box;overflow:hidden;background:${pt};}
579
+ @media (prefers-color-scheme: dark){
580
+ html,body{background:${St};}
581
+ [data-sg-frame]{background:${mt};}
582
+ }
583
+ ${K()}`}var Lt={reset:`<path d="M18,28A12,12,0,1,0,6,16v6.2L2.4,18.6,1,20l6,6,6-6-1.4-1.4L8,22.2V16H8A10,10,0,1,1,18,26Z"/>`,zoomOut:`<path d="M8 12H18V14H8z"/><path d="M21.4479,20A10.856,10.856,0,0,0,24,13,11,11,0,1,0,13,24a10.856,10.856,0,0,0,7-2.5521L27.5859,29,29,27.5859ZM13,22a9,9,0,1,1,9-9A9.01,9.01,0,0,1,13,22Z"/>`,zoomIn:`<path d="M18 12 14 12 14 8 12 8 12 12 8 12 8 14 12 14 12 18 14 18 14 14 18 14 18 12z"/><path d="M21.4479,20A10.856,10.856,0,0,0,24,13,11,11,0,1,0,13,24a10.856,10.856,0,0,0,7-2.5521L27.5859,29,29,27.5859ZM13,22a9,9,0,1,1,9-9A9.01,9.01,0,0,1,13,22Z"/>`,chevronLeft:`<path d="M10 16 20 6 21.4 7.4 12.8 16 21.4 24.6 20 26z"/>`,chevronRight:`<path d="M22 16 12 26 10.6 24.6 19.2 16 10.6 7.4 12 6z"/>`},Rt=e=>`<svg viewBox="0 0 32 32" fill="currentColor" aria-hidden="true">${Lt[e]}</svg>`;function zt(){return`<div id="sg-wb-bar" class="sg-bar" role="toolbar" aria-label="Canvas controls"><button id="sg-wb-reset" class="sg-bar-btn" type="button" title="Reset view" aria-label="Reset view">${Rt(`reset`)}</button><span class="sg-bar-sep" aria-hidden="true"></span><button id="sg-wb-zoomout" class="sg-bar-btn" type="button" title="Zoom out" aria-label="Zoom out">${Rt(`zoomOut`)}</button><button id="sg-wb-zoomin" class="sg-bar-btn" type="button" title="Zoom in" aria-label="Zoom in">${Rt(`zoomIn`)}</button><span class="sg-bar-sep" aria-hidden="true"></span><span id="sg-wb-zoom" class="sg-bar-zoom">100%</span></div>`}function Bt(e,t){return`
584
+ (() => {
585
+ const W = ${e}, H = ${t}, MAXZOOM = 4;
586
+ // The runtime is injected in <head>, before the body parses, so the frame
587
+ // element is looked up lazily (capturing it at parse time would be null).
588
+ const elOf = () => document.querySelector('[data-sg-frame]');
589
+ let zoom = 1, x = 0, y = 0;
590
+ const vw = () => window.innerWidth, vh = () => window.innerHeight;
591
+ const cover = () => Math.max(vw() / W, vh() / H);
592
+ const clamp = (v, a, b) => Math.min(b, Math.max(a, v));
593
+ const clampPan = () => {
594
+ const w = W * zoom, h = H * zoom;
595
+ x = w >= vw() ? clamp(x, vw() - w, 0) : (vw() - w) / 2;
596
+ y = h >= vh() ? clamp(y, vh() - h, 0) : (vh() - h) / 2;
597
+ };
598
+ const label = () => { const l = document.getElementById('sg-wb-zoom'); if (l) l.textContent = Math.round(zoom * 100) + '%'; };
599
+ const apply = () => { const el = elOf(); if (el) el.style.transform = 'translate(' + x + 'px,' + y + 'px) scale(' + zoom + ')'; label(); };
600
+ // Open (and reset) at 100% centered; a canvas too small to cover the viewport
601
+ // at 1:1 scales up to the cover scale so no edge shows.
602
+ const fit = () => { zoom = Math.max(1, cover()); x = (vw() - W * zoom) / 2; y = (vh() - H * zoom) / 2; clampPan(); apply(); };
603
+ const setZoom = (nz, fx, fy) => {
604
+ // The cover scale is the min zoom; the max must be at least cover so the clamp
605
+ // never inverts (a small canvas can need >MAXZOOM just to cover the viewport).
606
+ const lo = cover(); nz = clamp(nz, lo, Math.max(MAXZOOM, lo));
607
+ fx = (fx == null) ? vw() / 2 : fx; fy = (fy == null) ? vh() / 2 : fy;
608
+ const ax = (fx - x) / zoom, ay = (fy - y) / zoom;
609
+ zoom = nz; x = fx - ax * zoom; y = fy - ay * zoom; clampPan(); apply();
610
+ };
611
+ let dragging = false, px = 0, py = 0;
612
+ window.addEventListener('pointerdown', (e) => {
613
+ if (e.button !== 0 || (e.target && e.target.closest && e.target.closest('#sg-wb-bar'))) return;
614
+ dragging = true; px = e.clientX; py = e.clientY; document.body.classList.add('sg-grabbing');
615
+ try { e.target.setPointerCapture && e.target.setPointerCapture(e.pointerId); } catch {}
616
+ });
617
+ window.addEventListener('pointermove', (e) => { if (!dragging) return; x += e.clientX - px; y += e.clientY - py; px = e.clientX; py = e.clientY; clampPan(); apply(); });
618
+ const end = () => { dragging = false; document.body.classList.remove('sg-grabbing'); };
619
+ window.addEventListener('pointerup', end); window.addEventListener('pointercancel', end); window.addEventListener('lostpointercapture', end);
620
+ window.addEventListener('wheel', (e) => {
621
+ e.preventDefault();
622
+ const unit = e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? vh() : 1;
623
+ if (e.ctrlKey || e.metaKey) { setZoom(zoom * Math.exp(-e.deltaY * unit * 0.0015), e.clientX, e.clientY); return; }
624
+ x -= e.deltaX * unit; y -= e.deltaY * unit; clampPan(); apply();
625
+ }, { passive: false });
626
+ // Wire the toolbar + do the first fit once the DOM exists (the runtime runs in
627
+ // <head>, before the toolbar buttons parse).
628
+ const wire = () => {
629
+ const onBar = (id, fn) => { const b = document.getElementById(id); if (b) b.addEventListener('click', fn); };
630
+ onBar('sg-wb-zoomout', () => setZoom(zoom / 1.2));
631
+ onBar('sg-wb-zoomin', () => setZoom(zoom * 1.2));
632
+ onBar('sg-wb-reset', () => fit());
633
+ fit();
634
+ };
635
+ window.addEventListener('resize', fit);
636
+ if (document.readyState === 'loading') window.addEventListener('DOMContentLoaded', wire); else wire();
637
+ window.addEventListener('load', fit);
638
+ })();`}function Vt(){return`.sg-present{position:fixed;left:0;right:0;bottom:24px;display:flex;align-items:center;justify-content:center;pointer-events:none;opacity:0;transition:opacity 300ms ease;z-index:10;font:13px system-ui,-apple-system,sans-serif;}
639
+ .sg-present.visible{opacity:1;}
640
+ .sg-present-group{display:flex;align-items:center;gap:2px;padding:4px;background:rgba(30,30,30,0.85);border-radius:8px;pointer-events:auto;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);}
641
+ .sg-present-btn{width:32px;height:32px;display:flex;align-items:center;justify-content:center;padding:0;border:0;border-radius:6px;color:rgba(255,255,255,0.6);background:transparent;cursor:pointer;transition:color 120ms,background 120ms;}
642
+ .sg-present-btn svg{width:16px;height:16px;display:block;}
643
+ .sg-present-btn:hover{background:rgba(255,255,255,0.1);color:#fff;}
644
+ .sg-present-count{height:32px;display:flex;align-items:center;justify-content:center;padding:0 8px;color:rgba(255,255,255,0.6);font-weight:500;font-variant-numeric:tabular-nums;white-space:nowrap;user-select:none;}
645
+ .sg-present-reset{position:absolute;right:24px;}
646
+ .sg-present-restart{width:auto;gap:6px;padding:0 8px;font-weight:500;white-space:nowrap;}`}function Ht(e){return`html,body{margin:0;padding:0;height:100%;overflow:hidden;background:#4a4a4a;}
647
+ body{position:relative;}
648
+ [data-sg-frame]{position:absolute;left:0;top:0;transform-origin:0 0;box-sizing:border-box;overflow:hidden;display:none;}
649
+ [data-sg-frame][data-sg-present-active]{display:block;}
650
+ ${e.frames.map(t=>{let n=typeof t.geometry.width==`number`?`${t.geometry.width}px`:`100%`,r=t.geometry.height===`auto`||t.geometry.height===`fill`?`height:auto;`:`height:${t.geometry.height}px;`,i=`background:${wt(t.layout,t.background,e.display?.background)};`;return`[data-sg-frame-id="${t.id}"]{width:${n};${r}${i}}`}).join(`
651
+ `)}
652
+ ${Vt()}`}function Ut(){return`<div id="sg-present" class="sg-present"><div class="sg-present-group" role="group" aria-label="Slide navigation"><button id="sg-prev" class="sg-present-btn" type="button" title="Previous" aria-label="Previous">${Rt(`chevronLeft`)}</button><span id="sg-count" class="sg-present-count">1 / 1</span><button id="sg-next" class="sg-present-btn" type="button" title="Next" aria-label="Next">${Rt(`chevronRight`)}</button></div><div class="sg-present-group sg-present-reset"><button id="sg-restart" class="sg-present-btn sg-present-restart" type="button" title="Restart" aria-label="Restart">${Rt(`reset`)}<span>Restart</span></button></div></div>`}function Wt(){return`
653
+ (() => {
654
+ const MAX_SCALE = 6;
655
+ const frames = () => Array.prototype.slice.call(document.querySelectorAll('[data-sg-frame]'));
656
+ let active = 0, hideTimer = null;
657
+ const fitActive = () => {
658
+ const all = frames(); if (!all.length) return;
659
+ const el = all[active]; const fw = el.offsetWidth || 1, fh = el.offsetHeight || 1;
660
+ const pad = 48; const scale = Math.min((window.innerWidth - pad) / fw, (window.innerHeight - pad) / fh, MAX_SCALE);
661
+ const s = Math.max(0.05, scale);
662
+ el.style.transform = 'translate(' + ((window.innerWidth - fw * s) / 2) + 'px,' + ((window.innerHeight - fh * s) / 2) + 'px) scale(' + s + ')';
663
+ };
664
+ const updateCount = () => { const c = document.getElementById('sg-count'); if (c) c.textContent = (active + 1) + ' / ' + frames().length; };
665
+ const show = (i) => {
666
+ const all = frames(); if (!all.length) return;
667
+ active = ((i % all.length) + all.length) % all.length;
668
+ all.forEach((el, idx) => { el.toggleAttribute('data-sg-present-active', idx === active); el.setAttribute('aria-hidden', idx === active ? 'false' : 'true'); });
669
+ fitActive(); updateCount();
670
+ };
671
+ const step = (d) => show(active + d);
672
+ const reveal = () => { const c = document.getElementById('sg-present'); if (!c) return; c.classList.add('visible'); if (hideTimer) clearTimeout(hideTimer); hideTimer = setTimeout(() => c.classList.remove('visible'), 2500); };
673
+ const wire = () => {
674
+ const on = (id, fn) => { const b = document.getElementById(id); if (b) b.addEventListener('click', (e) => { e.stopPropagation(); fn(); reveal(); }); };
675
+ on('sg-prev', () => step(-1)); on('sg-next', () => step(1)); on('sg-restart', () => show(0));
676
+ show(0); reveal();
677
+ };
678
+ window.addEventListener('keydown', (e) => {
679
+ if (e.altKey || e.ctrlKey || e.metaKey) return;
680
+ // Don't hijack keys aimed at a focused control or text field: typing in a slide
681
+ // input must work, and Space on a focused button should activate it natively
682
+ // (not double-step). Mirrors the in-app present keyboard guard.
683
+ const t = e.target;
684
+ if (t && t.closest && t.closest('input,textarea,select,[contenteditable="true"],button,a[href],[role="button"]')) return;
685
+ if (e.key === 'ArrowRight' || e.key === 'PageDown' || e.key === ' ') { step(1); reveal(); e.preventDefault(); }
686
+ else if (e.key === 'ArrowLeft' || e.key === 'PageUp' || e.key === 'Backspace') { step(-1); reveal(); e.preventDefault(); }
687
+ else if (e.key === 'Home') { show(0); reveal(); e.preventDefault(); }
688
+ else if (e.key === 'End') { show(frames().length - 1); reveal(); e.preventDefault(); }
689
+ });
690
+ // Navigation is via the stepper controls + keyboard only — clicking a slide does
691
+ // NOT advance (the stepper is the clearer affordance). A click still reveals the
692
+ // auto-hiding controls.
693
+ window.addEventListener('click', reveal);
694
+ window.addEventListener('mousemove', reveal);
695
+ window.addEventListener('resize', fitActive);
696
+ if (document.readyState === 'loading') window.addEventListener('DOMContentLoaded', wire); else wire();
697
+ window.addEventListener('load', () => { show(active); reveal(); });
698
+ })();`}function Gt(e){let t=e.frames.map(t=>{let n=typeof t.geometry.width==`number`?`${t.geometry.width}px`:`100%`,r=typeof t.geometry.height==`number`?`min-height:${t.geometry.height}px;`:``,i=wt(t.layout,t.background,e.display?.background);return`[data-sg-frame-id="${t.id}"]:not([data-sg-page]){width:${n};max-width:100%;margin:0 auto 32px;${r}background:${i};box-shadow:0 6px 24px rgba(0,0,0,0.18);}`}).join(`
699
+ `);return`html,body{margin:0;padding:0;background:transparent;height:100%;}
700
+ body{box-sizing:border-box;min-height:100%;overflow:auto;padding:48px 0;}
701
+ [data-sg-frame]{position:relative;box-sizing:border-box;background:transparent;overflow:visible;}
702
+ [data-sg-frame][data-sg-page]{margin:0 auto 32px;overflow:hidden;box-shadow:0 6px 24px rgba(0,0,0,0.18);}
703
+ ${Qt()}
704
+ ${t}`}function Kt(e){return e.layout===`pages`&&typeof e.geometry.width==`number`&&typeof e.geometry.height==`number`}function qt(e){return e.frames.filter(Kt)}function Jt(e){return e.replace(/(<style\b[^>]*>)([\s\S]*?)(<\/style>)|(\sstyle\s*=\s*)("([^"]*)"|'([^']*)')/gi,(e,t,n,r,i,a,o,s)=>{if(t!==void 0)return t+ct(n)+r;let c=a[0],l=o===void 0?s:o;return i+c+ct(l)+c})}function Yt(e){let t=e.shared,n=t?.files,r=n&&Object.fromEntries(Object.entries(n).map(([e,t])=>[e,e.toLowerCase().endsWith(`.css`)?ct(t):t]));return{...e,...t?{shared:{...t,files:r,...t.head?{head:Jt(t.head)}:{}}}:{},frames:e.frames.map(e=>Kt(e)?{...e,content:Jt(e.content)}:e)}}function Xt(e){let t=e.pageMargins;return{top:t?.top??P.top,right:t?.right??P.right,bottom:t?.bottom??P.bottom,left:t?.left??P.left}}function Zt(){return`[data-sg-doc-flow] img{max-width:100%;height:auto;}
705
+ [data-sg-doc-flow] svg,[data-sg-doc-flow] video,[data-sg-doc-flow] canvas,[data-sg-doc-flow] table,[data-sg-doc-flow] pre{max-width:100%;}`}function Qt(){return`[data-sg-furniture]{position:absolute;font:12px var(--sg-furniture-font, system-ui, -apple-system, sans-serif);color:#374151;pointer-events:none;}`}function $t(){return Qt()}function q(e){let t=Xt(e),n=e.geometry.width,r=e.geometry.height,i=n-t.left-t.right,a=r-t.top-t.bottom,o=t.right+t.left+40;return{width:n,height:r,contentWidth:i,contentHeight:a,gap:o,pitch:i+o,margins:t}}function en(e,t,n,r,i,a){let o={};for(let t of e)o[t.id]={...q(t),title:t.title||`Document`,background:wt(t.layout,t.background,a),...t.furniture?{furniture:t.furniture}:{},...t.pageNumbers?{pageNumbers:t.pageNumbers}:{}};return`
706
+ (() => {
707
+ const artifactId = ${JSON.stringify(t)};
708
+ const renderId = ${JSON.stringify(r)};
709
+ const FRAME_GAP = 64;
710
+ const PROMOTE = ${JSON.stringify(n)};
711
+ const HOSTED_CANVAS = ${JSON.stringify(i)};
712
+ const DONE_ATTR = 'data-sg-paginated-done';
713
+ const PAGINATE = ${JSON.stringify(o)};
714
+ const cssEscape = (value) => (window.CSS && CSS.escape) ? CSS.escape(value) : String(value);
715
+ // Pick the page-position furniture variant: page 1 -> first (or middle), last
716
+ // page -> last (or middle), every other page -> middle.
717
+ const pickSlot = (slots, index, count) => index === 0
718
+ ? (slots.first || slots.middle)
719
+ : (index === count - 1 ? (slots.last || slots.middle) : slots.middle);
720
+ const addRegion = (tile, html, region, margins, anchor, offset) => {
721
+ if (!html) return;
722
+ const el = document.createElement('div');
723
+ el.setAttribute('data-sg-furniture', '');
724
+ el.setAttribute('data-sg-furniture-region', region);
725
+ // left/right inset to the side margins so the band aligns to the content column.
726
+ el.style.left = margins.left + 'px';
727
+ el.style.right = margins.right + 'px';
728
+ el.innerHTML = html;
729
+ tile.appendChild(el);
730
+ // Two placements, by anchor:
731
+ // - 'page' (letterhead/masthead): pin to the page's OUTER edge — header at the
732
+ // top edge, footer at the bottom edge, offset px in — independent of margin
733
+ // depth, so a masthead rides high with a deep body margin (no content-padding
734
+ // hack). Height-independent.
735
+ // - 'content' (default, running header/footer): bottom-align the header to just
736
+ // above the content (within the top margin) / top-align the footer to just
737
+ // below it, from the MEASURED height so a tall band never overlaps the body.
738
+ // The default "Page N of M" counter is bottom-RIGHT, so a centered/left footer
739
+ // band clears it. If a margin is smaller than its furniture the author must grow
740
+ // pageMargins — out-of-flow furniture can't reserve space.
741
+ const GAP = 10, MIN_INSET = 8;
742
+ const place = () => {
743
+ if (anchor === 'page') {
744
+ // Pin to the page's outer edge, offset px in (default MIN_INSET).
745
+ const inset = (typeof offset === 'number') ? offset : MIN_INSET;
746
+ if (region === 'header') el.style.top = inset + 'px';
747
+ else el.style.bottom = inset + 'px';
748
+ return;
749
+ }
750
+ // Content anchor: offset is the GAP between the band and the content edge
751
+ // (default GAP) — so it has effect on both anchors, per the model.
752
+ const gap = (typeof offset === 'number') ? offset : GAP;
753
+ const h = el.offsetHeight;
754
+ if (region === 'header') el.style.top = Math.max(MIN_INSET, margins.top - gap - h) + 'px';
755
+ else el.style.bottom = Math.max(MIN_INSET, margins.bottom - gap - h) + 'px';
756
+ };
757
+ place();
758
+ // A logo <img> without a fixed height measures 0 until it loads, which would
759
+ // mis-place a content-anchored band; re-place once each image settles (the render
760
+ // waits for network-idle, so the reposition lands before capture).
761
+ el.querySelectorAll('img').forEach((img) => { if (!img.complete) img.addEventListener('load', place); });
762
+ };
763
+ const addFurniture = (tile, furniture, index, count, margins) => {
764
+ if (furniture.header) addRegion(tile, pickSlot(furniture.header, index, count), 'header', margins, furniture.header.anchor, furniture.header.offset);
765
+ if (furniture.footer) addRegion(tile, pickSlot(furniture.footer, index, count), 'footer', margins, furniture.footer.anchor, furniture.footer.offset);
766
+ };
767
+ // The DEFAULT page number, bottom-right within the bottom margin (replaces the
768
+ // removed Paged.js @page{@bottom-right{counter(page)}} default). Baked as literal
769
+ // text per tile — no cross-tile counter() to keep — so every document keeps page
770
+ // numbers even when it declares no furniture.
771
+ const addPageNumber = (tile, index, count, margins, cfg) => {
772
+ cfg = cfg || {};
773
+ if (cfg.show === false) return;
774
+ if (cfg.showOnFirst === false && index === 0) return;
775
+ const startAt = (typeof cfg.startAt === 'number') ? cfg.startAt : 1;
776
+ const n = startAt + index;
777
+ const m = startAt + count - 1;
778
+ const format = (typeof cfg.format === 'string') ? cfg.format : 'Page {n} of {m}';
779
+ const text = format.replace(/\\{n\\}/g, String(n)).replace(/\\{m\\}/g, String(m));
780
+ if (!text) return;
781
+ const position = cfg.position || 'bottom-right';
782
+ const isTop = position.indexOf('top-') === 0;
783
+ const el = document.createElement('div');
784
+ el.setAttribute('data-sg-furniture', '');
785
+ el.setAttribute('data-sg-furniture-region', 'pagenum');
786
+ el.style.color = '#6b7280';
787
+ // Vertical: offset px from the nearer page edge, else centered in the band
788
+ // (the legacy default: bottom-right at about bottom-margin/2).
789
+ const band = isTop ? margins.top : margins.bottom;
790
+ const v = (typeof cfg.offset === 'number') ? cfg.offset : Math.max(8, Math.round(band / 2) - 8);
791
+ el.style[isTop ? 'top' : 'bottom'] = v + 'px';
792
+ // Horizontal: aligned to the content column's left/right edge, or centered
793
+ // WITHIN the content column (spanning left..right with text-align, like a
794
+ // furniture band) so it stays aligned under asymmetric margins.
795
+ if (position.indexOf('-left') >= 0) el.style.left = margins.left + 'px';
796
+ else if (position.indexOf('-right') >= 0) el.style.right = margins.right + 'px';
797
+ else { el.style.left = margins.left + 'px'; el.style.right = margins.right + 'px'; el.style.textAlign = 'center'; }
798
+ el.textContent = text;
799
+ tile.appendChild(el);
800
+ };
801
+ const compose = async () => {
802
+ const expansions = [];
803
+ // Frames whose composition THREW. Reported to the host so it can surface a
804
+ // non-blocking "couldn't paginate" hint instead of a clipped single page.
805
+ const failed = [];
806
+ // ALWAYS run on every exit path (success, per-frame throw, or top-level throw):
807
+ // mark the settle signal + post frame-pages, so a host-less render's wait
808
+ // resolves and the live host never holds the reveal forever.
809
+ const finish = () => {
810
+ try { document.documentElement.setAttribute(DONE_ATTR, ''); } catch {}
811
+ if (PROMOTE) {
812
+ try { parent.postMessage({ channel: 'studiograph-artifact', artifactId: artifactId, type: 'frame-pages', renderId: renderId, expansions: expansions, failed: failed }, '*'); } catch {}
813
+ }
814
+ };
815
+ try {
816
+ // Measure after fonts settle so column breaks match the final type. Fonts are
817
+ // inlined as data: URLs by the host, so this normally resolves immediately;
818
+ // TIME-BOX it so a slow font endpoint can't stall composition for seconds.
819
+ try {
820
+ if (document.fonts && document.fonts.ready) {
821
+ await Promise.race([document.fonts.ready, new Promise(function (r) { setTimeout(r, ${lt}); })]);
822
+ }
823
+ } catch {}
824
+ for (const id of Object.keys(PAGINATE)) {
825
+ const source = document.querySelector('[data-sg-frame-id="' + cssEscape(id) + '"]');
826
+ if (!source || !source.parentNode) continue;
827
+ const cfg = PAGINATE[id];
828
+ try {
829
+ const PW = cfg.width, PH = cfg.height, CW = cfg.contentWidth, CH = cfg.contentHeight;
830
+ const GAP = cfg.gap, PITCH = cfg.pitch, m = cfg.margins;
831
+ // Hoist inline <style>/<link> out of the flow into <head> so they apply
832
+ // ONCE (not duplicated per page clone) and don't sit inside the multicol
833
+ // flow. They were rewritten for columns at build time with the shared CSS.
834
+ source.querySelectorAll('style, link[rel="stylesheet"]').forEach((node) => document.head.appendChild(node));
835
+ const flowHtml = source.innerHTML;
836
+ // Two-pass deterministic geometry: multicol STRETCHES columns to fill the
837
+ // container, drifting positions, so pass 1 measures the page count at a
838
+ // wide width and pass 2 pins the flow to exactly n*CW+(n-1)*GAP (+ an
839
+ // explicit column-count) so columns are exactly CW. Measure the real
840
+ // content extent via a Range (stretched columns inflate scrollWidth and
841
+ // would invent phantom empty pages).
842
+ const master = document.createElement('div');
843
+ master.setAttribute('data-sg-measure', '');
844
+ // data-sg-doc-flow so the columnFlowResetCss media caps apply during the
845
+ // measure too (else a wide img/table overflows here and over-counts pages).
846
+ master.setAttribute('data-sg-doc-flow', '');
847
+ master.style.cssText = 'position:absolute;left:-99999px;top:0;visibility:hidden;height:' + CH + 'px;width:8000px;column-width:' + CW + 'px;column-gap:' + GAP + 'px;column-fill:auto;';
848
+ master.innerHTML = flowHtml;
849
+ document.body.appendChild(master);
850
+ const measure = () => {
851
+ const range = document.createRange();
852
+ range.selectNodeContents(master);
853
+ const right = range.getBoundingClientRect().right - master.getBoundingClientRect().left;
854
+ return Math.max(1, Math.ceil((right - 1) / PITCH));
855
+ };
856
+ let n = measure();
857
+ let exact = n * CW + (n - 1) * GAP;
858
+ master.style.width = exact + 'px';
859
+ master.style.columnCount = String(n);
860
+ n = measure();
861
+ exact = n * CW + (n - 1) * GAP;
862
+ document.body.removeChild(master);
863
+ const reported = [];
864
+ const startLeft = source.offsetLeft;
865
+ let cursorTop = source.offsetTop;
866
+ for (let i = 0; i < n; i++) {
867
+ const pid = id + '__p' + (i + 1);
868
+ const tile = document.createElement('section');
869
+ tile.setAttribute('data-sg-frame', '');
870
+ tile.setAttribute('data-sg-frame-id', pid);
871
+ tile.setAttribute('data-frame-layout', 'pages');
872
+ tile.setAttribute('data-sg-derived-from', id);
873
+ tile.setAttribute('data-sg-page', String(i + 1));
874
+ tile.setAttribute('role', 'group');
875
+ tile.setAttribute('aria-label', cfg.title + ' — page ' + (i + 1));
876
+ tile.style.width = PW + 'px';
877
+ tile.style.height = PH + 'px';
878
+ tile.style.background = cfg.background;
879
+ // PROMOTE (editor grid): place absolutely; the host's apply-layout
880
+ // refines with the same column math. Scroll modes leave the position to
881
+ // presentDocumentLayoutCss (margin:0 auto centering).
882
+ if (PROMOTE) { tile.style.left = startLeft + 'px'; tile.style.top = cursorTop + 'px'; cursorTop += PH + FRAME_GAP; }
883
+ const win = document.createElement('div');
884
+ win.setAttribute('data-sg-page-window', '');
885
+ win.style.cssText = 'position:absolute;overflow:hidden;top:' + m.top + 'px;left:' + m.left + 'px;width:' + CW + 'px;height:' + CH + 'px;';
886
+ const flow = document.createElement('div');
887
+ flow.setAttribute('data-sg-doc-flow', '');
888
+ flow.style.cssText = 'height:' + CH + 'px;width:' + exact + 'px;column-width:' + CW + 'px;column-gap:' + GAP + 'px;column-fill:auto;column-count:' + n + ';transform:translateX(' + (-i * PITCH) + 'px);';
889
+ flow.innerHTML = flowHtml;
890
+ // Clone hygiene: each tile holds a full clone of the flow, so author ids
891
+ // repeat across tiles. We do NOT strip them — the clones are IDENTICAL,
892
+ // so an SVG url(#grad)/href="#x" resolves to the first matching id (same
893
+ // gradient/anchor on every page); stripping would instead break a
894
+ // gradient's own def→fill reference WITHIN the clone. The host draws a11y
895
+ // from its own per-tile proxies, so duplicate ids don't reach the a11y tree.
896
+ win.appendChild(flow);
897
+ tile.appendChild(win);
898
+ addFurniture(tile, cfg.furniture || {}, i, n, m);
899
+ addPageNumber(tile, i, n, m, cfg.pageNumbers);
900
+ source.parentNode.insertBefore(tile, source);
901
+ reported.push({ id: pid, width: PW, height: PH });
902
+ }
903
+ source.parentNode.removeChild(source);
904
+ expansions.push({ sourceId: id, title: cfg.title, pages: reported });
905
+ } catch (error) {
906
+ console.error('Artifact column pagination failed for frame ' + id, error);
907
+ failed.push({ id: id, reason: String((error && error.message) || error) });
908
+ // Leave the source frame in place as an un-paginated single flow.
909
+ continue;
910
+ }
911
+ }
912
+ // A document's author CSS often sets a body background (the page color). The
913
+ // hoisted inline styles + the head shared CSS can paint the WHOLE hosted
914
+ // surface behind the tiles (the editor grid reads as a solid slab, present
915
+ // loses page separation). Re-assert the transparent canvas LAST so the tiles
916
+ // keep their own background and the gaps show the canvas. HOSTED_CANVAS only
917
+ // (host iframe: editor grid + live present); standalone export / PDF / PNG —
918
+ // where body IS the document backdrop — are untouched.
919
+ if (HOSTED_CANVAS) {
920
+ const canvasReset = document.createElement('style');
921
+ canvasReset.setAttribute('data-sg-canvas-reset', '');
922
+ canvasReset.textContent = 'html,body{background:transparent !important;}';
923
+ document.head.appendChild(canvasReset);
924
+ }
925
+ if (PROMOTE) {
926
+ // Renumber data-frame-index across all top-level frames in DOM order so
927
+ // selection's frameIndex stays consistent after the tiles replace the source.
928
+ Array.prototype.slice.call(document.querySelectorAll('[data-sg-frame]'))
929
+ .forEach((el, i) => el.setAttribute('data-frame-index', String(i)));
930
+ }
931
+ } finally {
932
+ finish();
933
+ }
934
+ };
935
+ if (document.readyState === 'loading') window.addEventListener('DOMContentLoaded', () => { compose(); });
936
+ else compose();
937
+ })();`}function tn(e,t){let n=t.surface??(t.host===`iframe`?`editor`:`export`),r=n===`present`,i=jt(e),a=Pt(e),o=a&&n!==`editor`&&t.host===`iframe`,s=a&&t.host===`none`&&!!t.interactive,c=t.host===`none`&&!!t.interactive&&!a&&!i&&!Nt(e),l=r&&!i&&Nt(e),u=t.host===`none`&&!!t.interactive&&!i&&Nt(e),d=t.host===`none`&&!t.interactive&&!i&&Nt(e),f=l||u||d,p=ze(e.frames,{...t.layout,measuredHeights:t.measuredHeights}),m=tt(t.assets,t.baseHref?{allowBaseOrigin:t.baseHref}:void 0),h=e=>nt(e,t.assets),g=s?It(e):c?Ht(e):i?Mt(e):f?Gt(e):r&&!a?G(e):Et(e,p,t.host===`iframe`?t.colorScheme:void 0),_=s?Ft(e):null,v=s?Bt(_.width,_.height):c?Wt():r&&!l&&!a?At(e.artifactId):kt(e.artifactId,n,i,a),y=i?[]:qt(e),b=y.length>0&&(t.host===`iframe`||Nt(e))?y:[],ee=b.length?Yt(e):e,te=t.host===`iframe`&&!l,ne=[`<meta charset="utf-8">`,`<meta http-equiv="Content-Security-Policy" content="${m}">`,t.baseHref?`<base href="${B(t.baseHref)}">`:``,`<meta name="generator" content="Studiograph Artifact Canvas">`,`<title>${Be(e.title)}</title>`,ee.shared?.head??``,Tt(e.tokens),a?`<style data-artifact-whiteboard-tokens>${bt(t.colorScheme,t.host,s)}</style>`:``,W(ee),`<style data-artifact-frame-layout>\n${g}\n</style>`,o?`<style data-artifact-cursor>html,body{cursor:grab;}</style>`:``,b.length&&!f?`<style data-artifact-pagination>\n${$t()}\n</style>`:``,b.length?`<style data-artifact-columns-reset>\n${Zt()}\n</style>`:``,rt(e.libraries??[],t.librarySources),t.host===`iframe`||s||c?`<script data-artifact-runtime>${Ve(v)}<\/script>`:``].filter(Boolean).join(`
938
+ `),re=[Dt(ee,t.host===`none`&&r&&!f&&!a&&!i),s?zt():``,c?Ut():``,b.length?`<script data-artifact-pagination>${Ve(en(b,e.artifactId,te,t.renderId??``,t.host===`iframe`,e.display?.background))}<\/script>`:``,it(),Ot(e)].filter(Boolean).join(`
939
+ `);return h(`<!doctype html>
940
+ <html data-artifact-surface="${B(n)}">
941
+ <head>
942
+ ${ne}
943
+ </head>
944
+ <body>
945
+ ${re}
946
+ </body>
947
+ </html>`)}var nn={d3:()=>M(()=>import(`./CcWaWbrI2.js`),[],import.meta.url),motion:()=>M(()=>import(`./B9KfEsQw2.js`),[],import.meta.url),three:()=>M(()=>import(`./C1B4xDs0.js`),[],import.meta.url)},rn=()=>M(()=>import(`./rjjyuGhb.js`),[],import.meta.url),an={};async function on(e){let t={};for(let n of e)an[n]??=(await nn[n]()).default,t[n]=an[n],n===`three`&&(an.threeCore??=(await rn()).default,t.threeCore=an.threeCore);return t}var sn={otf:`font/otf`,ttf:`font/ttf`,woff:`font/woff`,woff2:`font/woff2`},cn=1500;function ln(e,t,n){return new Promise(r=>{let i=!1,a=e=>{i||(i=!0,clearTimeout(o),r(e))},o=setTimeout(()=>a(n),t);e.then(e=>a(e),()=>a(n))})}function un(e){return e.match(/\.(otf|ttf|woff2|woff)$/i)?.[1]?.toLowerCase()??null}var dn=new Map;function fn(e){let t=e.shared?.files;return t?Object.entries(t).filter(([e])=>e.toLowerCase().endsWith(`.css`)):[]}function pn(e){let t=new Map;for(let[,n]of fn(e))for(let e of Ge(n))un(e.filename)&&!t.has(e.key)&&t.set(e.key,e);return[...t.values()]}function mn(e){return pn(e).length>0}function hn(e){return e&&e.mode===`token`?e.token:null}function gn(e){let t=new Uint8Array(e),n=``,r=32768;for(let e=0;e<t.length;e+=r)n+=String.fromCharCode.apply(null,t.subarray(e,e+r));return btoa(n)}function _n(e,t){let n=dn.get(e.key);if(n)return n;let r=un(e.filename)??`otf`,i=`/api/assets/${e.assetId}/${We(e.filename)}`,a=t?Ke(i,t):i,o=(async()=>{try{let e=await fetch(a,{credentials:`include`});if(!e.ok)return null;let t=await e.arrayBuffer();return`data:${sn[r]??`font/otf`};base64,${gn(t)}`}catch{return null}})();return dn.set(e.key,o),o.then(t=>{t===null&&dn.delete(e.key)}),o}async function vn(e,t){let n=pn(e);if(n.length===0)return e;let r=hn(t),i=new Map;if(await Promise.all(n.map(async e=>{let t=await ln(_n(e,r),cn,null);t&&i.set(e.key,t)})),i.size===0)return e;let a={...e.shared?.files??{}};for(let[t,n]of fn(e))a[t]=qe(n,e=>i.get(e.key)??null);return{...e,shared:{...e.shared,files:a}}}function yn(e){return!!e.libraries?.length||xn(e)}function bn(e){return e.layout===`pages`&&typeof e.geometry.width==`number`&&typeof e.geometry.height==`number`}function xn(e){return e.frames.some(bn)}function Sn(e){return{host:`iframe`,surface:e.surface??`editor`,assets:e.assets,measuredHeights:e.measuredHeights,layout:e.layout,renderId:e.renderId,colorScheme:e.colorScheme}}function Cn(e,t={}){return tn(e,Sn(t))}async function wn(e,t={}){if(!yn(e))return Cn(e,t);let[n,r]=await Promise.all([e.libraries?.length?on(e.libraries):Promise.resolve(void 0),mn(e)?vn(e,t.assets):Promise.resolve(e)]);return tn(r,{...Sn(t),librarySources:n})}var Tn=1e6;function J(e){return typeof e!=`number`||!Number.isFinite(e)||Math.abs(e)>Tn?null:e}function Y(e,t){if(typeof e==`string`)return e.slice(0,t)}function En(e){if(!e||typeof e!=`object`)return null;let t=e,n=J(t.x),r=J(t.y),i=J(t.width),a=J(t.height);return n===null||r===null||i===null||a===null||i<0||a<0?null:{x:n,y:r,width:i,height:a}}function Dn(e){if(!e||typeof e!=`object`)return null;let t=e,n=En(t.rect),r=Y(t.selector,240),i=Y(t.tagName,40);if(!n||!r||!i)return null;let a=Y(t.frameId,120)??``,o=Y(t.text,240)??``,s=J(t.frameIndex);return{frameId:a,frameIndex:s!==null&&Number.isInteger(s)?s:-1,selector:r,tagName:i,text:o,rect:n,targetId:Y(t.targetId,280)||`${a}::${r}`.slice(0,280)}}function On(e,t){if(!e||typeof e!=`object`)return null;let n=e;if(n.channel!==`studiograph-artifact`||n.artifactId!==t)return null;if(n.type===`frame-sizes`){if(!Array.isArray(n.sizes))return null;let e=[];for(let t of n.sizes.slice(0,512)){if(!t||typeof t!=`object`)continue;let n=t,r=Y(n.id,128),i=J(n.width),a=J(n.height);!r||i===null||a===null||i<0||a<0||e.push({id:r,width:Math.round(i),height:Math.round(a)})}return{channel:`studiograph-artifact`,artifactId:t,type:`frame-sizes`,sizes:e}}if(n.type===`frame-pages`){if(!Array.isArray(n.expansions))return null;let e=[];for(let t of n.expansions.slice(0,64)){if(!t||typeof t!=`object`)continue;let n=t,r=Y(n.sourceId,128);if(!r||!Array.isArray(n.pages))continue;let i=Y(n.title,240)??``,a=[];for(let e of n.pages.slice(0,512)){if(!e||typeof e!=`object`)continue;let t=e,n=Y(t.id,160),r=J(t.width),i=J(t.height);!n||r===null||i===null||r<=0||i<=0||a.push({id:n,width:Math.round(r),height:Math.round(i)})}a.length&&e.push({sourceId:r,title:i,pages:a})}let r=Y(n.renderId,64),i=[];if(Array.isArray(n.failed))for(let e of n.failed.slice(0,64)){if(!e||typeof e!=`object`)continue;let t=e,n=Y(t.id,128);n&&i.push({id:n,reason:Y(t.reason,240)??``})}return{channel:`studiograph-artifact`,artifactId:t,type:`frame-pages`,...r?{renderId:r}:{},expansions:e,...i.length?{failed:i}:{}}}if(n.type===`selection-change`){if(!Array.isArray(n.targets))return null;let e=n.targets.slice(0,24).map(Dn).filter(e=>!!e),r=Array.isArray(n.path)?n.path.slice(0,24).map(e=>Y(e,60)).filter(e=>!!e):void 0;return{channel:`studiograph-artifact`,artifactId:t,type:`selection-change`,primaryTargetId:Y(n.primaryTargetId,280),targets:e,...r&&r.length?{path:r}:{}}}if(n.type===`clear-selection`)return{channel:`studiograph-artifact`,artifactId:t,type:`clear-selection`};if(n.type===`pan-delta`){let e=J(n.dx),r=J(n.dy);return e===null||r===null?null:{channel:`studiograph-artifact`,artifactId:t,type:`pan-delta`,dx:e,dy:r}}if(n.type===`zoom-delta`){let e=J(n.delta),r=J(n.x),i=J(n.y);return e===null||r===null||i===null?null:{channel:`studiograph-artifact`,artifactId:t,type:`zoom-delta`,delta:e,x:r,y:i}}if(n.type===`pan`){if(n.phase!==`start`&&n.phase!==`move`&&n.phase!==`end`)return null;let e=J(n.x),r=J(n.y);return e===null||r===null?null:{channel:`studiograph-artifact`,artifactId:t,type:`pan`,phase:n.phase,x:e,y:r}}if(n.type===`frame-state`){let e=J(n.index),r=J(n.count);return e===null||r===null||!Number.isInteger(e)||!Number.isInteger(r)||e<0||r<0?null:{channel:`studiograph-artifact`,artifactId:t,type:`frame-state`,index:e,count:r}}if(`type`in n||n.status!==`ready`&&n.status!==`error`)return null;let r={channel:`studiograph-artifact`,artifactId:t,status:n.status},i=Y(n.message,500);return i&&(r.message=i),r}async function kn(e){let t=new TextEncoder().encode(e),n=await crypto.subtle.digest(`SHA-256`,t);return Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,`0`)).join(``).slice(0,16)}var X={minZoom:.05,maxZoom:2,frameInset:32,framePadding:64,panInertiaImpulse:.08,panInertiaDecay:.84,panInertiaMaxVelocity:64,panInertiaStop:.08,panOverscanMin:32768,panOverscanViewportMultiplier:24};function Z(e,t,n){return Math.min(n,Math.max(t,e))}function An(e,t=X){return Math.min(t.maxZoom,Math.max(t.minZoom,Math.round(e*1e3)/1e3))}function jn(e,t,n,r=X){if(!n)return{x:r.frameInset,y:r.frameInset};let i=e.width*t,a=e.height*t;return{x:i+r.framePadding<=n.width?Math.max(r.frameInset,(n.width-i)/2):r.frameInset,y:a+r.framePadding<=n.height?Math.max(r.frameInset,(n.height-a)/2):r.frameInset}}function Mn(e,t,n=X){if(!t)return e.mode===`responsive`?.9:1;let r=Math.max(1,t.width-n.framePadding),i=Math.max(1,t.height-n.framePadding),a=Math.min(r/e.width,i/e.height);return An(Math.min(1,a),n)}function Nn(e,t,n,r=X){let i=jn(e,t,n,r),a=e.width*t,o=e.height*t,s=Math.max(r.panOverscanMin,n.width*r.panOverscanViewportMultiplier),c=Math.max(r.panOverscanMin,n.height*r.panOverscanViewportMultiplier);return{minX:-s-a-i.x,maxX:n.width+s-i.x,minY:-c-o-i.y,maxY:n.height+c-i.y}}function Pn(e,t,n,r,i,a=X){let o=Nn(n,r,i,a);return{x:Z(e,o.minX,o.maxX),y:Z(t,o.minY,o.maxY)}}function Fn(e,t){return e.width<=0||e.height<=0||t.width<=0||t.height<=0?1:Math.max(t.width/e.width,t.height/e.height)}function In(e,t,n,r,i){let a=(e,t,n)=>t>=n?Z(e,n-t,0):(n-t)/2;return{x:a(e,n.width*r,i.width),y:a(t,n.height*r,i.height)}}function Ln(e,t,n){let r=e.width*t,i=e.height*t;return{minX:r>=n.width?n.width-r:(n.width-r)/2,maxX:r>=n.width?0:(n.width-r)/2,minY:i>=n.height?n.height-i:(n.height-i)/2,maxY:i>=n.height?0:(n.height-i)/2}}function Rn(e,t,n){return{x:(n.width-e.width*t)/2,y:(n.height-e.height*t)/2}}function zn(e,t){return Math.max(1,Fn(e,t))}function Bn(e,t,n,r,i=X){return{velocityX:Z(e-n*i.panInertiaImpulse,-i.panInertiaMaxVelocity,i.panInertiaMaxVelocity),velocityY:Z(t-r*i.panInertiaImpulse,-i.panInertiaMaxVelocity,i.panInertiaMaxVelocity)}}function Vn(e,t,n=X){let r=e.velocityX*n.panInertiaDecay,i=e.velocityY*n.panInertiaDecay;if(Math.abs(r)<n.panInertiaStop&&Math.abs(i)<n.panInertiaStop)return{...e,velocityX:0,velocityY:0,active:!1};let a=Z(e.panX+r,t.minX,t.maxX),o=Z(e.panY+i,t.minY,t.maxY);Math.abs(a-e.panX)<.001&&(r=0),Math.abs(o-e.panY)<.001&&(i=0);let s=Math.abs(r)>=n.panInertiaStop||Math.abs(i)>=n.panInertiaStop;return{panX:a,panY:o,velocityX:r,velocityY:i,active:s}}function Hn(){return{front:`a`,a:{srcdoc:``,token:0},b:{srcdoc:``,token:0},pending:0}}var Un=e=>e===`a`?`b`:`a`,Q=(e,t)=>t===`a`?e.a:e.b;function Wn(e,t,n){return t===`a`?{...e,a:n}:{...e,b:n}}function Gn(e,t){if(t===``){if(Q(e,e.front).srcdoc===``)return{state:e,target:null,initial:!1};let t=e.pending+1;return{state:{...Wn(e,e.front,{srcdoc:``,token:t}),pending:t},target:e.front,initial:!0}}if(Q(e,e.front).srcdoc===t)return{state:e,target:null,initial:!1};let n=Un(e.front);if(Q(e,n).srcdoc===t&&Q(e,n).token===e.pending)return{state:e,target:null,initial:!1};let r=Q(e,e.front).srcdoc===``,i=r?e.front:n,a=e.pending+1;return{state:{...Wn(e,i,{srcdoc:t,token:a}),pending:a},target:i,initial:r}}function Kn(e,t){if(t===e.front||Q(e,t).srcdoc===``||Q(e,t).token!==e.pending)return{state:e,flipped:!1,dispose:null};let n=e.front;return{state:{...e,front:t},flipped:!0,dispose:n}}function qn(e,t){return e.front===t||Q(e,t).srcdoc===``||Q(e,t).token===e.pending?e:Wn(e,t,{...Q(e,t),srcdoc:``})}function Jn(e,t){return e?.status===`error`&&t.status===`ready`?e:{status:t.status,message:t.status===`error`?t.message??`Artifact error`:null}}var Yn=e(`<div class="fc-toolbar-pair svelte-1vhlljx" aria-label="Canvas tool"><button type="button" title="Select" aria-label="Select"><!></button> <button type="button" title="Pan" aria-label="Pan"><!></button></div>`),Xn=e(`<div class="fc-toolbar svelte-1vhlljx"><!> <button type="button" class="fc-tool-btn svelte-1vhlljx" title="Reset view" aria-label="Reset view"><!></button> <div class="fc-toolbar-sep svelte-1vhlljx" aria-hidden="true"></div> <div class="fc-toolbar-pair svelte-1vhlljx" aria-label="Zoom"><button type="button" class="fc-tool-btn svelte-1vhlljx" title="Zoom out" aria-label="Zoom out"><!></button> <button type="button" class="fc-tool-btn svelte-1vhlljx" title="Zoom in" aria-label="Zoom in"><!></button></div> <span class="fc-zoom svelte-1vhlljx"> </span></div>`),Zn=e(`<button type="button" class="fc-breadcrumb-up svelte-1vhlljx"><!> <span class="fc-breadcrumb-text svelte-1vhlljx"> </span></button>`),Qn=e(`<span class="fc-breadcrumb-seg fc-breadcrumb-current svelte-1vhlljx"> </span>`),$n=e(`<span class="fc-breadcrumb-seg fc-breadcrumb-current svelte-1vhlljx" aria-current="true"><span class="fc-breadcrumb-text svelte-1vhlljx"> </span></span>`),er=e(`<nav class="fc-breadcrumb svelte-1vhlljx" aria-label="Selection"><div class="fc-breadcrumb-path svelte-1vhlljx"><!></div> <span class="fc-breadcrumb-sep fc-breadcrumb-sep-end svelte-1vhlljx" aria-hidden="true"></span> <button type="button" class="fc-breadcrumb-clear svelte-1vhlljx" title="Clear selection" aria-label="Clear selection"><!></button></nav>`),tr=e(`<div class="fc-loading svelte-1vhlljx" role="status" aria-label="Loading artifact"><!></div>`),nr=e(`<div class="fc-paginate-hint svelte-1vhlljx" role="status">This document couldn’t be paginated — showing a single page.</div>`),rr=e(`<div class="fc-card svelte-1vhlljx"></div>`),ir=e(`<iframe sandbox="allow-scripts"></iframe> <iframe sandbox="allow-scripts"></iframe>`,1),ar=e(`<div class="fc-pulse svelte-1vhlljx"></div>`),or=e(`<div></div>`),sr=e(`<input class="fc-label fc-label-input svelte-1vhlljx"/>`),cr=e(`<button type="button" tabindex="-1"><span class="fc-label-num svelte-1vhlljx"> </span> <span class="fc-label-text svelte-1vhlljx"> </span></button>`),lr=e(`<!> <!> <!>`,1),ur=e(`<div class="fc-selection svelte-1vhlljx"></div>`),dr=e(`<div class="fc-proxy svelte-1vhlljx" role="option"></div>`),fr=e(`<div class="fc-a11y svelte-1vhlljx" role="listbox" aria-label="Artifact frames" tabindex="-1"></div>`),pr=e(`<div><div class="fc-present-group svelte-1vhlljx" aria-label="Frame navigation"><button type="button" class="fc-present-btn svelte-1vhlljx" title="Previous frame" aria-label="Previous frame"><!></button> <span class="fc-present-count svelte-1vhlljx"> </span> <button type="button" class="fc-present-btn svelte-1vhlljx" title="Next frame" aria-label="Next frame"><!></button></div> <div class="fc-present-group fc-present-reset svelte-1vhlljx" aria-label="Restart"><button type="button" class="fc-present-btn fc-present-restart svelte-1vhlljx" title="Restart" aria-label="Restart"><!> <span class="svelte-1vhlljx">Restart</span></button></div></div>`),mr=e(`<div class="fc svelte-1vhlljx"><div role="region" aria-label="Artifact canvas"><!> <!> <!> <!> <div><!> <!></div> <div aria-hidden="true"><!> <!></div> <!> <!></div></div>`),hr=e(`<div class="fc svelte-1vhlljx"><div class="fc-stage svelte-1vhlljx"><div class="fc-message svelte-1vhlljx" role="alert"><p class="svelte-1vhlljx">Artifact body could not be rendered.</p> <p class="fc-message-hint svelte-1vhlljx">Ask the agent to recreate this artifact.</p></div></div></div>`);function $(e,f){t(f,!0);let m=C(f,`showToolbar`,3,!0),h=C(f,`mode`,3,`editor`),v={rects:[],width:0,height:0,columns:0},y=X.frameInset,re=2400,w=A(void 0),ce=A(null);function O(e){let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+e.charCodeAt(n)|0;return(t>>>0).toString(36)}let M=A(1),N=A(0),P=A(0),Ce=A(!1),we=null,Ee=A(`pointer`),De=A(null),ke=A(null),F=A(x(Hn())),je=A(x({a:null,b:null})),I=A(x({a:{},b:{}})),L=A(x({a:{},b:{}})),R=A(x({a:!1,b:!1})),z=A(x({a:!1,b:!1})),Pe={a:``,b:``},Fe=null,Ie=0,Be=A(`loading`),B=A(!1),Ve=null,He=()=>typeof document<`u`&&document.documentElement.getAttribute(`data-theme`)===`dark`?`dark`:`light`,Ue=A(x(He())),V=A(x([])),H=A(x([])),We=A(x(new Set)),Ke=new Map,qe={},Je=A(0),Ye=A(0),Xe=A(x({})),Ze=A(!0),Qe=null,U=A(null),$e=A(0),et=0,tt=A(!1),nt=0,rt=0,it=0,at=0,ot=null,st=0,ct=0,lt=null,ut=0,dt=null,ft=A(null),pt=A(``),mt=A(null),ht=null,gt=null,_t=A(0),vt=A(null),yt=null,bt=null,xt=0,St=``;b(()=>{f.content!==St&&(St=f.content,j(vt,null),yt=null,bt=null,xt++)});let Ct=k(()=>g(vt)??f.content),wt=Promise.resolve();function Tt(e){wt=wt.then(e,e).catch(()=>{})}let W=k(()=>{try{let e=_e(JSON.parse(g(Ct)));return e.ok?e.bundle:null}catch{return null}}),Et=k(()=>(g($e),g(U)?{width:g(U).clientWidth,height:g(U).clientHeight}:{width:1280,height:800})),Dt=k(()=>!!g(W)&&jt(g(W))),Ot=k(()=>h()===`present`&&!!g(W)&&!g(Dt)&&Nt(g(W))),kt=k(()=>g(Dt)||g(Ot)),G=k(()=>!!g(W)&&Pt(g(W))),At=k(()=>h()===`editor`&&!g(G)&&g(V).length>0),Mt=k(()=>g(H).length>=2?g(H).slice(0,-1).map((e,t)=>({label:e,index:t})).reverse():[]),Ft=k(()=>g(G)&&h()===`present`?`hand`:g(Ee)),K=k(()=>!g(kt)&&(h()===`editor`||g(G))),It=k(()=>h()===`editor`&&!!f.repo&&!!f.entityId&&!f.versionCommit&&!g(Dt));function Lt(e,t){let n=[];for(let r of e){let e=t[r.id],i=e&&bn(r)?e.pages.filter(e=>e.id.startsWith(`${r.id}__p`)).slice(0,500):[];i.length?i.forEach((t,i)=>{n.push({...r,id:t.id,title:`${r.title||e.title||`Document`} · ${i+1}`,geometry:{...r.geometry},content:``,furniture:void 0})}):n.push(r)}return n}let Rt=k(()=>g(W)?Lt(g(W).frames,g(L).a):[]),zt=k(()=>g(W)?Lt(g(W).frames,g(L).b):[]),Bt=k(()=>g(F).front===`a`?g(Rt):g(zt)),Vt=k(()=>g(F).front===`a`?g(z).a:g(z).b),Ht=k(()=>g(W)?ze(g(Rt),{measuredHeights:g(I).a,viewport:g(Et)}):v),Ut=k(()=>g(W)?ze(g(zt),{measuredHeights:g(I).b,viewport:g(Et)}):v),Wt=k(()=>g(F).front===`a`?g(Ht):g(Ut)),Gt=k(()=>({width:g(Wt).width,height:g(Wt).height})),Kt=k(()=>g(F).a.srcdoc!==``||g(F).b.srcdoc!==``),qt=k(()=>g(Wt).rects.length),Jt=k(()=>g(G)?Fn(g(Gt),g(Et)):X.minZoom),Yt=k(()=>g(G)?g(Jt):X.minZoom),Xt=k(()=>g(G)?Math.max(X.maxZoom,g(Jt)):X.maxZoom),Zt=k(()=>Z(g(Ye),0,Math.max(0,g(qt)-1))),Qt=k(()=>{let e=g(Bt)[g(Zt)];return e?{width:Le(e,g(Et)),height:Re(e,g(Xe),void 0,g(Et))}:{width:1,height:1}}),$t=k(()=>{if(g($e),h()!==`present`||!g(U))return{scale:1,tx:0,ty:0};let{width:e,height:t}=g(Qt),n=Z(Math.min((g(U).clientWidth-48)/e,(g(U).clientHeight-48)/t),.05,6);return{scale:n,tx:(g(U).clientWidth-e*n)/2,ty:(g(U).clientHeight-t*n)/2}}),q=k(()=>g(kt)?1:g(K)?g(M):g($t).scale),en=k(()=>(g($e),g(G)||g(kt)?{x:0,y:0}:g(U)?jn(g(Gt),g(q),{width:g(U).clientWidth,height:g(U).clientHeight}):{x:y,y})),tn=k(()=>g(kt)?0:g(en).x+g(N)),nn=k(()=>g(kt)?0:g(en).y+g(P)),rn=k(()=>g(kt)?`translate(0px, 0px) scale(1)`:g(K)?`translate(${g(tn)}px, ${g(nn)}px) scale(${g(q)})`:`translate(${g($t).tx}px, ${g($t).ty}px) scale(${g($t).scale})`),an=e=>g(kt)?{width:g(Et).width,height:g(Et).height}:g(K)?{width:e.width,height:e.height}:{width:g(Qt).width,height:g(Qt).height},on=k(()=>h()===`editor`&&!!g(W)&&!g(B)&&g(Be)!==`error`),sn=k(()=>`${Math.round(g(q)*100)}%`),cn=k(()=>g(W)?.display?.background??`neutral`),ln=k(()=>{if(g($e),!g(W)||g(G))return[];let e=g(W).display?.background??`neutral`;return g(Wt).rects.map((t,n)=>{let r=g(Bt)[n];return{id:t.id,index:n,label:r?.title||`Frame ${n+1}`,transparent:(r?.background??e)===`transparent`,selected:g(V).some(e=>e.frameId===t.id&&wr(e)),cx:t.x,cy:t.y,cw:t.width,ch:t.height,left:g(tn)+t.x*g(q),top:g(nn)+t.y*g(q),width:t.width*g(q),height:t.height*g(q),pulsing:g(We).has(t.id)}})}),un=k(()=>(g($e),!g(W)||h()!==`editor`||g(V).length===0?[]:g(V).filter(e=>!wr(e)).map(e=>({key:e.targetId,left:g(tn)+e.rect.x*g(q),top:g(nn)+e.rect.y*g(q),width:Math.max(1,e.rect.width*g(q)),height:Math.max(1,e.rect.height*g(q))})))),dn=()=>f.shareToken?{mode:`share`,shareToken:f.shareToken,origin:window.location.origin}:f.repo&&f.entityId?{mode:`token`,token:g(w)??null,origin:window.location.origin}:{mode:`none`},fn=k(()=>Ge(f.content).length>0);b(()=>{if(!f.repo||!f.entityId||!g(fn)){j(w,void 0),j(ce,null);return}let e=f.versionCommit??O(f.content),t=f.repo,n=f.entityId,r=f.versionCommit,i=!1;return he(t,n,{version:e,commit:r}).then(t=>{i||(j(w,t,!0),j(ce,e,!0))}).catch(()=>{i||(j(w,void 0),j(ce,e,!0))}),()=>{i=!0}});let pn=k(()=>!f.shareToken&&!!f.repo&&!!f.entityId&&g(fn)&&g(ce)!==(f.versionCommit??O(f.content)));b(()=>{if(!g(W))return;j(Be,`loading`);let e=f.viewKey??g(W).artifactId;e!==ht&&(j(F,Hn(),!0),j(je,{a:null,b:null},!0),j(I,{a:{},b:{}},!0),j(L,{a:{},b:{}},!0),j(R,{a:!1,b:!1},!0),j(z,{a:!1,b:!1},!0),Fe&&=(clearTimeout(Fe),null),ht=e,j(N,0),j(P,0),j(Ce,!1),we=null,j(Ye,0),j(Xe,{},!0),j(Ze,!0),Q(),j(Je,0),j(We,new Set,!0),qe={},j(B,h()!==`editor`),ni(),Qr(),si(),vn(),j(M,te(()=>mn()),!0))}),b(()=>{if(!g(G)||!g(U))return;g($e);let e=g(Gt),t={width:g(U).clientWidth,height:g(U).clientHeight};t.width<=0||t.height<=0||te(()=>{if(g(Ce)){let n=Fn(e,t),r=Z(g(M),n,Math.max(X.maxZoom,n));r!==g(M)&&j(M,r,!0);let i=In(g(N),g(P),e,g(M),t);j(N,i.x,!0),j(P,i.y,!0)}else{let n=zn(e,t);j(M,n,!0);let r=Rn(e,n,t);j(N,r.x,!0),j(P,r.y,!0)}})}),b(()=>{let e=g(W),t=++Ie;if(!e){Br(``);return}if(g(pn))return;let n=String(t),r={surface:h()===`present`?`present`:`editor`,assets:dn(),renderId:n,colorScheme:g(G)?g(Ue):void 0};if(!yn(e)){Br(Cn(e,r),n);return}let i=!1;return wn(e,r).then(r=>{!i&&Ie===t&&g(W)?.artifactId===e.artifactId&&Br(r,n)}).catch(e=>{i||(j(Be,`error`),console.error(`Artifact resources failed to load`,e))}),()=>{i=!0}}),b(()=>{let e=f.content;gt!==null&&e!==gt&&(j(_t,g(_t)+1),Q(!0)),gt=e}),b(()=>{if(typeof document>`u`)return;j(Ue,He(),!0);let e=new MutationObserver(()=>{j(Ue,He(),!0)});return e.observe(document.documentElement,{attributes:!0,attributeFilter:[`data-theme`]}),()=>e.disconnect()}),b(()=>{if(!g(U))return;let e=new ResizeObserver(()=>{et+=1,j($e,et,!0)});return e.observe(g(U)),et+=1,j($e,et,!0),()=>e.disconnect()}),b(()=>()=>{ni(),Qr(),_i(),vn(),Fe&&clearTimeout(Fe),Qe&&clearTimeout(Qe);for(let e of Ke.values())clearTimeout(e);Ke.clear()});function mn(){if(!g(U))return 1;let e={width:g(U).clientWidth,height:g(U).clientHeight};return Mn(g(Gt),e)}function hn(){h()!==`editor`||g(G)||(j(M,mn(),!0),j(N,0),j(P,0),j(Ce,!1),ni(),Qr())}function gn(){if(ni(),Qr(),g(G)){j(Ce,!1);let e=Gr();if(e){let t=zn(g(Gt),e);j(M,t,!0);let n=Rn(g(Gt),t,e);j(N,n.x,!0),j(P,n.y,!0)}return}hn()}function _n(){g(B)||(vn(),g(Ce)||hn(),j(B,!0))}function vn(){Ve&&=(clearTimeout(Ve),null)}function xn(){if(h()!==`editor`||g(B)||!g(Kt))return;vn();let e=Sn(g(F).front)?4e3:1200;Ve=setTimeout(()=>{Ve=null,_n()},e)}function Sn(e){return!g(W)||g(R)[e]?!1:g(W).frames.some(bn)}function Tn(){if(!g(B)){if(Sn(g(F).front)){xn();return}_n()}}function J(e){if(!g(W))return;let t=ze(Lt(g(W).frames,g(L)[e]),{measuredHeights:g(I)[e],viewport:g(Et)});if(Ur(e,{type:`apply-layout`,rects:t.rects.map(e=>({id:e.id,x:e.x,y:e.y,width:e.width})),width:t.width,height:t.height}),e===g(F).front){if(!g(Ce)){hn();return}En(t)}}function Y(){if(!g(U))return null;let e=g(q)||1,t=(g(U).clientWidth/2-g(tn))/e,n=(g(U).clientHeight/2-g(nn))/e,r=null,i=1/0;for(let e of g(Wt).rects){if(t>=e.x&&t<=e.x+e.width&&n>=e.y&&n<=e.y+e.height)return e.id;let a=e.x+e.width/2-t,o=e.y+e.height/2-n,s=a*a+o*o;s<i&&(i=s,r=e.id)}return r}function En(e){let t=we;if(!t||!g(U))return;let n=e.rects.find(e=>e.id===t);if(!n)return;we=null;let r={width:g(U).clientWidth,height:g(U).clientHeight},i=g(q)||1,a=jn({width:e.width,height:e.height},i,r);j(N,r.width/2-a.x-(n.x+n.width/2)*i),j(P,r.height/2-a.y-(n.y+n.height/2)*i),ni(),Qr()}function Dn(e,t){if(!g(W))return;let n={...g(L)[e]};for(let e of t){let t=g(W).frames.find(t=>t.id===e.sourceId);!t||t.layout!==`pages`||(n[e.sourceId]=e)}j(L,e===`a`?{...g(L),a:n}:{...g(L),b:n},!0),j(R,e===`a`?{...g(R),a:!0}:{...g(R),b:!0},!0),h()===`editor`?J(e):Ur(e,{type:`set-frame`,index:g(Zt)}),e===g(F).front&&Tn()}b(()=>{h()!==`editor`||g(B)||!g(Kt)||Ve||xn()});function Un(e){g(Ee)!==e&&(j(Ee,e,!0),Wr({type:`set-tool`,tool:e}),si(),ni(),Qr())}function Q(e=!1){j(V,[],!0),j(H,[],!0),me.setSelectedArtifactTarget(null),yr([]),e&&Wr({type:`clear-selection`})}let Wn,$=null,gr;function _r(e){gr?.abort(),gr=new AbortController,e(gr.signal).catch(()=>{})}function vr(e,t){$&&$.repo===e&&$.id===t&&($=null),_r(n=>fe(e,t,n))}function yr(e,t,n){if(h()!==`editor`||!f.repo||!f.entityId)return;let r=f.repo,i=f.entityId;Wn&&clearTimeout(Wn),Wn=setTimeout(()=>{if(e.length===0){vr(r,i);return}$={repo:r,id:i};let a={targets:e.map(e=>({frameId:e.frameId,frameIndex:e.frameIndex,selector:e.selector,tagName:e.tagName,text:e.text})),...n?{primaryTargetId:n}:{},...t&&t.length?{path:t}:{}};_r(e=>pe(r,i,a,e))},300)}b(()=>{let e=f.repo,t=f.entityId;te(()=>{if($&&($.repo!==e||$.id!==t)){let e=$;vr(e.repo,e.id)}})}),oe(()=>{if(Wn&&clearTimeout(Wn),$){let e=$;vr(e.repo,e.id)}});function br(e){e<0||e>=g(H).length-1||Wr({type:`select-ancestor`,index:e})}function xr(e){let t=e.text?.trim();return`- ${[t?t.length>60?`${t.slice(0,57)}...`:t:e.tagName,e.frameId?`frame=${e.frameId}`:e.frameIndex>=0?`frame=${e.frameIndex+1}`:null,e.selector?`selector=${e.selector}`:null,t?`text="${t}"`:null,`${Math.round(e.rect.width)}x${Math.round(e.rect.height)}`].filter(Boolean).join(` · `)}`}function Sr(e,t,n){if(!g(W)||h()!==`editor`)return;if(j(V,e,!0),j(H,e.length===1&&t?t:[],!0),yr(e,g(H),n),e.length===0){me.setSelectedArtifactTarget(null);return}let r=`${e.length} selected\n${e.map(xr).join(`
948
+ `)}`.slice(0,1600);me.setSelectedArtifactTarget(r)}let Cr=e=>`[data-sg-frame-id="${e}"]`,wr=e=>e.selector===Cr(e.frameId);function Tr(e){if(!g(W)||h()!==`editor`)return;let t=g(Wt).rects[e],n=g(Bt)[e];!t||!n||Sr([{frameId:n.id,frameIndex:e,selector:Cr(n.id),tagName:`section`,text:n.title??``,rect:{x:t.x,y:t.y,width:t.width,height:t.height},targetId:`${n.id}::${Cr(n.id)}`}])}async function Er(e,t,n,r,i,a,o,s){if(e===xt)try{let o=await de(r,i,yt??await kn(t),a);if(e!==xt)return;yt=o.hash,bt=n}catch(t){e===xt&&(xt++,j(vt,bt,!0),bt===null&&(yt=null));let n=t?.status;ge.error(n===409?o:s)}}function Dr(e){let t=g(Bt)[e]?.id;return!t||!g(W)?null:g(W).frames.some(e=>e.id===t)?t:null}function Or(e){if(!g(It)||!g(W))return;let t=Dr(e);t&&(j(ft,e,!0),j(pt,g(W).frames.find(e=>e.id===t)?.title??``,!0))}function kr(){j(ft,null),j(pt,``)}b(()=>{g(ft)!==null&&g(mt)&&(g(mt).focus(),g(mt).select())});function Ar(){let e=g(ft);if(e===null||!g(W)||!f.repo||!f.entityId){kr();return}let t=Dr(e),n=t?g(W).frames.find(e=>e.id===t):void 0;if(!t||!n){kr();return}let r=g(pt).trim(),i=n.title??``;if(j(ft,null),j(pt,``),r===i)return;let a=g(W).frames.map(e=>e.id===t?(()=>{let t={...e};return r?t.title=r:delete t.title,t})():e),o=f.content,s=JSON.stringify({...g(W),frames:a},null,2)+`
949
+ `;j(vt,s);let c=f.repo,l=f.entityId,u=xt;Tt(()=>Er(u,o,s,c,l,[{op:`set_frame_meta`,frameId:t,title:r}],`This artifact changed elsewhere — the rename was not applied.`,`Could not rename the frame.`))}function jr(e){e.key===`Enter`?(e.preventDefault(),Ar()):e.key===`Escape`&&(e.preventDefault(),kr())}function Mr(){if(!g(W))return;let e={};for(let t of g(W).frames)e[t.id]=O(t.content);let t=typeof window<`u`&&window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches;if(Object.keys(qe).length>0&&!t)for(let[t,n]of Object.entries(e))qe[t]!==n&&Nr(t);qe=e}function Nr(e){let t=new Set(g(We));t.add(e),j(We,t,!0);let n=Ke.get(e);n&&clearTimeout(n),Ke.set(e,setTimeout(()=>{let t=new Set(g(We));t.delete(e),j(We,t,!0),Ke.delete(e)},re))}function Pr(e){return e&&g(De)?.contentWindow===e?`a`:e&&g(ke)?.contentWindow===e?`b`:null}function Fr(e){let t=g(W);if(!t)return;let n=Pr(e.source);if(!n)return;let r=On(e.data,t.artifactId);if(r){if(!(`type`in r)){Rr(n,Jn(g(je)[n],{status:r.status,message:r.message})),n===g(F).front&&zr(n);return}if(r.type===`frame-sizes`){h()===`present`?Ir(r.sizes):Lr(n,r.sizes);return}if(r.type===`frame-pages`){if(r.renderId&&r.renderId!==Pe[n])return;Dn(n,r.expansions);let e=!!(r.failed&&r.failed.length>0);j(z,n===`a`?{...g(z),a:e}:{...g(z),b:e},!0);return}if(n===g(F).front){if(r.type===`frame-state`){j(Ye,Z(r.index,0,Math.max(0,r.count-1)),!0),xi();return}if(r.type===`selection-change`){Sr(r.targets,r.path,r.primaryTargetId);return}if(r.type===`clear-selection`){Q();return}if(r.type===`pan-delta`){ti(r.dx,r.dy,{inertial:!0});return}if(r.type===`zoom-delta`){Zr(r.delta,qr(r.x,r.y));return}if(r.type===`pan`){ci(r.phase,r.x,r.y);return}}}}function Ir(e){let t={...g(Xe)},n=!1;for(let r of e)r.height>0&&t[r.id]!==r.height&&(t[r.id]=r.height,n=!0);n&&j(Xe,t,!0)}function Lr(e,t){if(!g(W))return;let n=new Set(g(W).frames.filter(e=>e.geometry.height===`auto`).map(e=>e.id)),r={...g(I)[e]},i=!1;for(let e of t)n.has(e.id)&&r[e.id]!==e.height&&(r[e.id]=e.height,i=!0);i&&(j(I,e===`a`?{...g(I),a:r}:{...g(I),b:r},!0),J(e))}function Rr(e,t){j(je,e===`a`?{...g(je),a:t}:{...g(je),b:t},!0)}function zr(e){let t=e===`a`?g(je).a:g(je).b;j(Be,t?t.status:`ready`,!0),g(B)||(g(Be)===`error`?_n():Tn())}function Br(e,t=``){we=h()===`editor`&&g(B)&&g(Ce)&&e!==``&&Object.keys(g(L)[g(F).front]??{}).length>0?Y():null;let n=Gn(g(F),e);if(n.target===null){e!==``&&zr(g(F).front);return}Rr(n.target,null),j(I,n.target===`a`?{...g(I),a:{}}:{...g(I),b:{}},!0),j(L,n.target===`a`?{...g(L),a:{}}:{...g(L),b:{}},!0),j(R,n.target===`a`?{...g(R),a:!1}:{...g(R),b:!1},!0),j(z,n.target===`a`?{...g(z),a:!1}:{...g(z),b:!1},!0),Pe=n.target===`a`?{...Pe,a:t}:{...Pe,b:t},j(F,n.state,!0)}function Vr(e){let t=Kn(g(F),e);j(F,t.state,!0),t.flipped?(zr(e),Wr({type:`set-tool`,tool:g(Ft)}),Mr(),Tn(),g(R)[e]&&J(e),t.dispose&&Hr(t.dispose)):e===t.state.front&&(t.state.front===`a`?t.state.a:t.state.b).srcdoc!==``&&(zr(e),Wr({type:`set-tool`,tool:g(Ft)}),Mr(),Tn())}function Hr(e){Fe&&clearTimeout(Fe),Fe=setTimeout(()=>{Fe=null;let t=qn(g(F),e),n=t!==g(F);j(F,t,!0),n&&(Rr(e,null),j(I,e===`a`?{...g(I),a:{}}:{...g(I),b:{}},!0),j(L,e===`a`?{...g(L),a:{}}:{...g(L),b:{}},!0),j(R,e===`a`?{...g(R),a:!1}:{...g(R),b:!1},!0),j(z,e===`a`?{...g(z),a:!1}:{...g(z),b:!1},!0))},280)}function Ur(e,t){let n=g(W),r=g(e===`a`?De:ke);!n||!r?.contentWindow||r.contentWindow.postMessage({channel:`studiograph-artifact-host`,artifactId:n.artifactId,...t},`*`)}function Wr(e){Ur(g(F).front,e)}function Gr(){return g(U)?{width:g(U).clientWidth,height:g(U).clientHeight}:null}function Kr(e,t){let n=Gr();return!n||!g(K)?{x:e,y:t}:g(G)?In(e,t,g(Gt),g(M),n):Pn(e,t,g(Gt),g(M),n)}function qr(e,t){return g(K)?{x:g(tn)+e*g(M),y:g(nn)+t*g(M)}:null}function Jr(){return g(U)?{x:g(U).clientWidth/2,y:g(U).clientHeight/2}:null}function Yr(e,t=Jr()){let n=An(e,{minZoom:g(Yt),maxZoom:g(Xt)});if(Math.abs(n-g(M))<5e-4)return;j(Ce,!0);let r=Gr();if(!r||!g(K)||!t){j(M,n,!0);return}let i=e=>g(G)?{x:0,y:0}:jn(g(Gt),e,r),a=i(g(M)),o=(t.x-a.x-g(N))/g(M),s=(t.y-a.y-g(P))/g(M),c=i(n);j(M,n,!0);let l=Kr(t.x-c.x-o*n,t.y-c.y-s*n);j(N,l.x,!0),j(P,l.y,!0)}function Xr(e,t=Jr()){Yr(g(M)*Math.exp(-e*.006),t)}function Zr(e,t=Jr()){g(K)&&(ni(),Xr(e,t),ei(e,t))}function Qr(){lt!==null&&(cancelAnimationFrame(lt),lt=null),ut=0,dt=null}function $r(){if(ut*=.86,Math.abs(ut)<.08||g(M)<=g(Yt)||g(M)>=X.maxZoom||!g(K)){Qr();return}Xr(ut,dt),lt=requestAnimationFrame($r)}function ei(e,t){g(K)&&(dt=t,ut=Z(ut+e*.16,-18,18),lt===null&&(lt=requestAnimationFrame($r)))}function ti(e,t,n={}){if(!g(K))return;j(Ce,!0);let r=Kr(g(N)-e,g(P)-t);j(N,r.x,!0),j(P,r.y,!0),n.inertial&&ii(e,t)}function ni(){ot!==null&&(cancelAnimationFrame(ot),ot=null),st=0,ct=0}function ri(){let e=Gr();if(!g(K)||!e){ni();return}let t=Vn({panX:g(N),panY:g(P),velocityX:st,velocityY:ct},g(G)?Ln(g(Gt),g(M),e):Nn(g(Gt),g(M),e));if(j(N,t.panX,!0),j(P,t.panY,!0),st=t.velocityX,ct=t.velocityY,!t.active){ni();return}ot=requestAnimationFrame(ri)}function ii(e,t){let n=Bn(st,ct,e,t);st=n.velocityX,ct=n.velocityY,ot===null&&(ot=requestAnimationFrame(ri))}function ai(e,t){ni(),Qr(),j(tt,!0),nt=e,rt=t,it=g(N),at=g(P)}function oi(e,t){if(!g(tt))return;let n=Kr(it+(e-nt),at+(t-rt));j(N,n.x,!0),j(P,n.y,!0),j(Ce,!0)}function si(){j(tt,!1)}function ci(e,t,n){!g(K)||g(Ft)!==`hand`||(e===`start`?ai(t,n):e===`move`?oi(t,n):si())}let li=null,ui=null,di=null,fi=null;function pi(e){let t=e.deltaMode===1?16:e.deltaMode===2?g(U)?.clientHeight??window.innerHeight:1;return{dx:e.deltaX*t,dy:e.deltaY*t}}function mi(e){if(!g(K))return;let t=pi(e);if(!(Math.abs(t.dx)<.01&&Math.abs(t.dy)<.01)){if(e.ctrlKey||e.metaKey){di=di?{delta:di.delta+t.dy,clientX:e.clientX,clientY:e.clientY}:{delta:t.dy,clientX:e.clientX,clientY:e.clientY},fi===null&&(fi=requestAnimationFrame(gi)),e.preventDefault();return}li=li?{dx:li.dx+t.dx,dy:li.dy+t.dy}:{dx:t.dx,dy:t.dy},ui===null&&(ui=requestAnimationFrame(hi)),e.preventDefault()}}function hi(){if(ui=null,!li)return;let e=li;li=null,ti(e.dx,e.dy,{inertial:!0})}function gi(){if(fi=null,!di)return;let e=di;di=null;let t=g(U)?.getBoundingClientRect();Zr(e.delta,t?{x:e.clientX-t.left,y:e.clientY-t.top}:null)}function _i(){ui!==null&&(cancelAnimationFrame(ui),ui=null),li=null,fi!==null&&(cancelAnimationFrame(fi),fi=null),di=null}function vi(e){let t=e.target;h()===`editor`&&!t?.closest(`.fc-viewport`)&&!t?.closest(`.fc-toolbar`)&&Q(!0),!(!g(K)||g(Ft)!==`hand`||e.button!==0)&&(ai(e.clientX,e.clientY),e.currentTarget.setPointerCapture(e.pointerId),e.preventDefault())}function yi(e){h()===`present`&&xi(),oi(e.clientX,e.clientY),g(tt)&&e.preventDefault()}function bi(e){if(!g(tt))return;let t=e.currentTarget;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId),si()}function xi(){h()===`present`&&(j(Ze,!0),Qe&&clearTimeout(Qe),Qe=setTimeout(()=>{j(Ze,!1),Qe=null},2500))}function Si(e){h()!==`present`||g(qt)<=1||(Wr({type:`set-frame`,index:(g(Zt)+e+g(qt))%g(qt)}),xi())}function Ci(e){h()===`present`&&(Wr({type:`set-frame`,index:Z(Math.round(e),0,Math.max(0,g(qt)-1))}),xi())}b(()=>{h()===`present`&&g(W)&&xi()});function wi(e){if(h()===`editor`&&e.key===`Escape`&&g(V).length>0){Q(!0),e.preventDefault();return}h()!==`present`||g(Ot)||g(qt)<=1||e.target?.closest(`input,textarea,select,[contenteditable="true"]`)||e.altKey||e.ctrlKey||e.metaKey||(e.key===`ArrowRight`||e.key===`PageDown`||e.key===` `?(Si(1),e.preventDefault()):e.key===`ArrowLeft`||e.key===`PageUp`?(Si(-1),e.preventDefault()):e.key===`Home`?(Ci(0),e.preventDefault()):e.key===`End`&&(Ci(g(qt)-1),e.preventDefault()))}function Ti(e){if(!g(W)||h()!==`editor`)return;let t=g(Wt).rects.length,n=Math.max(1,g(Wt).columns),r=g(Je);if(e.key===`ArrowRight`)r=Math.min(t-1,g(Je)+1);else if(e.key===`ArrowLeft`)r=Math.max(0,g(Je)-1);else if(e.key===`ArrowDown`)r=Math.min(t-1,g(Je)+n);else if(e.key===`ArrowUp`)r=Math.max(0,g(Je)-n);else if(e.key===`Enter`||e.key===` `){Tr(g(Je)),e.preventDefault();return}else return;e.preventDefault(),j(Je,r,!0),document.getElementById(`fc-proxy-${r}`)?.focus()}var Ei=ue();o(`message`,ne,Fr),o(`keydown`,ne,wi);var Di=ae(Ei),Oi=e=>{var t=mr(),c=T(t);let f;var v=T(c),y=e=>{var t=Xn(),a=T(t),c=e=>{var t=Yn(),i=T(t);let a;Te(T(i),{size:16}),r(i);var o=S(i,2);let s;Oe(T(o),{size:16}),r(o),r(t),E(()=>{a=u(i,1,`fc-tool-btn svelte-1vhlljx`,null,a,{active:g(Ft)===`pointer`}),D(i,`aria-pressed`,g(Ft)===`pointer`),s=u(o,1,`fc-tool-btn svelte-1vhlljx`,null,s,{active:g(Ft)===`hand`}),D(o,`aria-pressed`,g(Ft)===`hand`)}),n(`click`,i,()=>Un(`pointer`)),n(`click`,o,()=>Un(`hand`)),l(e,t)};s(a,e=>{h()===`editor`&&e(c)});var d=S(a,2);Ae(T(d),{size:16}),r(d);var f=S(d,4),p=T(f);Ne(T(p),{size:16}),r(p);var m=S(p,2);Me(T(m),{size:16}),r(m),r(f);var _=S(f,2),v=T(_,!0);r(_),r(t),E(()=>i(v,g(sn))),n(`pointerdown`,t,e=>e.stopPropagation()),o(`wheel`,t,e=>e.stopPropagation()),n(`click`,d,gn),n(`click`,p,()=>Yr(g(M)-.1)),n(`click`,m,()=>Yr(g(M)+.1)),l(e,t)};s(v,e=>{m()&&!g(Dt)&&(h()===`editor`||g(G))&&!g(At)&&e(y)});var b=S(v,2),te=e=>{var t=er(),a=T(t),c=T(a),u=e=>{var t=ue();ie(ae(t),17,()=>g(Mt),e=>e.index,(e,t)=>{var a=Zn(),o=T(a);be(o,{size:16});var s=S(o,2),c=T(s,!0);r(s),d(s,e=>Se?.(e)),r(a),E(()=>{D(a,`title`,`Select ${g(t).label}`),i(c,g(t).label)}),n(`click`,a,()=>br(g(t).index)),l(e,a)}),l(e,t)},f=e=>{var t=Qn(),n=T(t);r(t),E(()=>i(n,`${g(V).length??``} selected`)),l(e,t)},p=e=>{var t=$n(),n=T(t),a=T(n,!0);r(n),d(n,e=>Se?.(e)),r(t),E(()=>i(a,g(H)[g(H).length-1])),l(e,t)};s(c,e=>{g(H).length>=2?e(u):g(H).length===0?e(f,1):e(p,-1)}),r(a);var m=S(a,4);ye(T(m),{size:14}),r(m),r(t),n(`pointerdown`,t,e=>e.stopPropagation()),o(`wheel`,t,e=>e.stopPropagation()),n(`click`,m,()=>Q(!0)),l(e,t)};s(b,e=>{g(At)&&e(te)});var ne=S(b,2),x=e=>{var t=tr();ve(T(t),{size:28}),r(t),l(e,t)};s(ne,e=>{g(on)&&e(x)});var oe=S(ne,2),C=e=>{l(e,nr())};s(oe,e=>{g(Vt)&&g(B)&&h()===`editor`&&e(C)});var w=S(oe,2);let ce,O;var k=T(w),A=e=>{var t=ue();ie(ae(t),17,()=>g(ln),e=>e.id,(e,t)=>{var n=ue(),r=ae(n),i=e=>{var n=rr();let r;E(()=>r=le(n,``,r,{left:`${g(t).cx}px`,top:`${g(t).cy}px`,width:`${g(t).cw}px`,height:`${g(t).ch}px`})),l(e,n)};s(r,e=>{g(t).transparent||e(i)}),l(e,n)}),l(e,t)};s(k,e=>{h()===`editor`&&!g(Dt)&&e(A)});var de=S(k,2),fe=e=>{var t=ir(),n=ae(t);let r,i;ee(n,e=>j(De,e),()=>g(De));var s=S(n,2);let c,d;ee(s,e=>j(ke,e),()=>g(ke)),E((e,t)=>{D(n,`title`,g(W).title),r=u(n,1,`fc-frame svelte-1vhlljx`,null,r,{"is-back":g(F).front!==`a`}),D(n,`aria-hidden`,g(F).front!==`a`),D(n,`srcdoc`,g(F).a.srcdoc),i=le(n,``,i,e),D(s,`title`,g(W).title),c=u(s,1,`fc-frame svelte-1vhlljx`,null,c,{"is-back":g(F).front!==`b`}),D(s,`aria-hidden`,g(F).front!==`b`),D(s,`srcdoc`,g(F).b.srcdoc),d=le(s,``,d,t)},[()=>({width:`${Math.max(1,an(g(Ht)).width)}px`,height:`${Math.max(1,an(g(Ht)).height)}px`}),()=>({width:`${Math.max(1,an(g(Ut)).width)}px`,height:`${Math.max(1,an(g(Ut)).height)}px`})]),o(`load`,n,()=>Vr(`a`)),a(n),o(`load`,s,()=>Vr(`b`)),a(s),l(e,t)};s(de,e=>{g(Kt)&&e(fe)}),r(w);var pe=S(w,2);let me;var he=T(pe);ie(he,17,()=>g(ln),e=>e.id,(e,t)=>{var a=lr(),c=ae(a),d=e=>{var n=ar();let r;E(()=>r=le(n,``,r,{"--fc-pulse-ms":`${re}ms`,left:`${g(t).left}px`,top:`${g(t).top}px`,width:`${g(t).width}px`,height:`${g(t).height}px`})),l(e,n)};s(c,e=>{g(t).pulsing&&e(d)});var f=S(c,2),p=e=>{var n=or();let r,i;E(()=>{r=u(n,1,`fc-frame-border svelte-1vhlljx`,null,r,{selected:g(t).selected}),i=le(n,``,i,{left:`${g(t).left}px`,top:`${g(t).top}px`,width:`${g(t).width}px`,height:`${g(t).height}px`})}),l(e,n)};s(f,e=>{h()===`editor`&&!g(Dt)&&(g(t).transparent||g(t).selected)&&e(p)});var m=S(f,2),v=e=>{var a=ue(),c=ae(a),d=e=>{var r=sr();_(r);let i;ee(r,e=>j(mt,e),()=>g(mt)),E(e=>{D(r,`aria-label`,`Rename frame ${g(t).index+1}`),i=le(r,``,i,e)},[()=>({left:`${g(t).left}px`,top:`${g(t).top}px`,"max-width":`${Math.max(60,g(t).width)}px`})]),n(`pointerdown`,r,e=>e.stopPropagation()),n(`keydown`,r,jr),o(`blur`,r,()=>Ar()),se(r,()=>g(pt),e=>j(pt,e)),l(e,r)},f=e=>{var a=cr();let o,s;var c=T(a),d=T(c,!0);r(c);var f=S(c,2),p=T(f,!0);r(f),r(a),E(e=>{o=u(a,1,`fc-label svelte-1vhlljx`,null,o,{selected:g(t).selected}),D(a,`title`,g(It)?`Double-click to rename · click to select ${g(t).label}`:`Select ${g(t).label}`),s=le(a,``,s,e),i(d,g(t).index+1),i(p,g(t).label)},[()=>({left:`${g(t).left}px`,top:`${g(t).top}px`,"max-width":`${Math.max(60,g(t).width)}px`})]),n(`pointerdown`,a,e=>e.stopPropagation()),n(`click`,a,()=>Tr(g(t).index)),n(`dblclick`,a,e=>{e.stopPropagation(),e.preventDefault(),Or(g(t).index)}),l(e,a)};s(c,e=>{g(ft)===g(t).index?e(d):e(f,-1)}),l(e,a)};s(m,e=>{h()===`editor`&&!g(Dt)&&e(v)}),l(e,a)}),ie(S(he,2),17,()=>g(un),e=>e.key,(e,t)=>{var n=ur();let r;E(()=>r=le(n,``,r,{left:`${g(t).left}px`,top:`${g(t).top}px`,width:`${g(t).width}px`,height:`${g(t).height}px`})),l(e,n)}),r(pe);var ge=S(pe,2),N=e=>{var t=fr();ie(t,21,()=>g(ln),e=>e.id,(e,t)=>{var n=dr();let r;E(e=>{D(n,`id`,`fc-proxy-${g(t).index}`),D(n,`aria-selected`,e),D(n,`aria-label`,`Frame ${g(t).index+1} of ${g(ln).length}: ${g(t).label}`),D(n,`tabindex`,g(t).index===g(Je)?0:-1),r=le(n,``,r,{left:`${g(t).left}px`,top:`${g(t).top}px`,width:`${g(t).width}px`,height:`${g(t).height}px`})},[()=>g(V).some(e=>e.frameId===g(t).id)]),o(`focus`,n,()=>j(Je,g(t).index,!0)),l(e,n)}),r(t),n(`keydown`,t,Ti),l(e,t)};s(ge,e=>{h()===`editor`&&!g(Dt)&&g(ln).length>0&&e(N)});var _e=S(ge,2),P=e=>{var t=pr();let a;var s=T(t),c=T(s);be(T(c),{size:16}),r(c);var d=S(c,2),f=T(d);r(d);var m=S(d,2);xe(T(m),{size:16}),r(m),r(s);var h=S(s,2),_=T(h);Ae(T(_),{size:16}),p(2),r(_),r(h),r(t),E(()=>{a=u(t,1,`fc-present-controls svelte-1vhlljx`,null,a,{visible:g(Ze)}),i(f,`${g(Zt)+1} / ${g(qt)??``}`)}),n(`pointerdown`,t,e=>e.stopPropagation()),n(`pointermove`,t,xi),o(`wheel`,t,e=>e.stopPropagation()),n(`click`,c,()=>Si(-1)),n(`click`,m,()=>Si(1)),n(`click`,_,()=>Ci(0)),l(e,t)};s(_e,e=>{h()===`present`&&!g(Ot)&&g(qt)>1&&e(P)}),r(c),ee(c,e=>j(U,e),()=>g(U)),r(t),E(e=>{f=u(c,1,`fc-stage svelte-1vhlljx`,null,f,{panning:g(tt),"hand-tool":g(Ft)===`hand`,whiteboard:g(G)}),D(c,`data-mode`,h()),D(c,`data-background`,g(cn)),ce=u(w,1,`fc-viewport svelte-1vhlljx`,null,ce,{revealing:!g(B)&&h()===`editor`}),O=le(w,``,O,e),me=u(pe,1,`fc-overlay svelte-1vhlljx`,null,me,{revealing:!g(B)&&h()===`editor`})},[()=>({width:`${Math.max(1,an(g(Wt)).width)}px`,height:`${Math.max(1,an(g(Wt)).height)}px`,transform:g(rn)})]),n(`pointerdown`,c,vi),n(`pointermove`,c,yi),n(`pointerup`,c,bi),o(`pointercancel`,c,bi),o(`lostpointercapture`,c,bi),o(`wheel`,c,mi),l(e,t)},ki=e=>{var t=hr(),n=T(t);r(t),E(()=>D(n,`data-mode`,h())),l(e,t)};s(Di,e=>{g(W)?e(Oi):e(ki,-1)}),l(e,Ei),c()}m([`pointerdown`,`pointermove`,`pointerup`,`click`,`keydown`,`dblclick`]);export{tn as n,$ as t};