shotops-mcp 0.10.0 → 0.11.0

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.
@@ -1 +0,0 @@
1
- import{S as Ln,G as Rn,A as Fn,D as ve,M as Nn,R as _n,a as Bn,C as zn,b as jn,c as Dn}from"./three-addons-zF8BveTt.js";import{aa as Wn,P as Ue,b as Hn,V as G,a4 as Un,l as Dt,C as R,ab as Gn,J as ot,$ as ne,M as $n,a2 as Vn,B as qn,a3 as Xn,a7 as Kn,ac as rt,ad as Yn,ae as Jn}from"./three-webgl-BAyyruEx.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))o(r);new MutationObserver(r=>{for(const a of r)if(a.type==="childList")for(const i of a.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&o(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const a={};return r.integrity&&(a.integrity=r.integrity),r.referrerPolicy&&(a.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?a.credentials="include":r.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function o(r){if(r.ep)return;r.ep=!0;const a=n(r);fetch(r.href,a)}})();const $={lineHeight:1.2,bandInset:.06,bandCenter:.5,padX:.07},ie={sizePt:{min:20,max:120},maxWidth:{min:.1,max:1},lineHeight:{min:.5,max:3},bandInset:{min:0,max:.5},bandCenter:{min:0,max:1},padX:{min:0,max:.5},reserveLines:{min:1,max:8}},se=[{id:"inter",family:"Inter",label:"Inter"},{id:"manrope",family:"Manrope",label:"Manrope"},{id:"poppins",family:"Poppins",label:"Poppins"},{id:"fraunces",family:"Fraunces",label:"Fraunces"},{id:"space-grotesk",family:"Space Grotesk",label:"Space Grotesk"}],at=se.map(e=>e.id);[at[0],...at.slice(1)];const K=600;function Ge(e){return se.find(t=>t.id===e)??se[0]}const Wt=[{id:"standard",label:"Standard",blurb:"Headline on top, whole device below it, nothing cropped. The safe default.",character:"safe",bleedEdge:"none",shotLook:{deviceSize:"100",hOffset:"0",vOffset:"18",angle:"front",cameraPos:null,roll:"0"},caption:{sizePt:32,maxWidth:.86,reserveLines:2,align:"center",boxAlign:"center",padX:.07}},{id:"bleed",label:"Bleed",blurb:"Room for a longer headline, device running off the bottom edge. What the market looks like.",character:"conventional",bleedEdge:"bottom",shotLook:{deviceSize:"100",hOffset:"0",vOffset:"38",angle:"front",cameraPos:null,roll:"0"},caption:{sizePt:32,maxWidth:.86,reserveLines:4,align:"center",boxAlign:"center",padX:.07}},{id:"top-bleed",label:"Top bleed",blurb:"Device running off the TOP edge, headline underneath it. Inverts the usual reading order.",character:"expressive",bleedEdge:"top",shotLook:{deviceSize:"100",hOffset:"0",vOffset:"-38",angle:"front",cameraPos:null,roll:"0"},caption:{sizePt:32,maxWidth:.86,reserveLines:4,band:"bottom",align:"center",boxAlign:"center",padX:.07}},{id:"lean-right",label:"Lean right",blurb:"Device pushed off the RIGHT edge, headline in a column down the left. Reads as one continuous swipe.",character:"expressive",bleedEdge:"right",shotLook:{deviceSize:"100",hOffset:"46",vOffset:"18",angle:"front",cameraPos:null,roll:"0"},caption:{sizePt:32,maxWidth:.61,reserveLines:2,align:"left",boxAlign:"left",padX:.07}},{id:"lean-left",label:"Lean left",blurb:"Device pushed off the LEFT edge, headline in a column down the right. The mirror of Lean right.",character:"expressive",bleedEdge:"left",shotLook:{deviceSize:"100",hOffset:"-46",vOffset:"18",angle:"front",cameraPos:null,roll:"0"},caption:{sizePt:32,maxWidth:.61,reserveLines:2,align:"right",boxAlign:"right",padX:.07}},{id:"swipe",label:"Swipe",blurb:"A third of the device carried into the next panel, headline full width above it. Only honest applied to every frame.",character:"expressive",bleedEdge:"right",shotLook:{deviceSize:"100",hOffset:"78",vOffset:"18",angle:"front",cameraPos:null,roll:"0"},caption:{sizePt:32,maxWidth:.86,reserveLines:2,align:"center",boxAlign:"center",padX:.07}},{id:"corner-bleed",label:"Corner bleed",blurb:"Off the bottom AND the right at once, headline in a column down the left. The most opinionated panel here.",character:"expressive",bleedEdge:"bottom-right",shotLook:{deviceSize:"100",hOffset:"46",vOffset:"38",angle:"front",cameraPos:null,roll:"0"},caption:{sizePt:32,maxWidth:.61,reserveLines:4,align:"left",boxAlign:"left",padX:.07}}],$e=Wt,it=$e.map(e=>e.id);[it[0],...it.slice(1)];Array.from(new Set(Wt.flatMap(e=>Object.keys(e.caption))));const Ht=[{id:"noir",label:"Noir",blurb:"Near-black, high contrast, glossy silver device. The default premium look.",background:{gradientFrom:"#1C1C22",gradientTo:"#08080B",gradientDir:"vertical",shadow:!0,floorReflection:!1},shotLook:{material:"real",colorway:"silver",finish:"0",clearcoat:"1",reflections:!0,lighting:!0,angle:"front"},caption:{fontId:"inter",color:"FFFFFF"}},{id:"daylight",label:"Daylight",blurb:"Warm off-white, soft matte white device, dark text. Calm and editorial.",background:{gradientFrom:"#F4F1EA",gradientTo:"#DFD8CA",gradientDir:"vertical",shadow:!0,floorReflection:!1},shotLook:{material:"clay",clayTone:"white",finish:"0",clearcoat:"0",reflections:!1,lighting:!0,angle:"front"},caption:{fontId:"manrope",color:"1A1A1F"}},{id:"pop",label:"Pop",blurb:"Saturated indigo-to-violet, orange device. Loud, consumer, scroll-stopping.",background:{gradientFrom:"#5B6CF0",gradientTo:"#9B4DF0",gradientDir:"vertical",shadow:!0,floorReflection:!1},shotLook:{material:"real",colorway:"orange",finish:"0",clearcoat:"0.4",reflections:!0,lighting:!0,angle:"front"},caption:{fontId:"poppins",color:"FFFFFF"}},{id:"clay",label:"Clay",blurb:"Warm terracotta, matte charcoal device, tilted. Reads like a product photo.",background:{gradientFrom:"#E9BBAC",gradientTo:"#C88C7C",gradientDir:"vertical",shadow:!0,floorReflection:!1},shotLook:{material:"clay",clayTone:"charcoal",finish:"0",clearcoat:"0",reflections:!1,lighting:!0,angle:"left",roll:"-6"},caption:{fontId:"fraunces",color:"2A2320"}},{id:"studio",label:"Studio",blurb:"Mid slate with a floor reflection, blue device. Technical and precise.",background:{gradientFrom:"#5A6678",gradientTo:"#2B3340",gradientDir:"vertical",shadow:!0,floorReflection:!0},shotLook:{material:"real",colorway:"blue",finish:"0",clearcoat:"0",reflections:!0,lighting:!0,angle:"front"},caption:{fontId:"space-grotesk",color:"FFFFFF"}}],st=Ht.map(e=>e.id);[st[0],...st.slice(1)];const M={angle:"front",cameraPos:null,roll:"0",deviceSize:"100",hOffset:"0",vOffset:"18",material:"real",colorway:"blue",customColor:"32374A",finish:"0",clearcoat:"0",clayTone:"grey",clayCustom:"B0B0B0",flatScreen:!1,glare:!1,lighting:!0,reflections:!1},Te={angle:{valueKind:"angle",required:!0,defaultSource:"default-look",defaultValue:M.angle,persistence:"always"},cameraPos:{valueKind:"camera-position",required:!0,defaultSource:"default-look",defaultValue:M.cameraPos,persistence:"always"},roll:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:M.roll,persistence:"always"},deviceSize:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:M.deviceSize,persistence:"always"},hOffset:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:M.hOffset,persistence:"always"},vOffset:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:M.vOffset,persistence:"always"},material:{valueKind:"material",required:!0,defaultSource:"default-look",defaultValue:M.material,persistence:"always"},colorway:{valueKind:"colorway",required:!0,defaultSource:"default-look",defaultValue:M.colorway,persistence:"always"},customColor:{valueKind:"string",required:!0,defaultSource:"default-look",defaultValue:M.customColor,persistence:"always"},finish:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:M.finish,persistence:"always"},clearcoat:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:M.clearcoat,persistence:"always"},clayTone:{valueKind:"clay-tone",required:!0,defaultSource:"default-look",defaultValue:M.clayTone,persistence:"always"},clayCustom:{valueKind:"string",required:!0,defaultSource:"default-look",defaultValue:M.clayCustom,persistence:"always"},flatScreen:{valueKind:"boolean",required:!0,defaultSource:"default-look",defaultValue:M.flatScreen,persistence:"always"},clipToFrame:{valueKind:"boolean",required:!1,defaultSource:"explicit",defaultValue:!1,persistence:"omit-default"},deviceFrame:{valueKind:"boolean",required:!1,defaultSource:"explicit",defaultValue:!0,persistence:"omit-default"},screenCornerRadius:{valueKind:"numeric-string",required:!1,defaultSource:"explicit",defaultValue:"12",persistence:"omit-default"},glare:{valueKind:"boolean",required:!0,defaultSource:"default-look",defaultValue:M.glare,persistence:"always"},lighting:{valueKind:"boolean",required:!0,defaultSource:"default-look",defaultValue:M.lighting,persistence:"always"},reflections:{valueKind:"boolean",required:!0,defaultSource:"default-look",defaultValue:M.reflections,persistence:"always"}},Zn={roll:{min:-45,max:45},deviceSize:{min:25,max:240},hOffset:{min:-100,max:100},vOffset:{min:-200,max:200},finish:{min:0,max:1},clearcoat:{min:0,max:1},screenCornerRadius:{min:0,max:50}},Ut=.82;function Qn(e){return e/100*Ut}function eo(e){return Math.round(e/Ut*100)/100}const Y={x:.5,y:.06},Ve={fontId:"inter",sizePt:32,color:"FFFFFF",align:"center",anchor:Y,maxWidth:.86},lt=[{id:"r69",label:"6.9″ iPhone · 1320×2868",width:1320,height:2868},{id:"r65",label:"6.5″ iPhone · 1242×2688",width:1242,height:2688},{id:"r55",label:"5.5″ iPhone · 1242×2208",width:1242,height:2208},{id:"pixel69",label:"Pixel 10 Pro · 1320×2868",width:1320,height:2868},{id:"ipad13",label:"13″ iPad · 2064×2752",width:2064,height:2752},{id:"ipad129",label:"12.9″ iPad · 2048×2732",width:2048,height:2732}];function Z(e){return lt.find(t=>t.id===e)??lt[0]}const he=932,Me="iphone-17-pro",to="pixel-10-pro",qe=[{id:"iphone-6-9",label:"iPhone 17 Pro",panelPresetId:"r69",ascDeviceSet:"APP_IPHONE_67",modelId:Me,screenFamily:"iphone"},{id:"iphone-6-5",label:"iPhone 17",panelPresetId:"r65",ascDeviceSet:"APP_IPHONE_65",modelId:Me,screenFamily:"iphone"},{id:"pixel-10-pro",label:"Pixel 10 Pro",panelPresetId:"pixel69",ascDeviceSet:"ANDROID_PHONE",modelId:to,screenFamily:"android"},{id:"ipad-13",label:"iPad 13″",panelPresetId:"ipad13",ascDeviceSet:"APP_IPAD_PRO_129",modelId:"ipad-pro",screenFamily:"ipad",comingSoon:!0},{id:"ipad-12-9",label:"iPad 12.9″",panelPresetId:"ipad129",ascDeviceSet:"APP_IPAD_PRO_3GEN_129",modelId:"ipad-pro",screenFamily:"ipad",comingSoon:!0}];function no(e){return qe.find(t=>t.panelPresetId===e)?.modelId??Me}const Gt="iphone-6-9";function Xe(e){return qe.find(t=>t.id===e)}function oo(){return qe.filter(e=>!e.comingSoon)}function $t(e,t){if(Array.isArray(e)){const n=new Set,o=[];for(const r of e){const a=Xe(r);a&&!a.comingSoon&&!n.has(r)&&(n.add(r),o.push(r))}if(o.length>0)return o}if(t){const n=oo().find(o=>o.panelPresetId===t);if(n)return[n.id]}return[Gt]}function ro(e,t){return e.find(o=>Xe(o)?.panelPresetId===t)??e[0]}function ao(e){const t=e??{},n=Array.isArray(t.outputs)?t.outputs.filter(a=>typeof a=="string"):void 0,o=$t(n,typeof t.panelPresetId=="string"?t.panelPresetId:void 0),r=Z(typeof t.panelPresetId=="string"?t.panelPresetId:"").id;return{outputs:o,panelPresetId:r,activeDeviceId:ro(o,r)}}const Ke=Xe(Gt)?.screenFamily??"iphone";function Vt(e){const t={...e},n=t,o=Object.keys(Te);for(const r of o){const a=Te[r];a.persistence==="omit-default"&&(n[r]===void 0||n[r]===a.defaultValue)&&delete n[r]}return t}function io(e){if(!e||typeof e!="object"||Array.isArray(e)||!("phoneHeight"in e))return e;const{phoneHeight:t,...n}=e;if(n.deviceSize===void 0){const o=typeof t=="number"?t:Number.parseFloat(String(t??""));Number.isFinite(o)&&(n.deviceSize=String(eo(o)))}return n}function qt(e){return Vt({...M,...io(e)})}function Xt(e){return Vt(qt(e))}function F(e,t){const{min:n,max:o}=Zn[e],r=typeof t=="number"?t:Number.parseFloat(t??""),a=Number.isFinite(r)?r:Number.parseFloat(String(Te[e].defaultValue));return Math.max(n,Math.min(o,a))}const so=90,Kt=180,lo="#1b1b2e",co="#0a0a14";function uo(e){return e==="horizontal"?so:Kt}function fo(e){const t=(e%180+180)%180;return t>=45&&t<135?"horizontal":"vertical"}function Yt(e,t,n){return{stops:[{color:e,at:0},{color:t,at:1}],angle:uo(n)}}const Jt=e=>e*Math.PI/180;function ho(e){const t=Jt(e);return{dx:Math.sin(t),dy:-Math.cos(t)}}function po(e,t,n){const o=Jt(n);return Math.abs(e*Math.sin(o))+Math.abs(t*Math.cos(o))}function mo(e,t,n){const{dx:o,dy:r}=ho(n),a=po(e,t,n)/2,i=e/2,s=t/2;return{x0:i-a*o,y0:s-a*r,x1:i+a*o,y1:s+a*r}}function le(e){const t=e.stops[0],n=e.stops[e.stops.length-1];return{gradientFrom:t?.color??"#000000",gradientTo:n?.color??t?.color??"#000000",gradientDir:fo(e.angle)}}function pe(e,t){if(!Array.isArray(e)||e.length===0)return null;const n=[];for(const r of e){if(!r||typeof r!="object")return null;const a=r;if(typeof a.color!="string"||typeof a.at!="number"||!Number.isFinite(a.at))return null;n.push({color:a.color,at:Math.min(1,Math.max(0,a.at))})}const o=typeof t=="number"&&Number.isFinite(t)?go(t):Kt;return{stops:n,angle:o}}function ce(e){return pe(e.gradientStops,e.gradientAngle)??Yt(e.gradientFrom,e.gradientTo,e.gradientDir)}function go(e){return(e%360+360)%360}function yo(e){return pe(e.stops,e.angle)??Yt(e.from,e.to,e.dir)}function Zt(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,o]of Object.entries(e)){if(!o||typeof o!="object")continue;const r=o;if(r.kind==="solid"&&typeof r.color=="string")t[n]={kind:"solid",color:r.color};else if(r.kind==="gradient"&&typeof r.from=="string"&&typeof r.to=="string"&&(r.dir==="horizontal"||r.dir==="vertical")){const a=pe(r.stops,r.angle);t[n]=a?{kind:"gradient",stops:a.stops,angle:a.angle,from:r.from,to:r.to,dir:r.dir}:{kind:"gradient",from:r.from,to:r.to,dir:r.dir}}}return t}const ct=e=>Math.round(e*1e6)/1e6;function Q(e){return e.widthMode==="fill"?1-2*(e.padX??$.padX):e.maxWidth}function Qt(e){const t=Q(e);if(e.boxAlign===void 0&&e.bandCenter!==void 0)return e.bandCenter-t/2;const n=e.padX??$.padX;return e.boxAlign==="left"?n:e.boxAlign==="right"?1-n-t:$.bandCenter-t/2}function bo(e,t){return Math.abs(e-$.bandCenter)<1e-9?null:e<.5?{boxAlign:"left",padX:ct(e-t/2)}:{boxAlign:"right",padX:ct(1-e-t/2)}}function Ee(e,t){const n={...e,...t},o=t;return o.bandCenter!==void 0&&o.boxAlign===void 0&&delete n.boxAlign,o.boxAlign!==void 0&&o.bandCenter===void 0&&delete n.bandCenter,n}function D(e){return!e||e.x===Y.x&&e.y===Y.y}const vo=["sizePt","maxWidth","lineHeight","reserveLines"];function wo(e,t){return t?vo.filter(n=>e[n]!==t[n]):[]}function xo(e){const{text:t,anchor:n,...o}=e;return D(n)?{...o}:{...o,anchor:n}}const Io=.55,N="en-US";function So(e,t){return`${e}:${t}`}function Ao(e){const t=e.lastIndexOf(":");if(t<=0)return null;const n=Number(e.slice(t+1));return!Number.isSafeInteger(n)||n<0?null:{panelId:e.slice(0,t),index:n}}function en(e,t,n,o){if(!e||typeof e!="object"||Array.isArray(e))return{};const r={};for(const[a,i]of Object.entries(e)){if(a===n||!t.includes(a)||!Array.isArray(i))continue;const s=Array.from(new Set(i.filter(c=>typeof c=="string"))).filter(c=>{const l=Ao(c);return!!l&&!!o[n]?.[l.panelId]?.[l.index]&&!!o[a]?.[l.panelId]?.[l.index]});s.length>0&&(r[a]=s)}return r}function tn(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,o]of Object.entries(e))!o||typeof o!="object"||Array.isArray(o)||(t[n]=V(o));return t}function Po(e){if(!e||typeof e!="object")return;const t=e,n=typeof t.x=="number"?t.x:Y.x,o=typeof t.y=="number"?t.y:Y.y;return D({x:n,y:o})?void 0:{x:n,y:o}}function V(e){const t=e&&typeof e=="object"?e:{},n=Po(t.anchor),o={...Ve,...t};n?o.anchor=n:delete o.anchor,typeof o.reserveLines!="number"||!Number.isFinite(o.reserveLines)||o.reserveLines<ie.reserveLines.min?delete o.reserveLines:o.reserveLines=Math.floor(o.reserveLines),o.band!=="bottom"&&delete o.band;for(const r of["bandInset","lineHeight","bandCenter","padX"]){const{min:a,max:i}=ie[r],s=o[r];(typeof s!="number"||!Number.isFinite(s)||s<a||s>i)&&delete o[r]}return o.boxAlign!=="left"&&o.boxAlign!=="center"&&o.boxAlign!=="right"&&delete o.boxAlign,o.widthMode!=="fill"&&delete o.widthMode,Co(o),o}function Co(e){const t=e.bandCenter;if(t===void 0)return;const n=bo(t,e.maxWidth);if(e.boxAlign!==void 0||n===null){delete e.bandCenter;return}e.widthMode!=="fill"&&n.padX>=ie.padX.min&&n.padX<=ie.padX.max&&(e.boxAlign=n.boxAlign,e.padX=n.padX,delete e.bandCenter)}function ko(e){const t=e&&typeof e=="object"?e:{};return{...V(t),text:typeof t.text=="string"?t.text:""}}function Ye(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,o]of Object.entries(e))Array.isArray(o)?o.length>0&&(t[n]=o.map(V)):o&&typeof o=="object"&&(t[n]=[V(o)]);return t}function Oo(e,t){const n=[{...V(t),text:e.headline}];return typeof e.subtitle=="string"&&e.subtitle.trim()&&n.push({...V({...t,sizePt:t.sizePt*Io}),text:e.subtitle}),n}function me(e,t,n=N){if(!e||typeof e!="object"||Array.isArray(e))return{};const o=tn(t),r=l=>o[l]??Ve,a=l=>{if(!l||typeof l!="object"||Array.isArray(l))return{};const u={};for(const[f,d]of Object.entries(l))Array.isArray(d)?d.length>0&&(u[f]=d.map(ko)):d&&typeof d=="object"&&typeof d.headline=="string"&&(u[f]=Oo(d,r(f)));return u},i=Object.entries(e);if(i.some(([,l])=>!!l&&typeof l=="object"&&typeof l.headline=="string"))return{[n]:a(e)};const c={};for(const[l,u]of i)c[l]=a(u);return c}function ge(e,t,n=N){return e[t??n]??e[n]??{}}function nn(e,t=N){const n={},o=Object.keys(e),r=o.includes(t)?[t,...o.filter(a=>a!==t)]:o;for(const a of r){const i=e[a];if(i)for(const[s,c]of Object.entries(i))n[s]===void 0&&Array.isArray(c)&&c.length>0&&(n[s]=c.map(xo))}return n}function Le(e,t=N,n=Ke){const o={};return e.family!==void 0&&e.family!==n&&(o.family=e.family),e.locale!==void 0&&e.locale!==t&&(o.locale=e.locale),o}function dt(e){const t=[];return e.family!==void 0&&t.push(`family=${e.family}`),e.locale!==void 0&&t.push(`locale=${e.locale}`),t.join("&")}function Re(e){const t=[];return e.family!==void 0&&t.push("family"),e.locale!==void 0&&t.push("locale"),t}const To={order:["family","locale"],reach:"strict"},Mo={order:["locale","family"],reach:"lattice"};function Eo(e){const t=[];for(let n=0;n<1<<e.length;n++){const o=[];for(let r=0;r<e.length;r++)n&1<<r&&o.push(e[r]);t.push(o)}return t.sort((n,o)=>{if(n.length!==o.length)return o.length-n.length;for(let r=0;r<n.length;r++){const a=e.indexOf(n[r])-e.indexOf(o[r]);if(a!==0)return a}return 0})}function Lo(e,t){const n=Re(e),o=t.order.filter(a=>n.includes(a));return(t.reach==="strict"?Array.from({length:o.length+1},(a,i)=>o.slice(0,o.length-i)):Eo(o)).map(a=>{const i={};return a.includes("family")&&(i.family=e.family),a.includes("locale")&&(i.locale=e.locale),i})}function on(e,t,n,o,r=N){const a=Le(n,r);for(const i of Lo(a,o)){const s=e(t,i);if(s!==void 0){const c=Re(i);return{value:s,resolvedAt:i,inherited:Re(a).filter(l=>!c.includes(l))}}}return{value:void 0,resolvedAt:null,inherited:[]}}const rn=e=>{let t="";for(let n=0;n<e.length;n++)t+=e[n].toString(16).padStart(2,"0");return t};async function Ro(e){const t=globalThis.crypto?.subtle;return t?rn(new Uint8Array(await t.digest("SHA-256",e))):No(e)}const Fo=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),z=(e,t)=>e>>>t|e<<32-t;function No(e){const t=e.length,n=new Uint8Array(t+72>>6<<6);n.set(e),n[t]=128;const o=t*8,r=new DataView(n.buffer);r.setUint32(n.length-8,Math.floor(o/4294967296)),r.setUint32(n.length-4,o>>>0);const a=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),i=new Uint32Array(64);for(let s=0;s<n.length;s+=64){for(let m=0;m<16;m++)i[m]=r.getUint32(s+m*4);for(let m=16;m<64;m++){const y=i[m-15],b=i[m-2],v=z(y,7)^z(y,18)^y>>>3,w=z(b,17)^z(b,19)^b>>>10;i[m]=i[m-16]+v+i[m-7]+w>>>0}let[c,l,u,f,d,h,g,p]=[a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]];for(let m=0;m<64;m++){const y=z(d,6)^z(d,11)^z(d,25),b=d&h^~d&g,v=p+y+b+Fo[m]+i[m]>>>0,w=z(c,2)^z(c,13)^z(c,22),x=c&l^c&u^l&u,I=w+x>>>0;p=g,g=h,h=d,d=f+v>>>0,f=u,u=l,l=c,c=v+I>>>0}a[0]=a[0]+c>>>0,a[1]=a[1]+l>>>0,a[2]=a[2]+u>>>0,a[3]=a[3]+f>>>0,a[4]=a[4]+d>>>0,a[5]=a[5]+h>>>0,a[6]=a[6]+g>>>0,a[7]=a[7]+p>>>0}return rn(_o(a))}function _o(e){const t=new Uint8Array(e.length*4),n=new DataView(t.buffer);for(let o=0;o<e.length;o++)n.setUint32(o*4,e[o]);return t}function Fe(e,t,n=N){const o=r=>{const a=new Set,i=[];for(const s of r)typeof s=="string"&&s&&!a.has(s)&&(a.add(s),i.push(s));return i};if(Array.isArray(t)){const r=o(t);if(r.length>0)return r.includes(n)?r:[...r,n]}return o([n,...Object.keys(e)])}function Je(e,t=N){return typeof e=="string"&&e.length>0?e:t}const q={"it-IT":"it"};function ut(e,t){if(!(Object.keys(e).some(r=>r in q)||(t?.some(r=>r in q)??!1)))return{captionText:e,locales:t};const o={};for(const[r,a]of Object.entries(e))r in q||(o[r]=a);for(const[r,a]of Object.entries(e)){const i=q[r];i&&(o[i]={...a,...o[i]??{}})}return{captionText:o,locales:t?.map(r=>q[r]??r)}}function Bo(e){const t=e??{},n=Je(t.baseLocale),o=Array.isArray(t.locales)?t.locales.filter(s=>typeof s=="string"&&s.length>0):void 0,{captionText:r,locales:a}=ut(me(t.captionText,t.captionStyles,n),o),i=ut({[n]:{}},[n]).locales?.[0]??n;return{captionText:r,locales:Fe(r,a,i),baseLocale:i}}function zo(e,t,n,o,r){return(a,i)=>{const s=i.locale??r,c=i.family!==void 0?t?.[i.family]?.[s]?.[n]?.[o]:e[s]?.[n]?.[o]?.text;return typeof c=="string"&&c.length>0?c:void 0}}function jo(e,t,n,o,r=N){const a=ge(e,o,r);if(n===Ke||!t?.[n])return a;const i={family:n,locale:o},s={};for(const[c,l]of Object.entries(a))s[c]=l.map((u,f)=>{const d=zo(e,t,c,f,r),{value:h}=on(d,So(c,f),i,Mo,r);return h===void 0||h===u.text?u:{...u,text:h}});return s}function an(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,o]of Object.entries(e)){if(n===Ke||!o||typeof o!="object"||Array.isArray(o))continue;const r={};for(const[a,i]of Object.entries(o)){if(!i||typeof i!="object"||Array.isArray(i))continue;const s={};for(const[c,l]of Object.entries(i))Array.isArray(l)&&l.every(u=>typeof u=="string")&&(s[c]=l);Object.keys(s).length>0&&(r[a]=s)}Object.keys(r).length>0&&(t[n]=r)}return t}function Do(e,t,n){if(!t||!n)return e;let o=!1;const r=e.map((a,i)=>{const s=t[i];if(!s)return a;const c=wo(s,n[i]);if(c.length===0)return a;const l={...a},u=l;for(const f of c){const d=s[f];d===void 0?delete u[f]:u[f]=d}return o=!0,l});return o?r:e}function Wo(e,t,n,o){if(t.length===0)return e;const r={...e},a=e[n];let i=!1;for(const s of t)for(const c of Object.keys(r)){const l=o(r[c][s],s,c);l!==void 0&&(r[c]={...r[c],[s]:c===n?l:Do(l,e[c][s],a?.[s])},i=!0)}return i?r:e}function ee(e,t){return t.flatMap(n=>e.filter(o=>o.panelId===n.id))}let ft=0,ht=0;function Ho(e,t){const n=(o,r)=>o.reduce((a,i)=>{const s=i.startsWith(r)?Number.parseInt(i.slice(r.length),10):NaN;return Number.isFinite(s)&&s>a?s:a},0);ft=Math.max(ft,n(e,"shot-")),ht=Math.max(ht,n(t,"panel-"))}const Uo=.49;function Go(e,t,n){return e.map(o=>{const r=n*o.heightFrac,a=o.height>0?o.width*(r/o.height):r*Uo,s=o.panelIndex*t+t/2-a/2+o.hOffset*(t/2),l=(n-r)/2+o.vOffset*(n/2);return{shotId:o.shotId,bytes:o.bytes,x:Math.round(s),y:Math.round(l),width:Math.round(a),height:Math.round(r),panelIndex:o.panelIndex,...o.clipToFrame===!0?{clipToFrame:!0}:{},...o.layers?{layers:o.layers}:{}}})}function $o(e,t){const n=t.panelBackgrounds??{},o=ce(t),r=o.stops[0]?.color??t.gradientFrom;if(!e.some(c=>n[c.id]))return t.bgMode==="gradient"?{kind:"gradient",gradient:o}:{kind:"perPanel",colors:e.map(c=>t.panelColors[c.id]??r)};const i=c=>t.bgMode==="gradient"?{kind:"gradient",gradient:o}:{kind:"solid",color:t.panelColors[c]??r};return{kind:"perPanelFills",fills:e.map(c=>{const l=n[c.id];return l?l.kind==="solid"?{kind:"solid",color:l.color}:{kind:"gradient",gradient:yo(l)}:i(c.id)})}}const Vo=9/19.5;function qo(e){return e.deviceFrame!==!1}function Xo(e,t,n,o){const r=e>0&&t>0,a=r?t:Math.max(1,o),i=r?e:a*Vo,s=Math.min(1,Math.max(1,o)/a),c=Math.max(1,Math.round(i*s)),l=Math.max(1,Math.round(a*s)),u=Math.min(c*F("screenCornerRadius",n.screenCornerRadius)/100,Math.min(c,l)/2),f=F("roll",n.roll)*Math.PI/180,d=Math.abs(Math.cos(f)),h=Math.abs(Math.sin(f)),g=Math.max(1,Math.ceil(c*d+l*h-1e-6)),p=Math.max(1,Math.ceil(c*h+l*d-1e-6));return{width:g,height:p,cardWidth:c,cardHeight:l,radius:u,rotation:f}}function sn(e,t,n=N){const o=ce(e);return{panelPresetId:e.panelPresetId,bgMode:e.bgMode,gradientStops:o.stops,gradientAngle:o.angle,...le(o),panelColors:e.panelColors,shadow:e.shadow,floorReflection:e.floorReflection??!1,panelBackgrounds:e.panelBackgrounds??{},captionStyles:{...Ye(e.captionStyles),...nn(t,n)}}}function Ko(e){const t=Yo(e),n=t.lines===void 0?"":` Reserves ${t.lines} headline lines (~${t.characters} characters).`;return`${e.blurb}${n}${t.column?" Restyles the headline into a narrower column.":" Leaves the headline full-width and centred."} Character: [${e.character}]. Bleeds: [${e.bleedEdge}].`}function Yo(e){const t=e.caption.reserveLines,n=e.caption.maxWidth??.86,o=n<.86||(e.caption.align??"center")!=="center";return typeof t!="number"?{column:o}:{lines:t,characters:Math.round(t*18*n/.86),column:o}}function Jo(e){return $e.find(t=>t.id===e)}const Zo=e=>({...e,...e.anchor?{anchor:{...e.anchor}}:{}}),we=(e,t)=>JSON.stringify(e)===JSON.stringify(t),j=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function pt(e){if(!j(e))return null;const[t]=Ye({layer:[e]}).layer,{text:n,...o}=t;return Object.fromEntries(Object.entries(o).sort(([r],[a])=>r<a?-1:r>a?1:0))}function Qo(e,t){if(!j(e)||!j(e.frameTemplates))return null;const n=e.frameTemplates[t];if(!j(n)||typeof n.templateId!="string"||!Jo(n.templateId))return null;const o=n.templateId,r=Array.isArray(n.shots)?n.shots.filter(j):[],a=Array.isArray(e.shots)?e.shots.filter(u=>j(u)&&u.panelId===t):[];let i=a.length!==r.length||r.some((u,f)=>{const d=a[f];return d?.id!==u.id||!we(d?.look,u.look)});const s=j(e.captionSlotIds)?e.captionSlotIds:{},c=Array.isArray(s[t])?s[t]:[],l=Array.isArray(n.captionSlotIds)?n.captionSlotIds:[];if(!i&&!we(c,l)&&(i=!0),!i){const u=j(e.captionText)?e.captionText:{},f=j(n.captions)?n.captions:{},d=typeof n.baseLocale=="string"?n.baseLocale:"",h=new Set([...Object.keys(u),...Object.keys(f)]);for(const g of Array.from(h)){const p=j(u[g])?u[g]:{},m=Array.isArray(p[t])?p[t]:[],y=Array.isArray(f[g])?f[g]:Array.isArray(f[d])?f[d]:[];if(m.length!==l.length||y.length!==l.length){i=!0;break}if(y.some((b,v)=>!we(pt(m[v]),pt(b)))){i=!0;break}}}return{templateId:o,modified:i,resettable:!0}}function er(e,t){return Math.max(0,...Object.values(e).map(n=>n[t]?.length??0))}function ln(e,t,n){const o=e&&typeof e=="object"&&!Array.isArray(e)?e:{},r=new Set,a={};let i=1;const s=()=>{for(;r.has(`caption-${i}`);)i+=1;const c=`caption-${i}`;return r.add(c),i+=1,c};for(const c of n){const l=er(t,c);if(l===0)continue;const u=Array.isArray(o[c])?o[c]:[];a[c]=Array.from({length:l},(f,d)=>{const h=u[d];return typeof h=="string"&&h.length>0&&!r.has(h)?(r.add(h),h):s()})}return a}function tr(e,t,n){const o={};for(const[r,a]of Object.entries(e.captionText)){const i=a[t];i?.length&&(o[r]=i.map(Zo))}return{templateId:n,baseLocale:e.baseLocale,shots:e.shots.filter(r=>r.panelId===t).map(r=>({id:r.id,frameNodeId:r.frameNodeId,frameName:r.frameName,look:{...r.look},...r.inputAnchor?{inputAnchor:r.inputAnchor}:{},...r.outputAnchor?{outputAnchor:r.outputAnchor}:{}})),captionSlotIds:[...e.captionSlotIds[t]??[]],captions:o}}function nr(e,t){return Qo(e,t)}const cn=2;function or(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e;return t.schema===cn&&Array.isArray(t.shots)&&Array.isArray(t.panels)&&t.panels.length>0}function rr(e){let t;try{t=JSON.parse(e)}catch{return null}if(!or(t))return null;const n=t,o=new Set(n.panels.map(h=>h.id)),r=n.shots.filter(h=>o.has(h.panelId)).map(h=>({id:h.id,panelId:h.panelId,frameNodeId:h.frameNodeId,frameName:h.frameName,bytes:null,look:qt(h.look),thumb:null,thumbStale:!0,inputAnchor:h.inputAnchor,outputAnchor:h.outputAnchor})),a=n.panels.map(h=>({id:h.id}));Ho(r.map(h=>h.id),a.map(h=>h.id));const i=n.selectedShotId&&r.some(h=>h.id===n.selectedShotId)?n.selectedShotId:r[0]?.id??null,{captionText:s,locales:c,baseLocale:l}=Bo(n),u=ao(n),f=ln(n.captionSlotIds,s,a.map(h=>h.id)),d=pe(n.gradientStops,n.gradientAngle);return{shots:ee(r,a),panels:a,selectedShotId:i,panelPresetId:u.panelPresetId,bgMode:n.bgMode==="perPanel"?"perPanel":"gradient",...d?{gradientStops:d.stops,gradientAngle:d.angle,...le(d)}:{gradientFrom:n.gradientFrom??"5B6CF0",gradientTo:n.gradientTo??"9B4DF0",gradientDir:n.gradientDir==="vertical"?"vertical":"horizontal"},panelColors:n.panelColors??{},shadow:n.shadow!==!1,floorReflection:n.floorReflection===!0,panelBackgrounds:Zt(n.panelBackgrounds),captionText:s,locales:c,baseLocale:l,staleCaptionTranslations:en(n.staleCaptionTranslations,c,l,s),outputs:u.outputs,localeScreens:{},outputCaptions:an(n.outputCaptions),captionSlotIds:f,frameTemplates:n.frameTemplates&&typeof n.frameTemplates=="object"&&!Array.isArray(n.frameTemplates)?n.frameTemplates:{}}}function dn(e){const n=ee(e.shots,e.panels).map(a=>({id:a.id,panelId:a.panelId,frameNodeId:a.frameNodeId,frameName:a.frameName,look:Xt(a.look),inputAnchor:a.inputAnchor,outputAnchor:a.outputAnchor})),o=Je(e.baseLocale),r=me(e.captionText,e.captionStyles,o);return{schema:cn,shots:n,panels:e.panels,selectedShotId:e.selectedShotId,captionText:r,locales:Fe(r,e.locales,o),baseLocale:o,staleCaptionTranslations:en(e.staleCaptionTranslations,Fe(r,e.locales,o),o,r),outputs:$t(e.outputs,e.panelPresetId),outputCaptions:an(e.outputCaptions),...(()=>{const a=ln(e.captionSlotIds,r,e.panels.map(i=>i.id));return Object.keys(a).length>0?{captionSlotIds:a}:{}})(),...e.frameTemplates&&Object.keys(e.frameTemplates).length>0?{frameTemplates:e.frameTemplates}:{},...sn(e,r,o)}}const ar=1;function ir(e){const t=ee(e.shots,e.panels),n=me(e.captionText,e.captionStyles),o=Je(e.baseLocale);return{schema:ar,shots:t.map(r=>({panelId:r.panelId,look:Xt(r.look)})),...sn(e,n,o)}}Ht.map(e=>({id:e.id,label:e.label,description:e.blurb}));$e.map(e=>({id:e.id,label:e.label,description:Ko(e),character:e.character}));const sr=[{id:"frame.add",domain:"frame",status:"supported",summary:"Add a blank frame after an existing one.",studioCommands:["addPanel"],wire:"structuralOperations: frame.add",targets:["project"],requiredInputs:["afterFrameId (optional)","frameRef (optional, patch-local alias)"],limits:["Declare frameRef to address the new frame in later ordered operations of the same patch. Without frameRef, wait until the next cycle reports its id."],evaluationCases:["structure-add-closing-frame"]},{id:"frame.remove",domain:"frame",status:"supported",summary:"Remove a frame, with the devices and captions it holds.",studioCommands:["removePanel"],wire:"structuralOperations: frame.remove",targets:["frame"],requiredInputs:["frameId"],limits:["The last remaining frame cannot be removed."],evaluationCases:["structure-remove-empty-frame","structure-remove-populated-frame"]},{id:"frame.reorder",domain:"frame",status:"supported",summary:"Change the order frames tell the story in.",studioCommands:["movePanel","reorderPanels"],wire:"structuralOperations: frame.move, or the complete screenOrder permutation",targets:["project","frame"],requiredInputs:["frameId and its new position"],evaluationCases:["project-reorder-strongest"]},{id:"frame.split",domain:"frame",status:"supported",summary:"Split a multi-device frame by moving some of its devices into a new frame beside it.",studioCommands:[],wire:"structuralOperations: frame.split",targets:["frame","device"],requiredInputs:["frameId","a non-empty proper subset of its deviceIds"],evaluationCases:["structure-split-two-device-frame"]},{id:"frame.combine",domain:"frame",status:"supported",summary:"Merge one frame into another, keeping every device and caption, and drop the emptied frame.",studioCommands:[],wire:"structuralOperations: frame.combine",targets:["frame"],requiredInputs:["frameId (the survivor)","fromFrameId (the frame merged into it)"],evaluationCases:["structure-combine-last-two-frames"]},{id:"device.look",domain:"device",status:"supported",summary:"Restyle a device: camera angle, tilt, size, position, body colour, finish and lighting.",studioCommands:["patchShotLook"],wire:"patch.devices (by deviceId) or the complete patch.shots array",targets:["device"],requiredInputs:["deviceId","the look fields to change"],limits:["The raw camera 3-vector is not writable; the Agent moves the sanctioned orbit axis instead."],evaluationCases:["device-frame-two-clockwise","device-frame-one-gold","device-alternating-clay","device-frame-three-smaller-right","multi-device-spread-frame-two"]},{id:"device.move-to-frame",domain:"device",status:"supported",summary:"Move a device into an existing frame, at a chosen position among that frame’s devices.",studioCommands:["moveShotToFrame","moveShotToPanel","reorderShots"],wire:"structuralOperations: device.move",targets:["device","frame"],requiredInputs:["deviceId","toFrameId","toIndex (optional)"],evaluationCases:["structure-combine-last-two-frames"]},{id:"device.reorder",domain:"device",status:"supported",summary:"Reorder devices inside their own frame.",studioCommands:["moveShot"],wire:"structuralOperations: device.reorder",targets:["device"],requiredInputs:["deviceId","toIndex"],evaluationCases:["structure-reorder-devices-in-frame"]},{id:"device.remove",domain:"device",status:"supported",summary:"Remove one device while its frame stays.",studioCommands:["removeShot"],wire:"structuralOperations: device.remove",targets:["device"],requiredInputs:["deviceId"],limits:["The project’s last remaining device cannot be removed."],evaluationCases:["structure-remove-second-device"]},{id:"device.add",domain:"device",status:"supported",summary:"Add a device to a frame from a screenshot supplied with this instruction.",studioCommands:["addShot"],wire:"structuralOperations: device.add, naming an assetId from AVAILABLE SCREENSHOTS",targets:["frame"],requiredInputs:["toFrameId","assetId","toIndex (optional)"],withoutAssetReason:"Adding a device needs a screenshot sent with the instruction. This one carried none.",limits:["Only a screenshot listed in AVAILABLE SCREENSHOTS; the Agent never invents or generates pixels.","A device created this cycle can only be addressed in the next one, after Studio reports its id.","It lands on the default device look, exactly as dropping a screenshot into Studio does."],evaluationCases:["asset-add-supplied-screenshot"]},{id:"device.replace-pixels",domain:"asset",status:"supported",summary:"Replace the screenshot shown on an existing device, keeping the device untouched.",studioCommands:["reskinShots","ordinalReskin"],wire:"structuralOperations: device.replace, naming an assetId from AVAILABLE SCREENSHOTS",targets:["device"],requiredInputs:["deviceId","assetId"],withoutAssetReason:"Changing what a device shows needs the new screenshot sent with the instruction. This one carried none.",limits:["Only a screenshot listed in AVAILABLE SCREENSHOTS; the Agent never invents or generates pixels.","The device keeps its look, placement, captions, translated screens and Output membership — only the pixels change."],evaluationCases:["asset-replace-device-screenshot"]},{id:"caption.text",domain:"caption",status:"supported",summary:"Rewrite the headline words on frames.",studioCommands:["patchCaptionLayer"],wire:"the complete patch.captions array",targets:["project","frame","caption"],requiredInputs:["the complete caption list, one entry per frame"],limits:["Only each frame’s first caption layer, in the base language.","Hand-placed caption anchors and per-language fit overrides stay manual."],evaluationCases:["copy-all-six-words","copy-frame-two-exact","selection-caption-shorter"]},{id:"caption.style",domain:"caption",status:"supported",summary:"Restyle captions: font, size, colour, alignment, width and band placement.",studioCommands:["patchAllCaptionStyles"],wire:"patch.captionStyle (strip-wide) or patch.frames[i].captionStyle (one frame)",targets:["project","frame"],requiredInputs:["the style fields to change"],evaluationCases:["style-all-captions-smaller","style-selected-caption-white-left"]},{id:"caption.add",domain:"caption",status:"supported",summary:"Add a caption layer to a frame, with its words and styling.",studioCommands:["addCaptionLayer"],wire:"structuralOperations: caption.add",targets:["frame"],requiredInputs:["frameId","the caption text"],evaluationCases:["structure-subtitle-each-frame"]},{id:"caption.remove",domain:"caption",status:"supported",summary:"Remove one caption layer from a frame.",studioCommands:["removeCaptionLayer"],wire:"structuralOperations: caption.remove",targets:["caption"],requiredInputs:["frameId","the caption position"],evaluationCases:["structure-remove-subtitle"]},{id:"caption.reorder",domain:"caption",status:"supported",summary:"Reorder the caption layers stacked on one frame.",studioCommands:["reorderCaptionLayer"],wire:"structuralOperations: caption.move within one frame",targets:["caption"],requiredInputs:["frameId","the caption position","its new position"],evaluationCases:["structure-reorder-captions"]},{id:"caption.move-to-frame",domain:"caption",status:"supported",summary:"Move a caption layer to another frame.",studioCommands:["moveCaptionLayer","moveCaptionLayerToFrame"],wire:"structuralOperations: caption.move across frames",targets:["caption","frame"],requiredInputs:["frameId","the caption position","toFrameId"],evaluationCases:["structure-move-caption-to-frame"]},{id:"caption.translate",domain:"caption",status:"intentionally_excluded",summary:"Write caption words in a non-base language.",studioCommands:["applyCaptionTranslations","clearCaptionTranslation"],wire:null,targets:["project"],requiredInputs:[],reason:"Agent refinement cannot translate captions. Open Translate in Studio to create German or other language versions while retaining the base words.",evaluationCases:["unsupported-translate-captions"]},{id:"caption.output-override",domain:"caption",status:"intentionally_excluded",summary:"Give an output family its own caption wording.",studioCommands:["patchOutputCaption","clearOutputCaption"],wire:null,targets:["caption"],requiredInputs:[],reason:"Agent refinement edits shared captions. Studio has manual output-family caption wording; both iPhone sizes share one family and cannot have separate words.",evaluationCases:["unsupported-per-output-caption"]},{id:"strip.background",domain:"look",status:"supported",summary:"Change the strip backdrop: gradient stops, angle, shadow and floor reflection.",studioCommands:["patchConfig"],wire:"patch.background",targets:["project"],requiredInputs:["the backdrop fields to change"],limits:["The canvas size a Look is authored against stays a Studio control.","Per-frame solid colours are set through the frame backdrop, not the strip config."],evaluationCases:["background-strip-navy-gradient"]},{id:"frame.background",domain:"look",status:"supported",summary:"Give one frame its own backdrop.",studioCommands:["setPanelBackground"],wire:"patch.frames[i].background",targets:["frame"],requiredInputs:["the frame","the backdrop fields"],evaluationCases:["background-frame-one-amber","background-frame-three-flat-teal","inspection-correct-frame-two-background"]},{id:"frame.background-reset",domain:"look",status:"intentionally_excluded",summary:"Drop one or all frame backdrops so they inherit the strip again.",studioCommands:["clearPanelBackground","clearAllPanelBackgrounds"],wire:null,targets:["frame"],requiredInputs:[],reason:"Agent refinement cannot reset backdrop inheritance. Use the frame background reset control in Studio to return it to the strip default.",evaluationCases:["unsupported-frame-background-reset"]},{id:"strip.background-broadcast",domain:"look",status:"intentionally_excluded",summary:"Copy one frame’s backdrop onto every frame, or promote it to the strip default.",studioCommands:["applyBackgroundToAllPanels","setStripDefaultBackground"],wire:null,targets:["project"],requiredInputs:[],reason:"No Studio surface offers these transfers today; the Agent writes the strip backdrop directly.",evaluationCases:["unsupported-background-broadcast"]},{id:"frame.color",domain:"look",status:"intentionally_excluded",summary:"Set the legacy per-panel colour that sits under a frame’s backdrop.",studioCommands:["setPanelColor"],wire:null,targets:["frame"],requiredInputs:[],reason:"No Studio surface dispatches it. A flat colour is a one-stop frame backdrop (`frame.background`), so a request for one is carried out there, never refused.",evaluationCases:["background-frame-three-flat-teal"]},{id:"look.design-preset",domain:"look",status:"supported",summary:"Apply a named design preset to the whole strip.",studioCommands:[],wire:"patch.designPreset",targets:["project"],requiredInputs:["a catalog preset id"],evaluationCases:["styling-apply-design-preset"]},{id:"look.layout-template",domain:"look",status:"supported",summary:"Apply a layout template, or explicitly reset one frame to its saved template baseline.",studioCommands:["applyLayoutTemplate","resetFrameTemplate"],wire:"patch.layout, or structuralOperations: frame.template-reset",targets:["project","frame"],requiredInputs:["a catalog layout id, or the frameId named in an explicit reset/revert request"],limits:["Never reset implicitly while handling a general styling request; reset may remove added screens or captions."],evaluationCases:["layout-use-bleed"]},{id:"look.apply-saved",domain:"look",status:"intentionally_excluded",summary:"Restore the project’s saved Look, or one of its earlier versions.",studioCommands:["applyLook"],wire:null,targets:["project"],requiredInputs:[],reason:"Agent refinement cannot restore a saved Look. Restore the saved version through Look version history in Studio.",evaluationCases:["unsupported-restore-saved-look"]},{id:"output.membership",domain:"output",status:"supported",summary:"Add or remove the store output sizes this project renders for.",studioCommands:["addOutput","removeOutput","setActiveOutput"],wire:"patch.outputs",targets:["project"],requiredInputs:["the complete output list"],limits:["Which output is previewed on screen stays a Studio cursor."],evaluationCases:["project-add-android-output"]},{id:"locale.membership",domain:"locale",status:"supported",summary:"Add or remove the languages this project is captioned in.",studioCommands:["addLocale","removeLocale"],wire:"patch.locales",targets:["project"],requiredInputs:["the complete language list"],limits:["The base language cannot be removed, and which language is being authored stays a Studio cursor."],evaluationCases:["project-add-german-locale","geometry-clear-while-adding-a-language"]},{id:"strip.add-screens",domain:"asset",status:"supported",summary:"Add new screenshots to the project, each in its own frame.",studioCommands:["addShots"],wire:"structuralOperations: frame.add with a frameRef, then device.add into it, once per screenshot from AVAILABLE SCREENSHOTS",targets:["project"],requiredInputs:["one or more authorized screenshot references"],withoutAssetReason:"New frames need new pixels. Send the screenshots with the instruction and the Agent will place them.",limits:["Only screenshots listed in AVAILABLE SCREENSHOTS; the Agent never invents or generates pixels.","Each new frame starts without a caption and its device on the default look, exactly as adding screenshots in Studio does."],evaluationCases:["asset-add-screens-supplied","asset-add-screens-needs-pixels"]},{id:"strip.replace-screens",domain:"asset",status:"supported",summary:"Replace every screenshot in the project, keeping the styling.",studioCommands:["loadScreens"],wire:"structuralOperations: device.replace on every device in strip order, each naming its own assetId from AVAILABLE SCREENSHOTS",targets:["project"],requiredInputs:["a complete authorized screenshot set"],withoutAssetReason:"Replacing the whole strip needs the whole new set of pixels. This instruction carried none.",limits:["Only screenshots listed in AVAILABLE SCREENSHOTS; the Agent never invents or generates pixels.","Every device keeps its look, placement, captions, translated screens and Output membership — only the pixels change.","When the supplied screenshots do not match the devices one to one, the Agent asks which goes where instead of swapping some of them."],evaluationCases:["asset-replace-all-screens-supplied","asset-replace-all-screens-needs-pixels","asset-replace-all-screens-count-mismatch"]},{id:"locale.load-screens",domain:"asset",status:"requires_asset",summary:"Supply localized screenshots for one language.",studioCommands:["loadLocaleScreens"],wire:null,targets:["project"],requiredInputs:["the language","authorized screenshots named for the frames they belong to"],reason:"A localized screen is different pixels, not a different caption.",evaluationCases:["asset-locale-screens-needs-pixels"]},{id:"output.load-screens",domain:"asset",status:"requires_asset",summary:"Supply screenshots captured at another output size.",studioCommands:["loadOutputScreens"],wire:null,targets:["project"],requiredInputs:["the output family","authorized screenshots named for the frames they belong to"],reason:"A second output size needs its own captures; the Agent cannot resample one from another.",evaluationCases:["asset-output-screens-needs-pixels"]}],lr="unknown",cr=[{id:"image.generate",summary:"Generate or paint new imagery rather than arranging supplied screenshots."},{id:"animation.create",summary:"Animate a screen, produce a video, or export motion instead of stills."},{id:"device.unsupported-model",summary:"Use a device model ShotOps does not offer."}],dr=sr.map(e=>e.id);[...dr,...cr.map(e=>e.id)];const ur=7,mt={front:{x:0,y:0,z:-1},left:{x:-2.6,y:.6,z:-5.2},right:{x:2.6,y:.6,z:-5.2}};function un(e){const t=mt[e]??mt.front,n=Math.hypot(t.x,t.y,t.z),o=ur/n;return{x:t.x*o,y:t.y*o,z:t.z*o}}function fr(e){return Math.atan2(e.x,-e.z)*180/Math.PI}const fn=[{code:"ar-SA",name:"Arabic",script:"rtl",dir:"rtl"},{code:"bn-BD",name:"Bengali",script:"indic",dir:"ltr"},{code:"ca",name:"Catalan",script:"latin",dir:"ltr"},{code:"cs",name:"Czech",script:"latin",dir:"ltr"},{code:"da",name:"Danish",script:"latin",dir:"ltr"},{code:"de-DE",name:"German",script:"latin",dir:"ltr"},{code:"el",name:"Greek",script:"greek",dir:"ltr"},{code:"en-AU",name:"English (Australia)",script:"latin",dir:"ltr"},{code:"en-CA",name:"English (Canada)",script:"latin",dir:"ltr"},{code:"en-GB",name:"English (U.K.)",script:"latin",dir:"ltr"},{code:"en-US",name:"English (U.S.)",script:"latin",dir:"ltr"},{code:"es-ES",name:"Spanish (Spain)",script:"latin",dir:"ltr"},{code:"es-MX",name:"Spanish (Mexico)",script:"latin",dir:"ltr"},{code:"fi",name:"Finnish",script:"latin",dir:"ltr"},{code:"fr-CA",name:"French (Canada)",script:"latin",dir:"ltr"},{code:"fr-FR",name:"French",script:"latin",dir:"ltr"},{code:"gu-IN",name:"Gujarati",script:"indic",dir:"ltr"},{code:"he",name:"Hebrew",script:"rtl",dir:"rtl"},{code:"hi",name:"Hindi",script:"indic",dir:"ltr"},{code:"hr",name:"Croatian",script:"latin",dir:"ltr"},{code:"hu",name:"Hungarian",script:"latin",dir:"ltr"},{code:"id",name:"Indonesian",script:"latin",dir:"ltr"},{code:"it",name:"Italian",script:"latin",dir:"ltr"},{code:"ja",name:"Japanese",script:"cjk",dir:"ltr"},{code:"kn-IN",name:"Kannada",script:"indic",dir:"ltr"},{code:"ko",name:"Korean",script:"cjk",dir:"ltr"},{code:"ml-IN",name:"Malayalam",script:"indic",dir:"ltr"},{code:"mr-IN",name:"Marathi",script:"indic",dir:"ltr"},{code:"ms",name:"Malay",script:"latin",dir:"ltr"},{code:"nl-NL",name:"Dutch",script:"latin",dir:"ltr"},{code:"no",name:"Norwegian",script:"latin",dir:"ltr"},{code:"or-IN",name:"Odia",script:"indic",dir:"ltr"},{code:"pa-IN",name:"Punjabi",script:"indic",dir:"ltr"},{code:"pl",name:"Polish",script:"latin",dir:"ltr"},{code:"pt-BR",name:"Portuguese (Brazil)",script:"latin",dir:"ltr"},{code:"pt-PT",name:"Portuguese (Portugal)",script:"latin",dir:"ltr"},{code:"ro",name:"Romanian",script:"latin",dir:"ltr"},{code:"ru",name:"Russian",script:"cyrillic",dir:"ltr"},{code:"sk",name:"Slovak",script:"latin",dir:"ltr"},{code:"sl-SI",name:"Slovenian",script:"latin",dir:"ltr"},{code:"sv",name:"Swedish",script:"latin",dir:"ltr"},{code:"ta-IN",name:"Tamil",script:"indic",dir:"ltr"},{code:"te-IN",name:"Telugu",script:"indic",dir:"ltr"},{code:"th",name:"Thai",script:"thai",dir:"ltr"},{code:"tr",name:"Turkish",script:"latin",dir:"ltr"},{code:"uk",name:"Ukrainian",script:"cyrillic",dir:"ltr"},{code:"ur-PK",name:"Urdu",script:"rtl",dir:"rtl"},{code:"vi",name:"Vietnamese",script:"latin",dir:"ltr"},{code:"zh-Hans",name:"Chinese (Simplified)",script:"cjk",dir:"ltr"},{code:"zh-Hant",name:"Chinese (Traditional)",script:"cjk",dir:"ltr"}];fn.map(e=>e.code);Object.fromEntries(fn.map(e=>[e.code,e]));({...Ve});function hr(e,t){t.material==="clay"?(e.setClay(t.clayTone==="custom"?`#${t.clayCustom}`:t.clayTone),e.setClearcoat(0)):(e.clayOff(),t.colorway==="custom"?e.setCustomColor(`#${t.customColor}`):e.setColorway(t.colorway),e.setFinish(F("finish",t.finish)),e.setClearcoat(F("clearcoat",t.clearcoat)))}function pr(e,t,n){e.screen.setGlare(!n&&t?e.device.environmentMap():null)}async function mr(e,t,n,o){const{stage:r,device:a,screen:i}=e,s=t.material==="clay";if(t.cameraPos?r.setCameraPosition(t.cameraPos):r.setAngle(t.angle),a.setRoll(F("roll",t.roll)),hr(a,t),i.restoreScreen(),r.setStudioLighting(t.lighting),a.setReflections(t.reflections),i.setFlatScreen(t.flatScreen),n){try{await i.applyWallpaper(n)}catch{}if(!o())return}pr(e,t.glare,s)}const gr=""+new URL("iphone-optimized-BdcJzlHi.glb",import.meta.url).href,yr="data:model/gltf-binary;base64,Z2xURgIAAADUAAAAwAAAAEpTT057ImFzc2V0Ijp7InZlcnNpb24iOiIyLjAiLCJnZW5lcmF0b3IiOiJTaG90T3BzIHBsYWNlaG9sZGVyIOKAlCB0aGUgUGl4ZWwgbW9kZWwgaXMgZGVsaWJlcmF0ZWx5IG5vdCBidW5kbGVkIGluIHRoZSBucG0gcGFja2FnZSJ9LCJzY2VuZXMiOlt7Im5hbWUiOiJwaXhlbC1ub3QtYnVuZGxlZCIsIm5vZGVzIjpbXX1dLCJzY2VuZSI6MH0gICA=",br=[{id:"grey",label:"Grey",color:11579568},{id:"white",label:"White",color:15263458},{id:"charcoal",label:"Charcoal",color:3815996}],vr=[{id:"blue",label:"Deep Blue",frame:3290954,back:4409953,accent:2172211},{id:"silver",label:"Silver",frame:16119285,back:16514043,accent:13816532},{id:"orange",label:"Cosmic Orange",frame:16219693,back:16487504,accent:12738072},{id:"ice",label:"Glacier",frame:15266559,back:15463679,accent:11450047},{id:"red",label:"Burgundy",frame:5052449,back:6435900,accent:3805721},{id:"black",label:"Black",frame:3947580,back:5460819,accent:2960685}],wr=[{id:"silver",label:"Moonstone",frame:9345186,back:8621205,accent:7041658},{id:"black",label:"Obsidian",frame:2763308,back:2565928,accent:2105377},{id:"orange",label:"Porcelain",frame:15920872,back:14670805,accent:11973550},{id:"green",label:"Jade",frame:9412240,back:8688005,accent:7042924}],de={id:"iphone-17-pro",glb:gr,fitSize:3.6,baseEuler:{x:0,y:0,z:0},pruneNamePrefixes:[],screen:{material:"OLED",repeat:{x:-1,y:1},coverFill:1.001,coverCornerRatio:.18,coverRepeat:{x:-1,y:-1}},body:{frame:["Anodized aluminum"],back:["Frosted glass"],accent:["Plastic antena","PaletteMaterial001"]},colorways:vr},gt={id:"pixel-10-pro",glb:yr,fitSize:3.6,baseEuler:{x:0,y:Math.PI,z:0},pruneNamePrefixes:["Google Pixel 10 Pro Moonstone.1"],screen:{material:"GP10p_display",repeat:{x:1,y:1},coverFill:1.001,coverCornerRatio:.14,coverRepeat:{x:1,y:-1}},body:{frame:["GP10p_mid","GP10p_camera"],back:["GP10p_back","GP10p_plastic"],accent:["GP10p_logo"]},colorways:wr},xr={[de.id]:de,[gt.id]:gt};function Ze(e){return e&&xr[e]||de}function Ne(e){const t=un(e);return new G(t.x,t.y,t.z)}const Ir=1.4;function Sr(e,t){return(t?new G(t.x,t.y,t.z):Ne(e)).multiplyScalar(Ir)}const Qe=35;function Ar(e){e.traverse(t=>{const n=t;n.geometry?.dispose();const o=n.material;Array.isArray(o)?o.forEach(yt):o&&yt(o)}),e.clear()}function yt(e){for(const t of Object.values(e))t&&typeof t=="object"&&t.isTexture&&t.dispose();e.dispose()}function hn(e,t){const n=document.createElement("canvas"),o=new Wn({canvas:n,antialias:!0,preserveDrawingBuffer:!0,alpha:!0});o.setSize(e,t,!1),o.shadowMap.enabled=!0;const r=new Ln;r.background=null;const{ambient:a,directionals:i}=Pr(r),s=new Ue(Qe,e/t,.01,100);s.position.copy(Ne("front")),s.lookAt(0,0,0);function c(h){s.position.copy(Ne(h)),s.lookAt(0,0,0)}function l(h){s.position.set(h.x,h.y,h.z),s.lookAt(0,0,0)}function u(h){i.forEach(g=>g.visible=h),a.intensity=h?.75:1.6}let f=!1;function d(){f||(f=!0,r.environment?.dispose(),r.environment=null,Ar(r),o.dispose(),o.forceContextLoss())}return{scene:r,camera:s,renderer:o,dispose:d,setAngle:c,setCameraPosition:l,getCameraPosition:()=>({x:s.position.x,y:s.position.y,z:s.position.z}),onUserPose:()=>{},previewOrbit:()=>{},commitOrbit:()=>{},setOrbitEnabled:()=>{},setBackground:()=>{},setStudioLighting:u,resize:()=>{},invalidate:()=>{}}}function Pr(e){const t=new Fn(16777215,.75);e.add(t);const n=new ve(16777215,2.2);n.position.set(3,5,5);const o=new ve(12571903,.7);o.position.set(-4,1,2);const r=new ve(16777215,1);r.position.set(0,3,-5);const a=[n,o,r];return a.forEach(i=>e.add(i)),{ambient:t,directionals:a}}function pn(e,t){const n=Ze(t);return new Promise((o,r)=>{new Rn().load(n.glb,a=>{const i=a.scene;if(n.pruneNamePrefixes.length){const d=[];i.traverse(h=>{n.pruneNamePrefixes.some(g=>h.name.startsWith(g))&&d.push(h)}),d.forEach(h=>h.removeFromParent())}i.rotation.set(n.baseEuler.x,n.baseEuler.y,n.baseEuler.z),i.updateMatrixWorld(!0);const s=new Hn().setFromObject(i),c=s.getSize(new G),l=s.getCenter(new G),u=n.fitSize/Math.max(c.x,c.y,c.z);i.scale.multiplyScalar(u),i.position.copy(l.multiplyScalar(-u));const f=new Un;f.add(i),e.scene.add(f),e.setAngle("front"),o(f)},void 0,r)})}function Cr(e){return pn(e)}const bt=1900,vt=2800,kr=8192,Or=2;async function Tr(e,t,n,o={}){const r=e.renderer,a=r.getPixelRatio(),i=r.getSize(new Dt);r.setDrawingBufferSize(t,n,1);let s;o.cameraPosition?(s=new Ue(Qe,t/n,.01,100),s.position.copy(o.cameraPosition),s.lookAt(0,0,0)):(s=e.camera.clone(),s.aspect=t/n,s.updateProjectionMatrix());try{const c=e.scene.background;e.scene.background=null;try{r.render(e.scene,s)}finally{e.scene.background=c}const l=document.createElement("canvas");let u=null;try{l.width=t,l.height=n,l.getContext("2d")?.drawImage(r.domElement,0,0);const f=mn(l),d=f.canvas;u=d;const h=d.width,g=d.height;return{bytes:await new Promise((m,y)=>{d.toBlob(b=>{if(!b){y(new Error("toBlob returned null"));return}b.arrayBuffer().then(v=>m(new Uint8Array(v)),y)},"image/png")}),width:h,height:g,frame:{width:t,height:n,cropX:f.x,cropY:f.y}}}finally{u&&u!==l&&(u.width=0,u.height=0),l.width=0,l.height=0}}finally{r.setDrawingBufferSize(i.x,i.y,a),e.invalidate()}}function mn(e,t=Or){const n=e.getContext("2d",{willReadFrequently:!0});if(!n)return{canvas:e,x:0,y:0};const{width:o,height:r}=e,a=n.getImageData(0,0,o,r).data;let i=o,s=r,c=-1,l=-1;for(let h=0;h<r;h++)for(let g=0;g<o;g++)a[(h*o+g)*4+3]!==0&&(g<i&&(i=g),g>c&&(c=g),h<s&&(s=h),h>l&&(l=h));if(c<i||l<s)return{canvas:e,x:0,y:0};i=Math.max(0,i-t),s=Math.max(0,s-t),c=Math.min(o-1,c+t),l=Math.min(r-1,l+t);const u=c-i+1,f=l-s+1,d=document.createElement("canvas");return d.width=u,d.height=f,d.getContext("2d")?.drawImage(e,i,s,u,f,0,0,u,f),{canvas:d,x:i,y:s}}function Mr(e){const t=URL.createObjectURL(new Blob([e],{type:"image/png"}));return new Promise((n,o)=>{const r=new Image;r.onload=()=>{URL.revokeObjectURL(t),n(r)},r.onerror=()=>{URL.revokeObjectURL(t),o(new Error("Screenshot could not be decoded for the flat card"))},r.src=t})}function Er(e,t,n,o){if(e.beginPath(),o<=0){e.rect(0,0,t,n);return}e.moveTo(o,0),e.arcTo(t,0,t,n,o),e.arcTo(t,n,0,n,o),e.arcTo(0,n,0,0,o),e.arcTo(0,0,t,0,o),e.closePath()}function Lr(e,t,n,o){const r=t?"naturalWidth"in t?t.naturalWidth:t.width:0,a=t?"naturalHeight"in t?t.naturalHeight:t.height:0,i=Xo(r,a,n,o),{width:s,height:c,cardWidth:l,cardHeight:u,radius:f,rotation:d}=i;e.width=s,e.height=c;const h=e.getContext("2d");if(!h)throw new Error("2D context unavailable for the flat card");return h.translate(s/2,c/2),h.rotate(d),h.translate(-l/2,-u/2),Er(h,l,u,f),h.clip(),t?(h.imageSmoothingQuality="high",h.drawImage(t,0,0,l,u)):(h.fillStyle="#000",h.fillRect(0,0,l,u)),i}async function Rr(e,t,n){return(await gn(e,t,n)).out}async function gn(e,t,n){const o=e?await Mr(e):null,r=document.createElement("canvas");try{const a=Lr(r,o,t,n),{width:i,height:s}=a;return{out:{bytes:await new Promise((l,u)=>{r.toBlob(f=>{if(!f){u(new Error("toBlob returned null"));return}f.arrayBuffer().then(d=>l(new Uint8Array(d)),u)},"image/png")}),width:i,height:s,frame:{width:i,height:s,cropX:0,cropY:0}},geometry:a}}finally{r.width=0,r.height=0}}const wt=24*1024*1024,_e=new WeakMap;async function Fr(e){const t=await Ro(e.bytes);return Be({look:e.look,screenshot:t,width:e.width,height:e.height,physicalBody:e.physicalBody,screenLayers:e.screenLayers})}function Nr(e,t){const n=_e.get(e);if(!n)return;const o=n.entries.get(t);if(o)return n.entries.delete(t),n.entries.set(t,o),o}function _r(e,t,n){const o=n.bytes.byteLength;if(o>wt)return;let r=_e.get(e);r||(r={entries:new Map,bytes:0},_e.set(e,r));const a=r.entries.get(t);a&&(r.bytes-=a.bytes.byteLength),r.entries.delete(t),r.entries.set(t,n),r.bytes+=o;const i=Array.from(r.entries.keys());for(let s=0;s<i.length&&r.bytes>wt;s++){const c=r.entries.get(i[s]);c&&(r.bytes-=c.bytes.byteLength,r.entries.delete(i[s]))}}function Be(e){if(e===null||typeof e!="object")return JSON.stringify(e)??"null";if(Array.isArray(e))return`[${e.map(Be).join(",")}]`;const t=e;return`{${Object.keys(t).filter(o=>t[o]!==void 0).sort().map(o=>`${JSON.stringify(o)}:${Be(t[o])}`).join(",")}}`}function Br(e,t,n,o,r){return{x:(e.x+1)/2*t-o,y:(1-e.y)/2*n-r}}function zr(e){const{width:t,height:n,cardWidth:o,cardHeight:r,rotation:a}=e,i=Math.cos(a),s=Math.sin(a),c=(f,d)=>({x:t/2+f*i-d*s,y:n/2+f*s+d*i}),l=o/2,u=r/2;return{tl:c(-l,-u),tr:c(l,-u),br:c(l,u),bl:c(-l,u)}}function xe(e){return new Promise((t,n)=>{e.toBlob(o=>{if(!o){n(new Error("toBlob returned null"));return}o.arrayBuffer().then(r=>t(new Uint8Array(r)),n)},"image/png")})}function xt(e,t,n,o,r){const a=document.createElement("canvas");return a.width=o,a.height=r,a.getContext("2d")?.drawImage(e,t,n,o,r,0,0,o,r),a}function jr(e,t){const n=Math.hypot(e.tr.x-e.tl.x,e.tr.y-e.tl.y),o=Math.hypot(e.bl.x-e.tl.x,e.bl.y-e.tl.y);return n>0?Math.min(n,o)*t/n:0}async function Dr(e,t,n,o,r,a={}){const i=e.renderer,s=i.getPixelRatio(),c=i.getSize(new Dt);i.setDrawingBufferSize(n,o,1);let l;a.cameraPosition?(l=new Ue(Qe,n/o,.01,100),l.position.copy(a.cameraPosition),l.lookAt(0,0,0)):(l=e.camera.clone(),l.aspect=n/o,l.updateProjectionMatrix()),l.updateMatrixWorld();const u=[],f=()=>{const d=document.createElement("canvas");return d.width=n,d.height=o,u.push(d),d};try{const d=f(),h=f(),g=f(),p=e.scene.background;e.scene.background=null;try{i.render(e.scene,l),d.getContext("2d")?.drawImage(i.domElement,0,0);try{t.setLayerPass("device"),i.render(e.scene,l),h.getContext("2d")?.drawImage(i.domElement,0,0),t.setLayerPass("screen"),i.render(e.scene,l),g.getContext("2d")?.drawImage(i.domElement,0,0)}finally{t.restoreLayerPass()}}finally{e.scene.background=p}const m=mn(d);m.canvas!==d&&u.push(m.canvas);const y=m.canvas.width,b=m.canvas.height,v=xt(h,m.x,m.y,y,b),w=xt(g,m.x,m.y,y,b);u.push(v,w),e.scene.updateMatrixWorld();const x=t.screenCornersWorld(),I=T=>{const O=T.clone().project(l);return Br(O,n,o,m.x,m.y)},P={x:0,y:0},S=x?{tl:I(x.tl),tr:I(x.tr),br:I(x.br),bl:I(x.bl)}:{tl:P,tr:P,br:P,bl:P},[k,A,C]=[await xe(m.canvas),await xe(v),await xe(w)];return{bytes:k,width:y,height:b,frame:{width:n,height:o,cropX:m.x,cropY:m.y},layers:{width:y,height:b,device:A,screen:{bytes:C,quad:S,cornerRadiusFrac:jr(S,t.cornerRatio),sourceNodeId:r}}}}finally{u.forEach(d=>{d.width=0,d.height=0}),i.setDrawingBufferSize(c.x,c.y,s),e.invalidate()}}async function Wr(e,t,n,o){const{out:r,geometry:a}=await gn(e,t,n);return Hr(r,a,o)}function Hr(e,t,n){const o=zr(t);return{...e,layers:{width:e.width,height:e.height,device:null,screen:{bytes:e.bytes,quad:o,cornerRadiusFrac:t.cardWidth>0?t.radius/t.cardWidth:0,sourceNodeId:n}}}}function Ur(e,t,n){return{shots:e,panels:t,selectedShotId:n.selectedShotId,panelPresetId:n.panelPresetId,bgMode:n.bgMode,gradientStops:n.gradientStops,gradientAngle:n.gradientAngle,gradientFrom:n.gradientFrom,gradientTo:n.gradientTo,gradientDir:n.gradientDir,panelColors:n.panelColors,shadow:n.shadow,floorReflection:n.floorReflection,panelBackgrounds:n.panelBackgrounds,captionStyles:n.captionStyles,captionText:n.captionText,locales:n.locales,baseLocale:n.baseLocale,outputs:n.outputs}}function Gr(e,t){return e.usesPhysicalFinish()?!0:t.material!=="clay"&&F("clearcoat",t.clearcoat)>0}async function $r(e,t,n,o,r,a){const i=ee(n,o),s=i.filter(g=>g.bytes);if(s.length===0)return null;const c=Z(r.panelPresetId),l=new Map(o.map((g,p)=>[g.id,p])),u=r.renderScale!=null&&Number.isFinite(r.renderScale)&&r.renderScale>0?r.renderScale:1,f=Math.min(u,kr/Math.max(bt,vt)),d=Math.max(1,Math.round(bt*f)),h=Math.max(1,Math.round(vt*f));{const g=[];for(let b=0;b<s.length;b++){const v=s[b];a(`Rendering ${b+1}/${s.length}${r.locale?` (${r.locale})`:""}…`);let w,x;const I=v.frameNodeId||null,P=r.screenLayers||!v.bytes?null:await Fr({look:v.look,bytes:v.bytes,width:d,height:h,physicalBody:Gr(t.device,v.look),screenLayers:!1}),S=P?Nr(e,P):void 0;if(S)w=S;else if(qo(v.look)){await mr(t,v.look,v.bytes,()=>!0);const k=Sr(v.look.angle,v.look.cameraPos);if(r.screenLayers){const A=await Dr(e,t.screen,d,h,I,{cameraPosition:k});w=A,x=A.layers}else w=await Tr(e,d,h,{cameraPosition:k})}else if(r.screenLayers){const k=await Wr(v.bytes,v.look,h,I);w=k,x=k.layers}else w=await Rr(v.bytes,v.look,h);P&&!S&&_r(e,P,w),g.push({shotId:v.id,bytes:w.bytes,width:w.width,height:w.height,heightFrac:Qn(F("deviceSize",v.look.deviceSize)),hOffset:F("hOffset",v.look.hOffset)/100,vOffset:F("vOffset",v.look.vOffset)/100,panelIndex:l.get(v.panelId)??0,...v.look.clipToFrame===!0?{clipToFrame:!0}:{},...x?{layers:x}:{}})}const p=Go(g,c.width,c.height),m=$o(o,r);a("Saving project…");const y=dn(Ur(i,o,r));return{panelWidth:c.width,panelHeight:c.height,count:o.length,background:m,phones:p,shadow:r.shadow,floorReflection:r.floorReflection??!1,project:JSON.stringify(y)}}}function ue(e){return/^[0-9a-fA-F]{3,8}$/.test(e)?`#${e}`:e}function ze(e,t,n,o){const{x0:r,y0:a,x1:i,y1:s}=mo(n,o,t.angle),c=e.createLinearGradient(r,a,i,s);for(const l of t.stops)c.addColorStop(Math.min(1,Math.max(0,l.at)),ue(l.color));return c}function oe(e,t,n,o,r,a,i){const s=document.createElement("canvas");s.width=n,s.height=o;try{const c=s.getContext("2d");if(!c)return;c.fillStyle=ze(c,t,n,o),c.fillRect(r,0,a,o),e.drawImage(s,r,0,a,o,i,0,a,o)}finally{s.width=0,s.height=0}}function It(e){return URL.createObjectURL(new Blob([e],{type:"image/png"}))}function St(e){return new Promise((t,n)=>{const o=new Image;o.onload=()=>t(o),o.onerror=n,o.src=e})}const Vr=128,qr=32;function Xr(e){const t=e.naturalWidth,n=e.naturalHeight;if(!(t>0&&n>0))return{rows:[]};const o=Math.min(Vr,n),r=Math.max(1,Math.min(t,Math.round(o*t/n)*2)),a=document.createElement("canvas");a.width=r,a.height=o;try{const i=a.getContext("2d",{willReadFrequently:!0});if(!i)return{rows:[]};i.drawImage(e,0,0,r,o);const s=i.getImageData(0,0,r,o).data,c=[];for(let l=0;l<o;l++){let u=-1,f=-1;for(let d=0;d<r;d++)s[(l*r+d)*4+3]<qr||(u<0&&(u=d),f=d);c.push(u<0?null:[u/r,(f+1)/r])}return{rows:c}}finally{a.width=0,a.height=0}}const Kr=16*1024*1024;function At(e){const t=(e.img.naturalWidth||0)*(e.img.naturalHeight||0),n=e.reflection?e.reflection.canvas.width*e.reflection.canvas.height:0;return t+n}function yn(){let e=0;const t=Array.from(U.values());for(const r of t)e+=At(r);const n=Array.from(U.keys());let o=0;for(;e>Kr&&o<n.length-1;){const r=U.get(n[o]);r&&(e-=At(r),r.reflection&&(r.reflection.canvas.width=0,r.reflection.canvas.height=0),U.delete(n[o])),o++}}const U=new Map,Ie=new Map;async function Yr(e,t){if(!t){const a=It(e);try{return{img:await St(a)}}finally{URL.revokeObjectURL(a)}}const n=U.get(e);if(n)return U.delete(e),U.set(e,n),n;const o=Ie.get(e);if(o)return o;const r=(async()=>{const a=It(e);try{return{img:await St(a)}}finally{URL.revokeObjectURL(a)}})();Ie.set(e,r);try{const a=await r;return U.set(e,a),yn(),a}finally{Ie.delete(e)}}async function Jr(e,t,n){const o={},r=t.panelWidth*t.count,a=t.panelHeight,i=n?.backgroundViewport,s=i?t.panelWidth*i.panelCount:r,c=i?t.panelWidth*i.panelIndex:0,l=n?.panelViewport,u=l===void 0?0:l*t.panelWidth,f=l===void 0?r:t.panelWidth;e.width=f,e.height=a;const d=e.getContext("2d");if(!d)return{silhouettes:o};n?.transparentBg?d.clearRect(0,0,r,a):t.background.kind==="gradient"?l!==void 0?oe(d,t.background.gradient,r,a,u,f,0):i?oe(d,t.background.gradient,s,a,c,r,0):(d.fillStyle=ze(d,t.background.gradient,r,a),d.fillRect(0,0,r,a)):t.background.kind==="perPanel"?t.background.colors.forEach((m,y)=>{d.fillStyle=ue(m),d.fillRect(y*t.panelWidth-u,0,t.panelWidth,a)}):t.background.fills.forEach((m,y)=>{const b=y*t.panelWidth-u;l!==void 0&&y!==l||(m.kind==="solid"?(d.fillStyle=ue(m.color),d.fillRect(b,0,t.panelWidth,a)):l!==void 0?oe(d,m.gradient,r,a,u,f,0):i?oe(d,m.gradient,s,a,c+b,t.panelWidth,b):(d.fillStyle=ze(d,m.gradient,r,a),d.fillRect(b,0,t.panelWidth,a)))}),d.save(),d.translate(-u,0);const h=n?.phoneRange?Math.max(0,n.phoneRange.start):0,g=n?.phoneRange?Math.min(t.phones.length,n.phoneRange.end):t.phones.length,p=n?.reuseDecodedPhones===!0;for(let m=h;m<g;m++){const y=t.phones[m],b=n?.clip==="panel"||n?.clip===void 0&&y.clipToFrame===!0;if(n?.skipShotId&&y.shotId===n.skipShotId)continue;const v=await Yr(y.bytes,p),w=v.img,x=v.silhouette??Xr(w);p&&(v.silhouette=x),o[y.shotId]=x,Zr(d,v,y,t,b,p)}return d.restore(),{silhouettes:o}}function Zr(e,t,n,o,r=n.clipToFrame===!0,a=!1,i=1){const s=t.img;r&&(e.save(),e.beginPath(),e.rect(n.panelIndex*o.panelWidth,0,o.panelWidth,o.panelHeight),e.clip()),o.floorReflection&&Qr(e,t,n,a),e.save(),o.shadow&&(e.shadowColor="rgba(0,0,0,0.35)",e.shadowBlur=o.panelWidth*.03*i,e.shadowOffsetY=o.panelHeight*.012*i),e.drawImage(s,n.x,n.y,n.width,n.height),e.restore(),r&&e.restore()}function Qr(e,t,n,o){const r=Math.round(n.height*.45);if(r<=0||n.width<=0)return;const a=o?t.reflection:void 0;if(a&&a.width===n.width&&a.height===n.height){e.drawImage(a.canvas,n.x,n.y+n.height,n.width,r);return}const i=t.img,s=document.createElement("canvas");s.width=Math.max(1,n.width),s.height=Math.max(1,r);const c=s.getContext("2d");if(!c)return;c.save(),c.translate(0,r),c.scale(1,-1),c.drawImage(i,0,r-n.height,n.width,n.height),c.restore();const l=c.createLinearGradient(0,0,0,r);l.addColorStop(0,"rgba(0,0,0,0.34)"),l.addColorStop(1,"rgba(0,0,0,0)"),c.globalCompositeOperation="destination-in",c.fillStyle=l,c.fillRect(0,0,n.width,r),e.drawImage(s,n.x,n.y+n.height,n.width,r),o&&(t.reflection={width:n.width,height:n.height,canvas:s},yn())}const bn=$.lineHeight,ea=$.bandInset;function ta(e,t,n){if(!e)return[t];const o=t.split(/\s+/).filter(Boolean),r=[];let a="";for(const i of o){const s=a?`${a} ${i}`:i;a&&e.measureText(s).width>n?(r.push(a),a=i):a=s}return a&&r.push(a),r}function na(e,t){if(!e)return 0;let n=0;for(const o of t)n=Math.max(n,e.measureText(o).width);return n}function Pt(e,t,n){return e==="center"?t+n/2:e==="right"?t+n:t}function vn(e,t,n,o){const r=t.map((g,p)=>{const m=g.text.trim();if(!m)return null;const y=g.sizePt*(o/he),b=Ge(g.fontId).family;e&&(e.font=`${K} ${y}px "${b}"`);const w=(D(g.anchor)?Q(g):g.maxWidth)*n,x=ta(e,m,w),I=y*(g.lineHeight??bn),P=x.length*I,S=Math.max(P,(g.reserveLines??x.length)*I);return{layer:g,index:p,lines:x,px:y,lineH:I,width:na(e,x),blockH:P,reservedH:S,boxWidth:w}}),a=r.filter(g=>g!==null&&D(g.layer.anchor)),i=a.filter(g=>g.layer.band==="bottom"),s=a.filter(g=>g.layer.band!=="bottom"),c=g=>g[0]?.layer.bandInset??ea,l=(1-c(i))*o-i.reduce((g,p)=>g+p.reservedH,0);let u=c(s)*o,f=l,d=0;const h=[];for(const g of r){if(!g)continue;if(!D(g.layer.anchor)){const w=g.layer.anchor.x*n,x=g.layer.anchor.y*o;h.push({layer:g.layer,index:g.index,x:Pt(g.layer.align,w,g.boxWidth),yTop:x,lines:g.lines,px:g.px,lineH:g.lineH,width:g.width,boxLeft:w,boxWidth:g.boxWidth,boxTop:x,boxHeight:g.blockH});continue}const p=g.layer.band==="bottom",m=p?f:u,y=m+(g.reservedH-g.blockH)/2,b=Qt(g.layer)*n,v=Pt(g.layer.align,b,g.boxWidth);h.push({layer:g.layer,index:g.index,x:v,yTop:y,lines:g.lines,px:g.px,lineH:g.lineH,width:g.width,boxLeft:b,boxWidth:g.boxWidth,boxTop:m,boxHeight:g.reservedH}),p?f+=g.reservedH:u+=g.reservedH,d=Math.max(d,y+g.blockH)}return{placed:h,bandBottom:d}}function oa(e,t,n,o){e.save(),e.textBaseline="top";const{placed:r}=vn(e,t,n,o);for(const a of r){e.fillStyle=ue(a.layer.color),e.textAlign=a.layer.align,e.font=`${K} ${a.px}px "${Ge(a.layer.fontId).family}"`;let i=a.yTop;for(const s of a.lines)e.fillText(s,a.x,i),i+=a.lineH}e.restore()}function ra(e,t){return e.sizePt*(t/he)*(e.lineHeight??bn)}function aa(e,t,n,o){const r=vn(e,t,n,o).placed;e?.save(),e&&(e.textBaseline="top");const a=r.map(i=>{const s=i.layer.align==="center"?i.x-i.width/2:i.layer.align==="right"?i.x-i.width:i.x,c=i.lines.length*i.lineH;let l=i.yTop,u=i.yTop+c;if(e){e.font=`${K} ${i.px}px "${Ge(i.layer.fontId).family}"`;const f=e.measureText(i.lines[0]).actualBoundingBoxAscent,d=e.measureText(i.lines[i.lines.length-1]).actualBoundingBoxDescent;Number.isFinite(f)&&Number.isFinite(d)&&(l=i.yTop-f,u=i.yTop+(i.lines.length-1)*i.lineH+d)}return{index:i.index,anchorX:i.boxLeft/n,top:i.yTop/o,boxLeft:i.boxLeft/n,boxTop:i.boxTop/o,boxWidth:i.boxWidth/n,boxHeight:i.boxHeight/o,left:s/n,width:i.width/n,height:c/o,inkTop:l/o,inkHeight:(u-l)/o}});return e?.restore(),a}function ia(e,t,n,o,r){t.forEach((a,i)=>{const s=r[a];!s||s.length===0||(e.save(),e.translate(i*n,0),oa(e,s,n,o),e.restore())})}const sa=""+new URL("Inter-SemiBold-B9yU462S.woff2",import.meta.url).href,la=""+new URL("Manrope-SemiBold-44nuYf5T.woff2",import.meta.url).href,ca=""+new URL("Poppins-SemiBold-DJVo7c07.woff2",import.meta.url).href,da=""+new URL("Fraunces-SemiBold-BtraKtER.woff2",import.meta.url).href,ua=""+new URL("SpaceGrotesk-SemiBold-CyO2J5Y0.woff2",import.meta.url).href,fa={inter:sa,manrope:la,poppins:ca,fraunces:da,"space-grotesk":ua},ha=se.map(e=>({...e,url:fa[e.id]}));let re=null;function pa(){return re||(re=(async()=>{const e=new Set;document.fonts.forEach(t=>e.add(`${t.family}/${t.weight}`)),await Promise.all(ha.filter(t=>!e.has(`${t.family}/${String(K)}`)).map(async t=>{const n=new FontFace(t.family,`url(${t.url})`,{weight:String(K)});await n.load(),document.fonts.add(n)})),await document.fonts.ready})().catch(e=>{throw re=null,e})),re}const ma=22/he,ga=1.1,Ct=4,ya=.063,ba=.167,X=Math.round(ma*he),va=.02,wa=50;function ye(e,t){const n=W(e,t.box);if(!n||!t.silhouette||t.silhouette.rows.length===0)return n;const{frame:o}=t,r=t.silhouette.rows,a=o.height/r.length;let i=1/0,s=1/0,c=-1/0,l=-1/0;const u=Math.max(0,Math.floor((n.y-o.y)/a)),f=Math.min(r.length-1,Math.ceil((n.y+n.height-o.y)/a)-1);for(let d=u;d<=f;d++){const h=r[d];if(!h)continue;const g=W(n,{x:o.x+h[0]*o.width,y:o.y+d*a,width:(h[1]-h[0])*o.width,height:a});g&&(i=Math.min(i,g.x),s=Math.min(s,g.y),c=Math.max(c,g.x+g.width),l=Math.max(l,g.y+g.height))}return c>i&&l>s?{x:i,y:s,width:c-i,height:l-s}:null}function W(e,t){const n=Math.max(e.x,t.x),o=Math.max(e.y,t.y),r=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height);return r<=n||a<=o?null:{x:n,y:o,width:r-n,height:a-o}}function fe(e,t){return W(e,t)}function kt(e,t){const n=Math.abs(e-t)%360;return n>180?360-n:n}function Ot(e){return fr(e.cameraPos??un(e.angle))}function be(e,t,n,o,r,a,i){if(t.length===0)return[];const s=[];for(const c of aa(e,t,r,a)){const l=t[c.index];if(!l)continue;const u=fe({x:(o+c.left)*r,y:c.top*a,width:c.width*r,height:c.height*a},i);u&&s.push({ref:{panelId:n,panelIndex:o,layerIndex:c.index,band:D(l.anchor)},box:u,lineHeightPx:ra(l,a)})}return s}function wn(e,t,n,o){return n.height<=je(e,t,o)}function je(e,t,n){const o=e.y+e.height/2<=t.y+t.height/2;return n*(o?ba:ya)}function De(e,t,n){return n.height<=je(e.box,t.box,e.lineHeightPx)+je(t.box,e.box,t.lineHeightPx)}function xa(e){const{ctx:t,panelIds:n,panelWidth:o,panelHeight:r}=e,a={x:0,y:0,width:o*n.length,height:r};t?.save();try{return Ia(e,a)}finally{t?.restore()}}function Ia(e,t){const{ctx:n,panelIds:o,panelWidth:r,panelHeight:a,captionLayers:i}=e,s=o.flatMap((p,m)=>be(n,i[p]??[],p,m,r,a,t)),c=[];for(const p of e.phones){const y=e.clip==="panel"||e.clip===void 0&&p.clipToFrame===!0?{x:p.panelIndex*r,y:0,width:r,height:a}:t,b={x:p.x,y:p.y,width:p.width,height:p.height},v=fe(b,y);v&&c.push({shotId:p.shotId,box:v,frame:b,silhouette:e.silhouettes?.[p.shotId],layoutHeight:p.height})}const l=[];for(let p=0;p<s.length;p++)for(let m=p+1;m<s.length;m++){const y=W(s[p].box,s[m].box);y&&l.push({a:s[p].ref,b:s[m].ref,overlap:y,depthFrac:a>0?y.height/a:0,inkUncertain:De(s[p],s[m],y)})}const u=[];for(const p of s)for(const m of c){const y=ye(p.box,m);y&&u.push({caption:p.ref,shotId:m.shotId,overlap:y,depthFrac:a>0?y.height/a:0,inkUncertain:wn(p.box,m.box,y,p.lineHeightPx)})}const f=[];for(let p=0;p<c.length;p++)for(let m=p+1;m<c.length;m++){const y=c[p],b=c[m],v=W(y.box,b.box);if(!v)continue;const w=[],x=Math.max(y.layoutHeight,b.layoutHeight),I=Math.min(y.layoutHeight,b.layoutHeight);I>0&&x/I>=ga&&w.push("scale");const P=e.looks?.[y.shotId],S=e.looks?.[b.shotId],k=!!P&&!!S;P&&S&&(kt(Ot(P),Ot(S))>=Ct&&w.push("angle"),kt(F("roll",P.roll),F("roll",S.roll))>=Ct&&w.push("roll"));const A=Math.min(y.box.width*y.box.height,b.box.width*b.box.height);f.push({shotIdA:y.shotId,shotIdB:b.shotId,overlap:v,coverage:A>0?v.width*v.height/A:0,deliberate:w.length>0,signals:w,anglesKnown:k})}const d=new Set;for(const p of l)p.a.band&&d.add(p.a.panelId),p.b.band&&d.add(p.b.panelId);for(const p of u)p.caption.band&&d.add(p.caption.panelId);const h=[],g=[];return o.forEach((p,m)=>{if(!d.has(p))return;const y=Aa(e,p,m,t,s,c);y!==null&&g.push({panelId:p,maxWidth:y});const b=Pa(e,p,m,t,s,c);b&&h.push(b)}),{captionsMeasurable:n!=null,captionOverlaps:l,captionDeviceOverlaps:u,deviceOverlaps:f,suggestions:h,widthSuggestions:g,hasWarning:l.length>0||u.length>0||f.some(p=>!p.deliberate)}}function Sa(e){const{ctx:t,panelIds:n,panelWidth:o,panelHeight:r}=e,a={x:0,y:0,width:o*n.length,height:r},i=[];for(const l of e.phones){const f=e.clip==="panel"||e.clip===void 0&&l.clipToFrame===!0?{x:l.panelIndex*o,y:0,width:o,height:r}:a,d={x:l.x,y:l.y,width:l.width,height:l.height},h=fe(d,f);h&&i.push({shotId:l.shotId,box:h,frame:d,silhouette:e.silhouettes?.[l.shotId],layoutHeight:l.height})}const s=(l,u,f)=>{const d=n.indexOf(l);if(d<0||!t)return[];t.save();try{return be(t,u,l,d,o,r,f?a:{x:-1e9,y:-1e9,width:2e9,height:2e9})}finally{t.restore()}},c=new Map(n.map(l=>[l,s(l,e.captionLayers[l]??[],!0)]));return{measurable:t!=null,commit(l,u){c.set(l,s(l,u,!0))},probe(l,u){const f=s(l,u,!1),d=f.flatMap(p=>{const m=fe(p.box,a);return m?[{...p,box:m}]:[]}),h=n.flatMap(p=>p===l?[]:c.get(p)??[]),g=[];for(const p of d){for(const m of i){const y=ye(p.box,m);y&&g.push({layerIndex:p.ref.layerIndex,band:p.ref.band,against:"device",samePanelBand:!1,depthFrac:r>0?y.height/r:0,inkUncertain:wn(p.box,m.box,y,p.lineHeightPx)})}for(const m of h){const y=W(p.box,m.box);y&&g.push({layerIndex:p.ref.layerIndex,band:p.ref.band,against:"caption",samePanelBand:!1,depthFrac:r>0?y.height/r:0,inkUncertain:De(p,m,y)})}}for(let p=0;p<d.length;p++)for(let m=p+1;m<d.length;m++){const y=W(d[p].box,d[m].box);if(!y)continue;const b=r>0?y.height/r:0,v=De(d[p],d[m],y);for(const[w,x]of[[d[p],d[m]],[d[m],d[p]]])g.push({layerIndex:w.ref.layerIndex,band:w.ref.band,against:"caption",samePanelBand:x.ref.band,depthFrac:b,inkUncertain:v})}return{hits:g,boxes:f.map(p=>({layerIndex:p.ref.layerIndex,band:p.ref.band,box:p.box}))}}}}function Aa(e,t,n,o,r,a){const i=e.captionLayers[t]??[];if(!i.length||i.some(u=>!D(u.anchor)))return null;const s=r.filter(u=>u.ref.panelId!==t).map(u=>u.box),c=u=>a.some(f=>ye(u,f))||s.some(f=>W(u,f)),l=Math.min(...i.map(u=>u.maxWidth));for(let u=Math.ceil(l*100)-1;u>=10;u--){const f=u/100,d=be(e.ctx,i.map(h=>({...h,maxWidth:f})),t,n,e.panelWidth,e.panelHeight,o);if(d.length&&d.every((h,g)=>!c(h.box)&&!d.slice(g+1).some(p=>W(h.box,p.box))))return f}return null}function Pa(e,t,n,o,r,a){const i=e.captionLayers[t]??[],s=i.flatMap((f,d)=>D(f.anchor)&&f.text.trim()?[d]:[]);if(s.length===0||!(Math.min(...s.map(f=>i[f].sizePt))>X))return null;const l=r.filter(f=>!(f.ref.panelId===t&&f.ref.band)).map(f=>f.box),u=f=>a.some(d=>ye(f,d))||l.some(d=>W(f,d));for(let f=1;f<=wa;f++){const d=Math.round((1-f*va)*100)/100,h=new Map(s.map(y=>[y,i[y].sizePt*d]));if(Math.min(...Array.from(h.values()))<X)return null;const g=i.map((y,b)=>{const v=h.get(b);return v===void 0?y:{...y,sizePt:v}});if(be(e.ctx,g,t,n,e.panelWidth,e.panelHeight,o).filter(y=>y.ref.band).every(y=>!u(y.box)))return{panelId:t,scale:d,layers:s.map(y=>({layerIndex:y,fromSizePt:i[y].sizePt,toSizePt:h.get(y)}))}}return null}de.colorways;class xn{frame=[];back=[];accent=[];allBody=[];model;scene;renderer;profile;envTexture=null;constructor(t,n,o,r){this.model=t,this.scene=n,this.renderer=o,this.profile=Ze(r);const{frame:a,back:i,accent:s}=this.profile.body;t.traverse(c=>{const l=c;if(!l.isMesh)return;(Array.isArray(l.material)?l.material:[l.material]).forEach(f=>{const d=f;!d||!d.name||(a.includes(d.name)?this.push(this.frame,d):i.includes(d.name)?this.push(this.back,d):s.includes(d.name)&&this.push(this.accent,d),this.push(this.allBody,d))})})}push(t,n){t.includes(n)||t.push(n)}get finishMaterials(){return[...this.frame,...this.back]}paint(t,n){const o=n instanceof R?n:new R(n);t.forEach(r=>{r.color=o.clone(),r.needsUpdate=!0})}setColorway(t){if(t==="custom")return;const n=this.profile.colorways.find(o=>o.id===t)??this.profile.colorways[0];n&&(this.paint(this.frame,n.frame),this.paint(this.back,n.back),this.paint(this.accent,n.accent))}setCustomColor(t){const n=new R(t),o=n.clone().lerp(new R(16777215),.2),r=n.clone().multiplyScalar(.6);this.paint(this.frame,n),this.paint(this.back,o),this.paint(this.accent,r)}setFinish(t){const n=Number.isFinite(t)?Math.max(0,Math.min(1,t)):0;this.finishMaterials.forEach(o=>{o.userData.baseRoughness===void 0&&(o.userData.baseRoughness=o.roughness);const r=o.userData.baseRoughness;o.roughness=r*(1-n),o.needsUpdate=!0})}clearcoatUpgraded=!1;usesPhysicalFinish(){return this.clearcoatUpgraded}setClearcoat(t){const n=Math.max(0,Math.min(1,t));n>0&&!this.clearcoatUpgraded&&this.upgradeFinishToPhysical(),this.clearcoatUpgraded&&this.finishMaterials.forEach(o=>{const r=o;r.clearcoat=n,r.clearcoatRoughness=.1,r.needsUpdate=!0})}upgradeFinishToPhysical(){this.clearcoatUpgraded=!0;const t=new Map;for(const o of Array.from(new Set(this.finishMaterials))){const r=new Nn;r.color.copy(o.color),r.metalness=o.metalness,r.roughness=o.roughness,r.map=o.map,r.normalMap=o.normalMap,r.normalScale.copy(o.normalScale),r.roughnessMap=o.roughnessMap,r.metalnessMap=o.metalnessMap,r.aoMap=o.aoMap,r.aoMapIntensity=o.aoMapIntensity,r.emissive.copy(o.emissive),r.emissiveMap=o.emissiveMap,r.emissiveIntensity=o.emissiveIntensity,r.envMapIntensity=o.envMapIntensity,r.transparent=o.transparent,r.opacity=o.opacity,r.alphaTest=o.alphaTest,r.side=o.side,r.flatShading=o.flatShading,r.vertexColors=o.vertexColors,r.name=o.name,r.userData={...o.userData},r.clearcoat=0,t.set(o,r)}this.model.traverse(o=>{const r=o;if(r.isMesh)if(Array.isArray(r.material))r.material=r.material.map(a=>t.get(a)??a);else{const a=t.get(r.material);a&&(r.material=a)}});const n=o=>o.map(r=>t.get(r)??r);this.frame=n(this.frame),this.back=n(this.back),this.allBody=n(this.allBody)}environmentMap(){if(!this.envTexture){const t=new Gn(this.renderer);this.envTexture=t.fromScene(new _n,.04).texture,t.dispose()}return this.envTexture}setClay(t){const n=br.find(r=>r.id===t),o=n?new R(n.color):new R(t);this.allBody.forEach(r=>{r.userData.clayStashedMap===void 0&&(r.userData.clayStashedMap=r.map),r.color=o.clone(),r.metalness=0,r.roughness=.85,r.map=null,r.needsUpdate=!0})}clayOff(){this.allBody.forEach(t=>{t.userData.clayStashedMap!==void 0&&(t.map=t.userData.clayStashedMap,t.userData.clayStashedMap=void 0,t.needsUpdate=!0)})}setReflections(t){this.scene.environment=t?this.environmentMap():null}setRoll(t){this.model.rotation.z=t*Math.PI/180}}const Tt=1.35;class In{materials=[];glassOverlays=[];screenMesh=null;flatPlane=null;texture=null;appliedBytes=null;flatScreenOn=!1;profile;model;passRestore=[];constructor(t,n){this.profile=Ze(n),this.model=t;const o=this.profile.screen.material;t.traverse(r=>{const a=r;if(!a.isMesh)return;(Array.isArray(a.material)?a.material:[a.material]).forEach(s=>{const c=s;c&&c.name===o&&!this.materials.includes(c)&&(this.materials.push(c),this.screenMesh=a)})}),this.dimGlassOverlay(t),this.prepareScreen(),this.setGlare(null)}get found(){return this.materials.length>0}setGlare(t){this.materials.forEach(n=>{n.envMap=t,n.envMapIntensity=t?.6:0,n.metalness=t?.5:0,n.roughness=t?.15:1,n.needsUpdate=!0}),this.glassOverlays.forEach(n=>{n.opacity=t?.08:0,n.needsUpdate=!0})}setFlatScreen(t){if(this.flatScreenOn=t,!this.screenMesh)return;if(this.flatPlane){this.screenMesh.remove(this.flatPlane);const v=this.flatPlane.material;v.map?.dispose(),v.dispose(),this.flatPlane.geometry.dispose(),this.flatPlane=null}if(!t||!this.texture)return;this.screenMesh.geometry.computeBoundingBox();const n=this.screenMesh.geometry.boundingBox;if(!n)return;const o=n.max.x-n.min.x,r=n.max.y-n.min.y,a=n.max.z-n.min.z,i=(n.max.x+n.min.x)/2,s=(n.max.y+n.min.y)/2,c=(n.max.z+n.min.z)/2,l=r<=o&&r<=a?"y":a<=o&&a<=r?"z":"x",u=this.texture.clone();u.needsUpdate=!0,u.colorSpace=ot,u.flipY=!1,u.center.set(.5,.5),u.wrapS=ne,u.wrapT=ne;const{coverFill:f,coverCornerRatio:d,coverRepeat:h}=this.profile.screen;u.repeat.set(h.x,h.y);const g=l==="x"?a:o,p=l==="z"||l==="x"?r:a,m=Math.min(g,p)*f*d,y=Ca(g*f,p*f,m),b=new $n(y,new Bn({map:u,emissive:new R(16777215),emissiveMap:u,emissiveIntensity:Tt,color:new R(0),toneMapped:!1,side:Vn,depthTest:!0,depthWrite:!0,polygonOffset:!0,polygonOffsetFactor:-4,polygonOffsetUnits:-4}));l==="y"?(b.rotation.x=-Math.PI/2,b.position.set(i,n.max.y,c)):l==="x"?(b.rotation.y=Math.PI/2,b.position.set(n.max.x,s,c)):b.position.set(i,s,n.max.z),b.renderOrder=999,this.screenMesh.add(b),this.flatPlane=b}setLayerPass(t){this.restoreLayerPass();const n=a=>{const i=a.visible;a.visible=!1,this.passRestore.push(()=>{a.visible=i})};if(t==="screen"){this.model.traverse(a=>{const i=a;if(!i.isMesh||i===this.flatPlane)return;(Array.isArray(i.material)?i.material:[i.material]).forEach(c=>{c&&!this.materials.includes(c)&&n(c)})});return}this.glassOverlays.forEach(n);const o=a=>new Xn({blending:Jn,blendEquation:Yn,blendSrc:rt,blendDst:rt,depthTest:!0,depthWrite:!0,side:a?.side??Kn,polygonOffset:a?.polygonOffset??!1,polygonOffsetFactor:a?.polygonOffsetFactor??0,polygonOffsetUnits:a?.polygonOffsetUnits??0}),r=(a,i)=>{const s=a.material;if(!(Array.isArray(s)?s:[s]).some(i))return;const c=[],l=u=>{if(!i(u))return u;const f=o(u);return c.push(f),f};a.material=Array.isArray(s)?s.map(l):l(s),this.passRestore.push(()=>{a.material=s,c.forEach(u=>u.dispose())})};this.model.traverse(a=>{const i=a;i.isMesh&&(i===this.flatPlane?r(i,()=>!0):r(i,s=>this.materials.includes(s)))})}restoreLayerPass(){const t=this.passRestore.reverse();this.passRestore=[],t.forEach(n=>n())}screenCornersWorld(){const t=this.screenMesh;if(!t)return null;const n=t.geometry;n.computeBoundingBox();const o=n.boundingBox,r=n.attributes.position,a=n.attributes.uv;if(!o||!r||!a)return null;const i=o.getSize(new G),s=o.getCenter(new G),c=i.y<=i.x&&i.y<=i.z?"y":i.z<=i.x&&i.z<=i.y?"z":"x",[l,u]=c==="y"?["x","z"]:c==="z"?["x","y"]:["z","y"],f=this.profile.screen.coverFill,{repeat:d}=this.profile.screen,h={};for(const b of[-1,1])for(const v of[-1,1]){const w=new G;w[c]=o.max[c],w[l]=s[l]+b*i[l]*f/2,w[u]=s[u]+v*i[u]*f/2;let x=-1,I=1/0;for(let A=0;A<r.count;A++){const C=Math.hypot(r.getComponent(A,"xyz".indexOf(l))-w[l],r.getComponent(A,"xyz".indexOf(u))-w[u]);C<I&&(I=C,x=A)}if(x<0)return null;const P=.5+(a.getX(x)-.5)*d.x,S=.5+(a.getY(x)-.5)*d.y;if(P===.5||S===.5)return null;const k=`${S<.5?"t":"b"}${P<.5?"l":"r"}`;if(h[k])return null;h[k]=w}const{tl:g,tr:p,br:m,bl:y}=h;return!g||!p||!m||!y?null:(t.updateWorldMatrix(!0,!1),{tl:g.applyMatrix4(t.matrixWorld),tr:p.applyMatrix4(t.matrixWorld),br:m.applyMatrix4(t.matrixWorld),bl:y.applyMatrix4(t.matrixWorld)})}get cornerRatio(){return this.profile.screen.coverCornerRatio}restoreScreen(){this.prepareScreen()}prepareScreen(){this.materials.forEach(t=>{t.color=new R(0),t.emissive=new R(16777215),t.emissiveIntensity=1,t.roughness=1,t.metalness=0,t.needsUpdate=!0})}dimGlassOverlay(t){t.traverse(n=>{const o=n;if(!o.isMesh)return;(Array.isArray(o.material)?o.material:[o.material]).forEach(a=>{const i=a;i&&i.name!==this.profile.screen.material&&i.transparent&&i.opacity>.2&&this.glassOverlays.push(i)})})}applyWallpaper(t){if(this.appliedBytes===t&&this.texture)return this.lightScreen(this.texture),Promise.resolve();const n=new Blob([t],{type:"image/png"}),o=URL.createObjectURL(n),r=this.texture;return new Promise((a,i)=>{const s=new Image;s.onload=()=>{try{const c=document.createElement("canvas");c.width=s.naturalWidth,c.height=s.naturalHeight;const l=c.getContext("2d");if(!l)throw new Error("2D context unavailable for wallpaper blit");l.drawImage(s,0,0);const u=new zn(c);u.colorSpace=ot,u.flipY=!1,u.center.set(.5,.5),u.wrapS=ne,u.wrapT=ne,u.repeat.set(this.profile.screen.repeat.x,this.profile.screen.repeat.y),u.needsUpdate=!0,this.texture=u,this.appliedBytes=t,this.lightScreen(u),this.flatScreenOn&&this.setFlatScreen(!0),r?.dispose(),URL.revokeObjectURL(o),a()}catch(c){URL.revokeObjectURL(o),i(c)}},s.onerror=()=>{URL.revokeObjectURL(o),i(new Error("wallpaper image failed to decode"))},s.src=o})}lightScreen(t){this.materials.forEach(n=>{n.map=t,n.emissiveMap=t,n.emissive=new R(16777215),n.emissiveIntensity=Tt,n.color=new R(0),n.needsUpdate=!0})}}function Ca(e,t,n){const o=e/2,r=t/2,a=Math.min(n,o,r),i=new jn;i.moveTo(-o+a,-r),i.lineTo(o-a,-r),i.quadraticCurveTo(o,-r,o,-r+a),i.lineTo(o,r-a),i.quadraticCurveTo(o,r,o-a,r),i.lineTo(-o+a,r),i.quadraticCurveTo(-o,r,-o,r-a),i.lineTo(-o,-r+a),i.quadraticCurveTo(-o,-r,-o+a,-r);const s=new Dn(i,16),c=s.attributes.position,l=new Float32Array(c.count*2);for(let u=0;u<c.count;u++)l[u*2]=(c.getX(u)+o)/e,l[u*2+1]=(c.getY(u)+r)/t;return s.setAttribute("uv",new qn(l,2)),s}function et(e){return`build-shot-${e+1}`}function Sn(e){const t=[...e.panelIds??[]];for(const n of e.shots)t.includes(n.panelId)||t.push(n.panelId);return t}const ka=1900,Oa=2800;function Ta(e){return new Promise((t,n)=>{e.toBlob(o=>{if(!o)return n(new Error("canvas toBlob returned null"));o.arrayBuffer().then(r=>t(new Uint8Array(r)),n)},"image/png")})}async function An(e,t,n,o={}){await pa();const r=Sn(e);if(o.panelViewport!==void 0&&(!Number.isInteger(o.panelViewport)||o.panelViewport<0||o.panelViewport>=r.length))throw new Error("buildStrip: panel viewport is outside the strip");const a=r.map(d=>({id:d})),i=e.shots.map((d,h)=>({id:et(h),panelId:d.panelId,frameNodeId:"",frameName:`screen-${h+1}`,bytes:t.screens[h]??null,look:d.look,thumb:null,thumbStale:!1})),c={panelPresetId:Z(e.panelPresetId).id,bgMode:e.bgMode,gradientStops:e.gradientStops,gradientAngle:e.gradientAngle,gradientFrom:e.gradientFrom,gradientTo:e.gradientTo,gradientDir:e.gradientDir,panelColors:e.panelColors,shadow:e.shadow,floorReflection:e.floorReflection,panelBackgrounds:e.panelBackgrounds,selectedShotId:null,renderScale:o.renderScale,locale:n},l=o.onProgress??(()=>{});let u=o.refs,f=null;if(!u){const d=no(e.panelPresetId);f=hn(ka,Oa);const h=await pn(f,d);u={stage:f,device:new xn(h,f.scene,f.renderer,d),screen:new In(h,d)}}try{const d=await $r(u.stage,u,i,a,c,l);if(!d)throw new Error("buildStrip: nothing renderable (no shots)");const h=document.createElement("canvas");try{const g={...o.panelViewport!==void 0?{panelViewport:o.panelViewport}:{},...o.clip?{clip:o.clip}:{},...o.backgroundViewport?{backgroundViewport:o.backgroundViewport}:{}},p=await Jr(h,d,Object.keys(g).length>0?g:void 0),m=d.panelWidth,y=d.panelHeight,b=h.getContext("2d");if(!b)throw new Error("buildStrip: 2D context unavailable");b.save(),o.panelViewport!==void 0&&b.translate(-o.panelViewport*m,0),ia(b,r,m,y,t.captionText??{}),b.restore();const v=xa({phones:d.phones,panelIds:r,captionLayers:t.captionText??{},panelWidth:m,panelHeight:y,ctx:b,looks:Object.fromEntries(i.map(A=>[A.id,A.look])),clip:o.clip,silhouettes:p.silhouettes}),w=o.renderScale&&o.renderScale>0&&o.renderScale<1?o.renderScale:1,x=[],I=o.panelViewport??0,P=o.panelViewport===void 0?d.count:I+1;for(let A=I;A<P;A++){const C=document.createElement("canvas");C.width=Math.max(1,Math.round(m*w)),C.height=Math.max(1,Math.round(y*w));const T=C.width,O=C.height;try{const E=C.getContext("2d",{alpha:!1});if(!E)throw new Error("buildStrip: 2D context unavailable");E.fillStyle="#000",E.fillRect(0,0,T,O),E.drawImage(h,o.panelViewport===void 0?A*m:0,0,m,y,0,0,T,O),x.push({index:A,bytes:await Ta(C),width:T,height:O})}finally{C.width=0,C.height=0}}const S=d.phones.map(({shotId:A,panelIndex:C,x:T,y:O,width:E,height:_})=>({shotId:A,panelIndex:C,x:T,y:O,width:E,height:_})),k={panelIds:[...r],panelWidth:m,panelHeight:y,phones:d.phones.map(({shotId:A,panelIndex:C,x:T,y:O,width:E,height:_,clipToFrame:H})=>({shotId:A,panelIndex:C,x:T,y:O,width:E,height:_,...H===!0?{clipToFrame:!0}:{}})),silhouettes:p.silhouettes,...o.clip?{clip:o.clip}:{}};return{panels:x,layout:v,phones:S,geometry:k}}finally{h.width=0,h.height=0}}finally{f&&f.dispose()}}function Ma(e){if(!e||e.length===0)return null;const t=Array.from(new Set(e.flatMap(o=>o.frames))).sort((o,r)=>o-r).map(o=>`Frame ${o+1}`),n=t.length===0?"":t.length===1?` in ${t[0]}`:` in ${t.slice(0,-1).join(", ")} and ${t[t.length-1]}`;return e.length===1?`${e[0].kind==="caption-device"?"A caption still overlaps a device":e[0].kind==="caption-caption"?"Two captions still overlap":"Two devices still collide"}${n}.`:`${e.length} layout overlaps still remain${n}.`}const We=.005,Ea=.02,La=12;function Se(e){return Math.max(1,Math.round(e*100))}function Ae(e){return`${e.kind}:${e.frames.join(",")}:${e.anchored}`}function Ra(e,t){const n=new Map(e.suggestions.map(i=>[i.panelId,i.scale])),o=new Map((e.widthSuggestions??[]).map(i=>[i.panelId,i.maxWidth])),r=[];for(const i of e.captionOverlaps){if(i.inkUncertain||i.depthFrac<We)continue;const[s,c]=i.a.band===i.b.band?[i.a,i.b]:i.a.band?[i.a,i.b]:[i.b,i.a],l=Pe([t.frameOfPanel(s.panelId),t.frameOfPanel(c.panelId)]);l.length!==0&&r.push({kind:"caption-caption",frames:l,depthPct:Se(i.depthFrac),anchored:!i.a.band||!i.b.band,...Mt(n,s.band?s.panelId:null),...Et(o,s.band?s.panelId:null)})}for(const i of e.captionDeviceOverlaps){if(i.inkUncertain||i.depthFrac<We)continue;const s=Pe([t.frameOfPanel(i.caption.panelId),t.frameOfShot(i.shotId)]);s.length!==0&&r.push({kind:"caption-device",frames:s,depthPct:Se(i.depthFrac),anchored:!i.caption.band,...Mt(n,i.caption.band?i.caption.panelId:null),...Et(o,i.caption.band?i.caption.panelId:null)})}for(const i of e.deviceOverlaps){if(i.deliberate||i.coverage<Ea)continue;const s=Pe([t.frameOfShot(i.shotIdA),t.frameOfShot(i.shotIdB)]);s.length!==0&&r.push({kind:"device-device",frames:s,depthPct:Se(i.coverage),anchored:!1})}const a=new Map;for(const i of r){const s=a.get(Ae(i));s?i.depthPct>s.depthPct?a.set(Ae(i),{...i,clearAtScale:i.clearAtScale??s.clearAtScale,clearAtMaxWidth:i.clearAtMaxWidth??s.clearAtMaxWidth}):s.clearAtScale==null&&i.clearAtScale!=null&&(s.clearAtScale=i.clearAtScale):a.set(Ae(i),i),s&&s.clearAtMaxWidth==null&&i.clearAtMaxWidth!=null&&(s.clearAtMaxWidth=i.clearAtMaxWidth)}return Array.from(a.values()).sort((i,s)=>s.depthPct-i.depthPct).slice(0,La).sort((i,s)=>i.frames[0]-s.frames[0]||i.kind.localeCompare(s.kind))}function Pe(e){const[t,...n]=e;return t<0?[]:[t,...n.filter(o=>o>=0&&o!==t)]}function Mt(e,t){const n=t==null?void 0:e.get(t);return n==null?{}:{clearAtScale:Math.round(n*100)/100}}function Et(e,t){const n=t==null?void 0:e.get(t);return n==null?{}:{clearAtMaxWidth:n}}function Fa(e,t){if(t.length===0)return e;const n=e.captionStyles;if(!n)return e;const o={};for(const[r,a]of Object.entries(n))o[r]=a.map(i=>({...i}));for(const r of t){const a=o[r.panelId];if(a)for(const i of r.layers){const s=a[i.layerIndex];s&&(s.sizePt=i.toSizePt)}}return{...e,captionStyles:o}}function Ce(e){return e.frames.map(t=>`frame ${t+1}`).join(" + ")}function Na(e,t,n){if(!e.captionsMeasurable)return null;const o=Ra(e,t);if(o.length===0)return null;const r=o.filter(l=>l.kind==="device-device"),a=o.filter(l=>l.kind!=="device-device"&&l.clearAtScale==null);if(r.length>0||a.length>0||!n){const l=[];r.length>0&&l.push(`${r.map(Ce).join(", ")}: two devices overlap without reading as composed. There is no deterministic repair — give the pair a real difference in scale, camera angle or roll (that is what makes an overlap read as deliberate), or leave it if it already is.`);for(const u of a)l.push(u.anchored?`${Ce(u)}: the caption is anchored by hand, so it is reported and never rewritten — move it, or drop its \`anchor\` to let the band place it.`:`${Ce(u)}: no caption size above the legibility floor clears it — shorten the headline, or pick a layout with a bigger text region (\`style.layout: "bleed"\`).`);return l.length===0&&l.push("The rendered look was not available here, so no corrected look could be built."),{findings:o,note:`No corrected look is offered. ${l.join(" ")}`}}const i=new Set(o.filter(l=>l.kind!=="device-device").map(l=>l.frames[0])),s=e.suggestions.filter(l=>i.has(t.frameOfPanel(l.panelId))),c=s.flatMap(l=>{const u=t.frameOfPanel(l.panelId)+1;return l.layers.map(f=>`frame ${u} layer ${f.layerIndex+1}: sizePt ${f.fromSizePt} → ${f.toSizePt}`)}).join("; ");return{findings:o,correctedLook:Fa(n,s),note:`\`layout.correctedLook\` is this same look with every caption shrunk to the largest size that was verified to clear the overlap (${c}). Nothing here is applied for you — re-render with it, or show the user the finding and let them decide. On render_strip pass it back as \`look\` together with the SAME \`style.captions\` you just sent: the words come from \`style.captions\` and every style field you leave out of them now comes from this look. The one thing that still beats it is a field you set EXPLICITLY on a caption entry, so if your \`style.captions\` pin \`sizePt\` at the original numbers, drop them or set them to the sizes above.`}}function _a(e){return String(Math.max(-100,Math.min(100,e*35)))}const Ba=["roll","deviceSize","hOffset","vOffset","finish","clearcoat"];function Lt(e){if(!e||typeof e!="object")return{};const t={...e};for(const n of Ba)typeof t[n]=="number"&&(t[n]=String(t[n]));return t}function za(e){const{subtitle:t,sizePt:n,maxWidth:o,...r}=e;return{...r,...n!==void 0?{sizePt:Number(n)}:{},...o!==void 0?{maxWidth:Number(o)}:{}}}function Rt(e){const t={};for(const[n,o]of Object.entries(e))o!==void 0&&(t[n]=o);return t}function ke(e,t,n){const o={};return e&&t.forEach((r,a)=>{const i=n[a];i!==void 0&&e[r]!==void 0&&(o[i]=e[r])}),o}function ja(e){const t=Array.isArray(e.sourcePanelIds)&&e.sourcePanelIds.length===e.slotSizes.length?e.sourcePanelIds:null,n=t?e.slotSizes.map(S=>Number.isInteger(S)&&S>0?S:0):e.slotSizes.filter(S=>Number.isInteger(S)&&S>0),o=n.map((S,k)=>`panel-${k+1}`);let r={};const a=e.look&&typeof e.look=="object"?e.look:null,i=e.style??null,s=a&&Array.isArray(a.shots)?a.shots:[],c=s.length>0,l=i?Lt(i.shotLook):null,u=[];let f=0;n.forEach((S,k)=>{for(let A=0;A<S;A++){const C=c?Lt(s[f]?.look??s[0]?.look??{}):l??{},T=C.hOffset!==void 0&&C.hOffset!==null?String(C.hOffset):_a(A);u.push({panelId:o[k],look:{...M,...C,hOffset:T}}),f++}});let d={},h={},g={},p="gradient",m=lo,y=co,b="vertical",v,w,x=!0,I=!1;if(a){p=a.bgMode==="perPanel"?"perPanel":"gradient";const S=ce({gradientStops:Array.isArray(a.gradientStops)?a.gradientStops:void 0,gradientAngle:typeof a.gradientAngle=="number"?a.gradientAngle:void 0,gradientFrom:typeof a.gradientFrom=="string"?a.gradientFrom:m,gradientTo:typeof a.gradientTo=="string"?a.gradientTo:y,gradientDir:a.gradientDir==="horizontal"?"horizontal":b});v=S.stops,w=S.angle,{gradientFrom:m,gradientTo:y,gradientDir:b}=le(S),a.shadow===!1&&(x=!1),a.floorReflection===!0&&(I=!0);const k=t?[...t]:[];if(!t)for(const A of s){const C=typeof A?.panelId=="string"?A.panelId:null;C&&!k.includes(C)&&k.push(C)}d=ke(a.panelColors,k,o),h=ke(Ye(a.captionStyles),k,o),g=ke(Zt(a.panelBackgrounds),k,o)}else if(i){const S=i.background??{};p=S.mode==="perPanel"?"perPanel":"gradient";const k=ce({gradientStops:S.stops,gradientAngle:S.angle,gradientFrom:m,gradientTo:y,gradientDir:b});v=k.stops,w=k.angle,{gradientFrom:m,gradientTo:y,gradientDir:b}=le(k),S.shadow===!1&&(x=!1),S.floorReflection===!0&&(I=!0),Array.isArray(S.panelColors)&&S.panelColors.forEach((A,C)=>{typeof A=="string"&&A&&o[C]!==void 0&&(d[o[C]]=A)})}if(i&&Array.isArray(i.captions)){const S=h,k=(O,E)=>({...S[O]?.[E]??{}}),A={},C={};i.captions.forEach((O,E)=>{const _=o[E];if(!(_===void 0||O===null||O===void 0)){if(Array.isArray(O)){const H=O.filter(B=>!!B&&typeof B=="object"&&typeof B.text=="string"&&B.text.trim()!=="").map((B,te)=>Ee(k(_,te),Rt(za(B))));H.length>0&&(C[_]=H)}else if(typeof O=="object"){const{text:H,subtitle:B,sizePt:te,maxWidth:nt,...En}=O;A[_]=Ee(k(_,0),Rt({...En,...te!==void 0?{sizePt:Number(te)}:{},...nt!==void 0?{maxWidth:Number(nt)}:{}})),typeof H=="string"&&H.trim()&&(C[_]={headline:H,...typeof B=="string"&&B?{subtitle:B}:{}})}}});const T=me({[N]:C},tn(A));h=nn(T),r=ge(T)}return{look:{panelPresetId:e.panelPresetId??(typeof a?.panelPresetId=="string"?a.panelPresetId:void 0)??"r69",bgMode:p,gradientStops:v,gradientAngle:w,gradientFrom:m,gradientTo:y,gradientDir:b,panelColors:d,shadow:x,floorReflection:I,panelBackgrounds:g,captionStyles:h,shots:u,...t?{panelIds:o}:{}},panelIds:o,captionText:r}}function Da(e){const t=e?.trim();return t?/\.(png|jpe?g|webp)$/i.test(t)?t:`${t}.png`:null}function Wa(e,t){const n=new Map;return e.map((o,r)=>{const a=Da(t?.[r]);if(!a)return`screen-${r+1}.png`;const i=n.get(a)??0;if(n.set(a,i+1),i===0)return a;const s=a.lastIndexOf(".");return`${a.slice(0,s)}-${i+1}${a.slice(s)}`})}function Ha(e){const{look:t,panelIds:n,captionText:o,locale:r,shotNames:a,outputs:i,locales:s,baseLocale:c}=e,l=n.map(d=>({id:d})),u=Wa(t.shots,a),f=t.shots.map((d,h)=>({id:`shot-${h+1}`,panelId:d.panelId,frameNodeId:u[h],frameName:u[h],bytes:null,look:d.look,thumb:null,thumbStale:!0}));return dn({shots:f,panels:l,selectedShotId:f[0]?.id??null,panelPresetId:t.panelPresetId,bgMode:t.bgMode,gradientStops:t.gradientStops,gradientAngle:t.gradientAngle,gradientFrom:t.gradientFrom,gradientTo:t.gradientTo,gradientDir:t.gradientDir,panelColors:t.panelColors,shadow:t.shadow,floorReflection:t.floorReflection,panelBackgrounds:t.panelBackgrounds,captionStyles:t.captionStyles,outputs:i,...s?{locales:s}:{},...c?{baseLocale:c}:{},captionText:o&&Object.keys(o).length>0?{[r||N]:o}:{}})}const Ua=1900,Ga=2800,Ft=new Map;async function $a(e){e("booting headless stage + loading model (once)…");const t=hn(Ua,Ga),n=await Cr(t);return{stage:t,device:new xn(n,t.scene,t.renderer),screen:new In(n)}}function Pn(e,t,n={}){let o=Ft.get(e);o||(o={refs:$a(n.onProgress??(()=>{})),tail:Promise.resolve()},Ft.set(e,o));const{refs:r}=o,a=o.tail.then(async()=>t(await r));return o.tail=a.catch(()=>{}),a}function Cn(e,t){return t===e.baseLocale||!e.locales||e.locales.includes(t)}function Nt(e,t){const n={...e,...t.set};for(const o of t.unset??[])delete n[o];return n}function Oe(e,t){if(t.edits.length===0)return e;const n=Object.keys(e.captionText).filter(f=>!Cn(e,f)),o=n.length===0?e.captionText:Object.fromEntries(Object.entries(e.captionText).filter(([f])=>!n.includes(f))),r=t.edits.filter(f=>f.locale===void 0||f.locale===e.baseLocale),a=new Map;for(const f of r)a.set(f.panelId,[...a.get(f.panelId)??[],f]);let i=Wo(o,Array.from(a.keys()),e.baseLocale,(f,d)=>{const h=a.get(d);if(!(!f?.length||!h))return f.map((g,p)=>h.filter(m=>m.layerIndex===p).reduce(Nt,g))});for(const f of t.edits){if(f.locale===void 0||f.locale===e.baseLocale||n.includes(f.locale))continue;const d=i[f.locale]?.[f.panelId];d?.[f.layerIndex]&&(i={...i,[f.locale]:{...i[f.locale],[f.panelId]:d.map((h,g)=>g===f.layerIndex?Nt(h,f):h)}})}if(i===o)return e;n.length>0&&(i={...i,...Object.fromEntries(n.map(f=>[f,e.captionText[f]]))});const s={...e,captionText:i};if(!e.frameTemplates||!e.shots)return s;const c={...e.frameTemplates},l=new Set(t.edits.map(f=>f.panelId));let u=!1;for(const f of Array.from(l)){const d=e.frameTemplates[f];if(!d)continue;const h=nr({...e,shots:e.shots,captionSlotIds:e.captionSlotIds??{},frameTemplates:e.frameTemplates},f);!h||h.modified||(c[f]=tr({shots:e.shots,captionText:i,captionSlotIds:e.captionSlotIds??{},baseLocale:e.baseLocale},f,d.templateId),u=!0)}return u?{...s,frameTemplates:c}:s}const Va=.4,_t=.02,qa=.02,Bt=[.04,.02],ae=.5,J=e=>Math.round(e*100)/100;function Xa(e){const t=new Map,n=o=>{const r=`${e.font}\0${e.textBaseline}\0${o}`;let a=t.get(r);return a||(a=e.measureText(o),t.set(r,a)),a};return new Proxy(e,{get(o,r){if(r==="measureText")return n;const a=Reflect.get(o,r,o);return typeof a=="function"?a.bind(o):a},set(o,r,a){return Reflect.set(o,r,a,o)}})}const He=e=>!e.inkUncertain&&e.depthFrac>=We;function kn(e){if(e.boxAlign)return e.boxAlign;if(e.bandCenter===void 0)return"center";const t=Qt(e),n=Q(e),o=t+n/2;return Math.abs(o-.5)<.01?"center":o<.5?"left":"right"}function Ka(e,t,n){return e.map((o,r)=>{if(!t.has(r))return o;let a={...o};const i=Q(o);return n.width<i-1e-9&&(delete a.widthMode,a.maxWidth=J(n.width)),n.align&&n.align!==kn(o)&&(a=Ee(a,{boxAlign:n.align})),n.flip&&(a.band==="bottom"?delete a.band:a.band="bottom"),n.inset!==null&&(a.bandInset=n.inset),a})}function Ya(e,t,n){return e.hits.some(o=>t.has(o.layerIndex)&&He(o))?!1:e.boxes.every(({layerIndex:o,box:r})=>!t.has(o)||r.y>=-ae&&r.y+r.height<=n.height+ae&&r.x>=n.left-ae&&r.x+r.width<=n.right+ae)}function zt(e,t,n){const o=n?[e]:[];for(let r=J(e-_t);r>=t-1e-9;r=J(r-_t))o.push(r);return o}function Ja(e,t,n){const o=Array.from(t),r=o.map(h=>Q(e[h])),a=Math.max(...r),i=Math.min(Va,Math.min(...r)),s=zt(a,i,!1).map(h=>({width:h,align:null,flip:!1,inset:null}));if(n)return s;const c=kn(e[o[0]]),l=[c,...["left","right","center"].filter(h=>h!==c)],u=e[o[0]].bandInset??.06,f=Bt.filter(h=>h<u-1e-9),d=(h,g,p)=>{for(const m of zt(a,i,!0))s.push({width:m,align:h,flip:g,inset:p})};return l.slice(1).forEach(h=>d(h,!1,null)),f.forEach(h=>l.forEach(g=>d(g,!1,h))),[null,...Bt].forEach(h=>l.forEach(g=>d(g,!0,h))),s}function Za(e,t,n,o,r){const a={},i=[];return t.maxWidth!==e.maxWidth&&(a.maxWidth=t.maxWidth),t.boxAlign!==e.boxAlign&&t.boxAlign&&(a.boxAlign=t.boxAlign),t.bandInset!==e.bandInset&&t.bandInset!==void 0&&(a.bandInset=t.bandInset),t.band!==e.band&&(t.band?a.band=t.band:i.push("band")),e.widthMode!==void 0&&t.widthMode===void 0&&i.push("widthMode"),e.bandCenter!==void 0&&t.bandCenter===void 0&&i.push("bandCenter"),Object.keys(a).length===0&&i.length===0?null:{...r?{locale:r}:{},panelId:n,layerIndex:o,set:a,...i.length>0?{unset:i}:{}}}function Qa(e,t){const n=p=>({state:e,resolution:{edits:[]},measured:p,remaining:[],remainingSentence:null});if(!t.ctx||t.panelIds.length===0)return n(!1);const o=Xa(t.ctx),r=p=>e.panels?e.panels.findIndex(m=>m.id===p):t.panelIds.indexOf(p),a=p=>{const m=t.panelIds.indexOf(p);return{left:m*t.panelWidth,right:(m+1)*t.panelWidth,height:t.panelHeight}},i=p=>Sa({phones:t.phones,panelIds:t.panelIds,captionLayers:p,panelWidth:t.panelWidth,panelHeight:t.panelHeight,ctx:o,...t.clip?{clip:t.clip}:{},...t.silhouettes?{silhouettes:t.silhouettes}:{}}),s=(p,m)=>new Set(p.flatMap((y,b)=>D(y.anchor)&&y.text.trim()&&!(m&&y.widthMode==="fill")?[b]:[])),c=(p,m,y,b)=>{const v=i(m),w=[];for(const x of t.panelIds){const I=m[x];if(!I?.length||!b(x))continue;const P=s(I,y);if(P.size===0)continue;const S=a(x);if(v.probe(x,I).hits.some(A=>P.has(A.layerIndex)&&He(A)))for(const A of Ja(I,P,y)){const C=Ka(I,P,A);if(Ya(v.probe(x,C),P,S)){v.commit(x,C),C.forEach((T,O)=>{const E=Za(I[O],T,x,O,y?p:void 0);E&&w.push(E)});break}}}return w},l=e.baseLocale,u=(p,m)=>t.family?jo(p.captionText,p.outputCaptions,t.family,m,l):ge(p.captionText,m,l),f=p=>Object.keys(p.captionText).filter(m=>Cn(p,m)),d=p=>{const m=new Map,y=f(p);for(const b of y.length>0?y:[l]){const v=u(p,b),w=i(v);for(const x of t.panelIds){const I=v[x];if(!I?.length)continue;const P=s(I,!1),S=r(x);if(!(S<0))for(const k of w.probe(x,I).hits){if(!P.has(k.layerIndex)||!He(k))continue;const A=k.against==="device"?"caption-device":"caption-caption",C=Math.max(1,Math.round(k.depthFrac*100)),T=`${A}:${S}`,O=m.get(T);(!O||O.depthPct<C)&&m.set(T,{kind:A,frames:[S],depthPct:C,anchored:!1})}}}return Array.from(m.values()).sort((b,v)=>b.frames[0]-v.frames[0]||b.kind.localeCompare(v.kind))},h=p=>{const m=c(l,u(p,l),!1,()=>!0);let y=Oe(p,{edits:m});const b=[];for(const v of f(y)){if(v===l)continue;const w=y.captionText[v]??{};b.push(...c(v,u(y,v),!0,x=>w[x]!==void 0))}return b.length>0&&(y=Oe(y,{edits:b})),{state:y,edits:[...m,...b],remaining:d(y)}};let g=h(e);if(g.remaining.length>0){const p=e.captionText[l]??{},m=Object.keys(p).flatMap(y=>p[y].flatMap((b,v)=>D(b.anchor)&&b.text.trim()&&b.sizePt>X?[{panelId:y,layerIndex:v,sizePt:b.sizePt}]:[]));for(let y=1;m.length>0;y++){const b=J(1-y*qa),v=m.map(({panelId:x,layerIndex:I,sizePt:P})=>({panelId:x,layerIndex:I,set:{sizePt:Math.max(X,J(P*b))}})),w=h(Oe(e,{edits:v}));if(w.remaining.length===0){g={...w,edits:[...v,...w.edits]};break}if(m.every(({sizePt:x})=>x*b<=X))break}}return{state:g.state,resolution:{edits:g.edits},measured:!0,remaining:g.remaining,remainingSentence:Ma(g.remaining)}}function L(e){console.log("[render]",e)}function On(e){const t=atob(e),n=new Uint8Array(t.length);for(let o=0;o<t.length;o++)n[o]=t.charCodeAt(o);return n}function tt(e){let t="";for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function ei(e){return new Promise((t,n)=>{e.toBlob(async o=>{if(!o)return n(new Error("toBlob null"));t(tt(new Uint8Array(await o.arrayBuffer())))},"image/png")})}function Tn(e,t){const n=Sn(t),o=new Map(t.shots.map((a,i)=>[et(i),n.indexOf(a.panelId)])),r=Na(e.layout,{frameOfPanel:a=>n.indexOf(a),frameOfShot:a=>o.get(a)??-1},t);if(r)return{layout:{findings:r.findings,...r.correctedLook?{correctedLook:r.correctedLook}:{}},layoutNote:r.note}}async function Mn(e){const t=await Promise.all(e.map(a=>createImageBitmap(new Blob([new Uint8Array(a.bytes)],{type:"image/png"})))),n=document.createElement("canvas");n.width=t.reduce((a,i)=>a+i.width,0),n.height=t[0]?.height??1;const o=n.getContext("2d");let r=0;for(const a of t)o.drawImage(a,r,0),r+=a.width,a.close();return{base64:await ei(n),width:n.width,height:n.height}}window.renderStrip=async function(t){try{if(!t||!Array.isArray(t.screenshots)||t.screenshots.length===0)throw new Error("renderStrip: input.screenshots must be a non-empty nested array of slots");const n=t.screenshots.map(v=>Array.isArray(v)?v:[v]),{look:o,panelIds:r,captionText:a}=ja({slotSizes:n.map(v=>v.length),...Array.isArray(t.panelIds)?{sourcePanelIds:t.panelIds}:{},panelPresetId:t.panelPresetId,look:t.look??void 0,style:t.style??void 0}),i=n.flat().map(On),s=Array.isArray(t.captionLayers)&&r[0]?{[r[0]]:t.captionLayers}:a,c=t.preview?.25:1;L(`buildStrip (${n.length} panel${n.length===1?"":"s"}${t.locale?`, ${t.locale}`:""})…`);let l=0;const u=await Pn("visible",v=>(l=performance.now(),An(o,{screens:i,captionText:s},t.locale,{refs:v,renderScale:c,onProgress:w=>L(" "+w),...t.clip?{clip:t.clip}:{},...Number.isInteger(t.panelViewport)?{panelViewport:t.panelViewport}:{},...t.backgroundViewport?{backgroundViewport:t.backgroundViewport}:{}})),{onProgress:L});L("encoding panels + stitching the strip preview…");const f=u.panels.map(v=>tt(v.bytes)),d=await Mn(u.panels),h=Z(o.panelPresetId),g=Math.round(performance.now()-l),p=Tn(u,o),m=u.layout.captionsMeasurable,y=Array.isArray(t.screenshotNames)?t.screenshotNames.flat():void 0,b=t.buildRecord?Ha({look:o,panelIds:r,captionText:a,locale:t.locale,shotNames:y,outputs:t.outputs}):void 0;return L(`done: ${u.panels.length} panels, strip ${d.width}x${d.height}, ${g}ms`),{ok:!0,ms:g,count:u.panels.length,panelPresetId:h.id,panelWidth:h.width,panelHeight:h.height,stripWidth:d.width,stripHeight:d.height,panels:f,stripBase64:d.base64,preview:c<1,...b?{projectRecord:b}:{},...p??{},layoutMeasured:m,...t.layerBoxes?{layerBoxes:u.phones.map(({shotId:v,...w})=>({shot:o.shots.findIndex((x,I)=>et(I)===v),...w}))}:{}}}catch(n){const o=n&&n.stack?n.stack:String(n);return L("ERROR: "+o),{ok:!1,error:String(n&&n.message?n.message:n)}}};window.renderProject=async function(t){try{if(!t||t.projectFile==null||typeof t.projectFile!="object")throw new Error("renderProject: input.projectFile (the saved ProjectFile) is required");const n=rr(JSON.stringify(t.projectFile));if(!n)throw new Error("renderProject: the saved project could not be restored (wrong schema or malformed record)");const o=t.locale||n.baseLocale||n.locales?.[0]||"en-US",r=ee(n.shots,n.panels),a=Le(t.variant||{},n.baseLocale),i=new Map((t.screenManifest||[]).map(I=>[`${I.shotId} ${dt(Le(I.variant||{},n.baseLocale))}`,I])),s=(I,P)=>i.get(`${I} ${dt(P)}`),c=r.map(I=>on(s,I.id,a,To,n.baseLocale)),l=r.map((I,P)=>({frameName:I.frameName,matched:c[P].value!==void 0,requestedVariant:a,resolvedAt:c[P].resolvedAt,inherited:c[P].inherited,...c[P].value?.source?{source:c[P].value.source}:{}})),u=c.map(({value:I})=>I?.bytes?On(I.bytes):null),f=ge(n.captionText,o,n.baseLocale),d=ir({...n,selectedShotId:null,panelPresetId:t.panelPresetId??n.panelPresetId,captionText:{[o]:f}}),h=t.preview?.25:1;L(`renderProject (${r.length} shot${r.length===1?"":"s"}, ${o})…`);let g=0;const p=await Pn("visible",I=>(g=performance.now(),An(d,{screens:u,captionText:f},o,{refs:I,renderScale:h,onProgress:P=>L(" "+P)})),{onProgress:L});L("encoding panels + stitching the strip preview…");const m=p.panels.map(I=>tt(I.bytes)),y=await Mn(p.panels),b=Z(d.panelPresetId),v=Math.round(performance.now()-g),w=Tn(p,d),x=p.layout.captionsMeasurable;return L(`done: ${p.panels.length} panels, strip ${y.width}x${y.height}, ${v}ms`),{ok:!0,ms:v,count:p.panels.length,panelPresetId:b.id,panelWidth:b.width,panelHeight:b.height,stripWidth:y.width,stripHeight:y.height,panels:m,stripBase64:y.base64,preview:h<1,shots:l,locale:o,...w??{},layoutMeasured:x,...t.layoutGeometry?{layoutGeometry:p.geometry}:{},...t.settleCaptions?ti(n,p.geometry,a.family):{}}}catch(n){const o=n&&n.stack?n.stack:String(n);return L("ERROR: "+o),{ok:!1,error:String(n&&n.message?n.message:n)}}};let jt=null;function ti(e,t,n){if(!t)return{captionResolution:{edits:[]},captionsMeasured:!1,captionRemaining:null};jt??=document.createElement("canvas").getContext("2d");const o=Qa(e,{...t,...n?{family:n}:{},ctx:jt});return{captionResolution:o.resolution,captionsMeasured:o.measured,captionRemaining:o.remainingSentence}}window.__RENDER_READY=!0;L("harness ready ✓");