shotops-mcp 0.10.0 → 0.12.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.
@@ -0,0 +1 @@
1
+ import{S as to,G as no,A as ro,D as tt,M as oo,R as ao,a as io,C as so,b as lo,c as co}from"./three-addons-zF8BveTt.js";import{aa as uo,P as jt,b as fo,V as ce,a4 as ho,l as qn,C as V,ab as po,J as nn,$ as Re,M as mo,a2 as go,B as yo,a3 as vo,a7 as bo,ac as rn,ad as wo,ae as xo}from"./three-webgl-BAyyruEx.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))r(o);new MutationObserver(o=>{for(const a of o)if(a.type==="childList")for(const i of a.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&r(i)}).observe(document,{childList:!0,subtree:!0});function n(o){const a={};return o.integrity&&(a.integrity=o.integrity),o.referrerPolicy&&(a.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?a.credentials="include":o.crossOrigin==="anonymous"?a.credentials="omit":a.credentials="same-origin",a}function r(o){if(o.ep)return;o.ep=!0;const a=n(o);fetch(o.href,a)}})();const pe={lineHeight:1.2,bandInset:.06,bandCenter:.5,padX:.07},De={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}},je=[{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"}],on=je.map(e=>e.id);[on[0],...on.slice(1)];const Ie=600;function Ut(e){return je.find(t=>t.id===e)??je[0]}const Xn=.862,Kn=[{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}}],Wt=Kn,an=Wt.map(e=>e.id);[an[0],...an.slice(1)];const Yn=["deviceSize","hOffset","vOffset"],Io=Array.from(new Set(Kn.flatMap(e=>Object.keys(e.caption)))),Jn=[{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"}}],sn=Jn.map(e=>e.id);[sn[0],...sn.slice(1)];const _={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},wt={angle:{valueKind:"angle",required:!0,defaultSource:"default-look",defaultValue:_.angle,persistence:"always"},cameraPos:{valueKind:"camera-position",required:!0,defaultSource:"default-look",defaultValue:_.cameraPos,persistence:"always"},roll:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:_.roll,persistence:"always"},deviceSize:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:_.deviceSize,persistence:"always"},hOffset:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:_.hOffset,persistence:"always"},vOffset:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:_.vOffset,persistence:"always"},material:{valueKind:"material",required:!0,defaultSource:"default-look",defaultValue:_.material,persistence:"always"},colorway:{valueKind:"colorway",required:!0,defaultSource:"default-look",defaultValue:_.colorway,persistence:"always"},customColor:{valueKind:"string",required:!0,defaultSource:"default-look",defaultValue:_.customColor,persistence:"always"},finish:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:_.finish,persistence:"always"},clearcoat:{valueKind:"numeric-string",required:!0,defaultSource:"default-look",defaultValue:_.clearcoat,persistence:"always"},clayTone:{valueKind:"clay-tone",required:!0,defaultSource:"default-look",defaultValue:_.clayTone,persistence:"always"},clayCustom:{valueKind:"string",required:!0,defaultSource:"default-look",defaultValue:_.clayCustom,persistence:"always"},flatScreen:{valueKind:"boolean",required:!0,defaultSource:"default-look",defaultValue:_.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:_.glare,persistence:"always"},lighting:{valueKind:"boolean",required:!0,defaultSource:"default-look",defaultValue:_.lighting,persistence:"always"},reflections:{valueKind:"boolean",required:!0,defaultSource:"default-look",defaultValue:_.reflections,persistence:"always"}},Ce={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}},Zn=.82;function Ht(e){return e/100*Zn}function So(e){return Math.round(e/Zn*100)/100}const Se={x:.5,y:.06},Gt={fontId:"inter",sizePt:32,color:"FFFFFF",align:"center",anchor:Se,maxWidth:.86},ln=[{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 Me(e){return ln.find(t=>t.id===e)??ln[0]}const Xe=932,xt="iphone-17-pro",Ao="pixel-10-pro",$t=[{id:"iphone-6-9",label:"iPhone 17 Pro",panelPresetId:"r69",ascDeviceSet:"APP_IPHONE_67",modelId:xt,screenFamily:"iphone"},{id:"iphone-6-5",label:"iPhone 17",panelPresetId:"r65",ascDeviceSet:"APP_IPHONE_65",modelId:xt,screenFamily:"iphone"},{id:"pixel-10-pro",label:"Pixel 10 Pro",panelPresetId:"pixel69",ascDeviceSet:"ANDROID_PHONE",modelId:Ao,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 ko(e){return $t.find(t=>t.panelPresetId===e)?.modelId??xt}const Qn="iphone-6-9";function Vt(e){return $t.find(t=>t.id===e)}function Po(){return $t.filter(e=>!e.comingSoon)}function er(e,t){if(Array.isArray(e)){const n=new Set,r=[];for(const o of e){const a=Vt(o);a&&!a.comingSoon&&!n.has(o)&&(n.add(o),r.push(o))}if(r.length>0)return r}if(t){const n=Po().find(r=>r.panelPresetId===t);if(n)return[n.id]}return[Qn]}function Oo(e,t){return e.find(r=>Vt(r)?.panelPresetId===t)??e[0]}function Co(e){const t=e??{},n=Array.isArray(t.outputs)?t.outputs.filter(a=>typeof a=="string"):void 0,r=er(n,typeof t.panelPresetId=="string"?t.panelPresetId:void 0),o=Me(typeof t.panelPresetId=="string"?t.panelPresetId:"").id;return{outputs:r,panelPresetId:o,activeDeviceId:Oo(r,o)}}const qt=Vt(Qn)?.screenFamily??"iphone";function tr(e){const t={...e},n=t,r=Object.keys(wt);for(const o of r){const a=wt[o];a.persistence==="omit-default"&&(n[o]===void 0||n[o]===a.defaultValue)&&delete n[o]}return t}function Mo(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 r=typeof t=="number"?t:Number.parseFloat(String(t??""));Number.isFinite(r)&&(n.deviceSize=String(So(r)))}return n}function nr(e){return tr({..._,...Mo(e)})}function rr(e){return tr(nr(e))}function U(e,t){const{min:n,max:r}=Ce[e],o=typeof t=="number"?t:Number.parseFloat(t??""),a=Number.isFinite(o)?o:Number.parseFloat(String(wt[e].defaultValue));return Math.max(n,Math.min(r,a))}const To=90,or=180,Eo="#1b1b2e",Lo="#0a0a14";function Fo(e){return e==="horizontal"?To:or}function Ro(e){const t=(e%180+180)%180;return t>=45&&t<135?"horizontal":"vertical"}function ar(e,t,n){return{stops:[{color:e,at:0},{color:t,at:1}],angle:Fo(n)}}const ir=e=>e*Math.PI/180;function zo(e){const t=ir(e);return{dx:Math.sin(t),dy:-Math.cos(t)}}function No(e,t,n){const r=ir(n);return Math.abs(e*Math.sin(r))+Math.abs(t*Math.cos(r))}function Bo(e,t,n){const{dx:r,dy:o}=zo(n),a=No(e,t,n)/2,i=e/2,s=t/2;return{x0:i-a*r,y0:s-a*o,x1:i+a*r,y1:s+a*o}}function Ue(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:Ro(e.angle)}}function Ke(e,t){if(!Array.isArray(e)||e.length===0)return null;const n=[];for(const o of e){if(!o||typeof o!="object")return null;const a=o;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 r=typeof t=="number"&&Number.isFinite(t)?_o(t):or;return{stops:n,angle:r}}function We(e){return Ke(e.gradientStops,e.gradientAngle)??ar(e.gradientFrom,e.gradientTo,e.gradientDir)}function _o(e){return(e%360+360)%360}function Do(e){return Ke(e.stops,e.angle)??ar(e.from,e.to,e.dir)}function sr(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,r]of Object.entries(e)){if(!r||typeof r!="object")continue;const o=r;if(o.kind==="solid"&&typeof o.color=="string")t[n]={kind:"solid",color:o.color};else if(o.kind==="gradient"&&typeof o.from=="string"&&typeof o.to=="string"&&(o.dir==="horizontal"||o.dir==="vertical")){const a=Ke(o.stops,o.angle);t[n]=a?{kind:"gradient",stops:a.stops,angle:a.angle,from:o.from,to:o.to,dir:o.dir}:{kind:"gradient",from:o.from,to:o.to,dir:o.dir}}}return t}const cn=e=>Math.round(e*1e6)/1e6;function Te(e){return e.widthMode==="fill"?1-2*(e.padX??pe.padX):e.maxWidth}function lr(e){const t=Te(e);if(e.boxAlign===void 0&&e.bandCenter!==void 0)return e.bandCenter-t/2;const n=e.padX??pe.padX;return e.boxAlign==="left"?n:e.boxAlign==="right"?1-n-t:pe.bandCenter-t/2}function jo(e,t){return Math.abs(e-pe.bandCenter)<1e-9?null:e<.5?{boxAlign:"left",padX:cn(e-t/2)}:{boxAlign:"right",padX:cn(1-e-t/2)}}function It(e,t){const n={...e,...t},r=t;return r.bandCenter!==void 0&&r.boxAlign===void 0&&delete n.boxAlign,r.boxAlign!==void 0&&r.bandCenter===void 0&&delete n.bandCenter,n}function te(e){return!e||e.x===Se.x&&e.y===Se.y}const Uo=["sizePt","maxWidth","lineHeight","reserveLines"];function Wo(e,t){return t?Uo.filter(n=>e[n]!==t[n]):[]}function Ho(e){const{text:t,anchor:n,...r}=e;return te(n)?{...r}:{...r,anchor:n}}const Go=.55,Y="en-US";function $o(e,t){return`${e}:${t}`}function Vo(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 cr(e,t,n,r){if(!e||typeof e!="object"||Array.isArray(e))return{};const o={};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(l=>typeof l=="string"))).filter(l=>{const c=Vo(l);return!!c&&!!r[n]?.[c.panelId]?.[c.index]&&!!r[a]?.[c.panelId]?.[c.index]});s.length>0&&(o[a]=s)}return o}function dr(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,r]of Object.entries(e))!r||typeof r!="object"||Array.isArray(r)||(t[n]=me(r));return t}function qo(e){if(!e||typeof e!="object")return;const t=e,n=typeof t.x=="number"?t.x:Se.x,r=typeof t.y=="number"?t.y:Se.y;return te({x:n,y:r})?void 0:{x:n,y:r}}function me(e){const t=e&&typeof e=="object"?e:{},n=qo(t.anchor),r={...Gt,...t};n?r.anchor=n:delete r.anchor,typeof r.reserveLines!="number"||!Number.isFinite(r.reserveLines)||r.reserveLines<De.reserveLines.min?delete r.reserveLines:r.reserveLines=Math.floor(r.reserveLines),r.band!=="bottom"&&delete r.band;for(const o of["bandInset","lineHeight","bandCenter","padX"]){const{min:a,max:i}=De[o],s=r[o];(typeof s!="number"||!Number.isFinite(s)||s<a||s>i)&&delete r[o]}return r.boxAlign!=="left"&&r.boxAlign!=="center"&&r.boxAlign!=="right"&&delete r.boxAlign,r.widthMode!=="fill"&&delete r.widthMode,Xo(r),r}function Xo(e){const t=e.bandCenter;if(t===void 0)return;const n=jo(t,e.maxWidth);if(e.boxAlign!==void 0||n===null){delete e.bandCenter;return}e.widthMode!=="fill"&&n.padX>=De.padX.min&&n.padX<=De.padX.max&&(e.boxAlign=n.boxAlign,e.padX=n.padX,delete e.bandCenter)}function Ko(e){const t=e&&typeof e=="object"?e:{};return{...me(t),text:typeof t.text=="string"?t.text:""}}function Xt(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,r]of Object.entries(e))Array.isArray(r)?r.length>0&&(t[n]=r.map(me)):r&&typeof r=="object"&&(t[n]=[me(r)]);return t}function Yo(e,t){const n=[{...me(t),text:e.headline}];return typeof e.subtitle=="string"&&e.subtitle.trim()&&n.push({...me({...t,sizePt:t.sizePt*Go}),text:e.subtitle}),n}function Ye(e,t,n=Y){if(!e||typeof e!="object"||Array.isArray(e))return{};const r=dr(t),o=c=>r[c]??Gt,a=c=>{if(!c||typeof c!="object"||Array.isArray(c))return{};const u={};for(const[f,d]of Object.entries(c))Array.isArray(d)?d.length>0&&(u[f]=d.map(Ko)):d&&typeof d=="object"&&typeof d.headline=="string"&&(u[f]=Yo(d,o(f)));return u},i=Object.entries(e);if(i.some(([,c])=>!!c&&typeof c=="object"&&typeof c.headline=="string"))return{[n]:a(e)};const l={};for(const[c,u]of i)l[c]=a(u);return l}function Ae(e,t,n=Y){return e[t??n]??e[n]??{}}function ur(e,t=Y){const n={},r=Object.keys(e),o=r.includes(t)?[t,...r.filter(a=>a!==t)]:r;for(const a of o){const i=e[a];if(i)for(const[s,l]of Object.entries(i))n[s]===void 0&&Array.isArray(l)&&l.length>0&&(n[s]=l.map(Ho))}return n}function St(e,t=Y,n=qt){const r={};return e.family!==void 0&&e.family!==n&&(r.family=e.family),e.locale!==void 0&&e.locale!==t&&(r.locale=e.locale),r}function dn(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 At(e){const t=[];return e.family!==void 0&&t.push("family"),e.locale!==void 0&&t.push("locale"),t}const Jo={order:["family","locale"],reach:"strict"},Zo={order:["locale","family"],reach:"lattice"};function Qo(e){const t=[];for(let n=0;n<1<<e.length;n++){const r=[];for(let o=0;o<e.length;o++)n&1<<o&&r.push(e[o]);t.push(r)}return t.sort((n,r)=>{if(n.length!==r.length)return r.length-n.length;for(let o=0;o<n.length;o++){const a=e.indexOf(n[o])-e.indexOf(r[o]);if(a!==0)return a}return 0})}function ea(e,t){const n=At(e),r=t.order.filter(a=>n.includes(a));return(t.reach==="strict"?Array.from({length:r.length+1},(a,i)=>r.slice(0,r.length-i)):Qo(r)).map(a=>{const i={};return a.includes("family")&&(i.family=e.family),a.includes("locale")&&(i.locale=e.locale),i})}function fr(e,t,n,r,o=Y){const a=St(n,o);for(const i of ea(a,r)){const s=e(t,i);if(s!==void 0){const l=At(i);return{value:s,resolvedAt:i,inherited:At(a).filter(c=>!l.includes(c))}}}return{value:void 0,resolvedAt:null,inherited:[]}}const hr=e=>{let t="";for(let n=0;n<e.length;n++)t+=e[n].toString(16).padStart(2,"0");return t};async function ta(e){const t=globalThis.crypto?.subtle;return t?hr(new Uint8Array(await t.digest("SHA-256",e))):ra(e)}const na=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]),Q=(e,t)=>e>>>t|e<<32-t;function ra(e){const t=e.length,n=new Uint8Array(t+72>>6<<6);n.set(e),n[t]=128;const r=t*8,o=new DataView(n.buffer);o.setUint32(n.length-8,Math.floor(r/4294967296)),o.setUint32(n.length-4,r>>>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 v=0;v<16;v++)i[v]=o.getUint32(s+v*4);for(let v=16;v<64;v++){const m=i[v-15],b=i[v-2],y=Q(m,7)^Q(m,18)^m>>>3,w=Q(b,17)^Q(b,19)^b>>>10;i[v]=i[v-16]+y+i[v-7]+w>>>0}let[l,c,u,f,d,p,g,h]=[a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]];for(let v=0;v<64;v++){const m=Q(d,6)^Q(d,11)^Q(d,25),b=d&p^~d&g,y=h+m+b+na[v]+i[v]>>>0,w=Q(l,2)^Q(l,13)^Q(l,22),x=l&c^l&u^c&u,P=w+x>>>0;h=g,g=p,p=d,d=f+y>>>0,f=u,u=c,c=l,l=y+P>>>0}a[0]=a[0]+l>>>0,a[1]=a[1]+c>>>0,a[2]=a[2]+u>>>0,a[3]=a[3]+f>>>0,a[4]=a[4]+d>>>0,a[5]=a[5]+p>>>0,a[6]=a[6]+g>>>0,a[7]=a[7]+h>>>0}return hr(oa(a))}function oa(e){const t=new Uint8Array(e.length*4),n=new DataView(t.buffer);for(let r=0;r<e.length;r++)n.setUint32(r*4,e[r]);return t}function kt(e,t,n=Y){const r=o=>{const a=new Set,i=[];for(const s of o)typeof s=="string"&&s&&!a.has(s)&&(a.add(s),i.push(s));return i};if(Array.isArray(t)){const o=r(t);if(o.length>0)return o.includes(n)?o:[...o,n]}return r([n,...Object.keys(e)])}function Kt(e,t=Y){return typeof e=="string"&&e.length>0?e:t}const ve={"it-IT":"it"};function un(e,t){if(!(Object.keys(e).some(o=>o in ve)||(t?.some(o=>o in ve)??!1)))return{captionText:e,locales:t};const r={};for(const[o,a]of Object.entries(e))o in ve||(r[o]=a);for(const[o,a]of Object.entries(e)){const i=ve[o];i&&(r[i]={...a,...r[i]??{}})}return{captionText:r,locales:t?.map(o=>ve[o]??o)}}function aa(e){const t=e??{},n=Kt(t.baseLocale),r=Array.isArray(t.locales)?t.locales.filter(s=>typeof s=="string"&&s.length>0):void 0,{captionText:o,locales:a}=un(Ye(t.captionText,t.captionStyles,n),r),i=un({[n]:{}},[n]).locales?.[0]??n;return{captionText:o,locales:kt(o,a,i),baseLocale:i}}function ia(e,t,n,r,o){return(a,i)=>{const s=i.locale??o,l=i.family!==void 0?t?.[i.family]?.[s]?.[n]?.[r]:e[s]?.[n]?.[r]?.text;return typeof l=="string"&&l.length>0?l:void 0}}function sa(e,t,n,r,o=Y){const a=Ae(e,r,o);if(n===qt||!t?.[n])return a;const i={family:n,locale:r},s={};for(const[l,c]of Object.entries(a))s[l]=c.map((u,f)=>{const d=ia(e,t,l,f,o),{value:p}=fr(d,$o(l,f),i,Zo,o);return p===void 0||p===u.text?u:{...u,text:p}});return s}function pr(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const t={};for(const[n,r]of Object.entries(e)){if(n===qt||!r||typeof r!="object"||Array.isArray(r))continue;const o={};for(const[a,i]of Object.entries(r)){if(!i||typeof i!="object"||Array.isArray(i))continue;const s={};for(const[l,c]of Object.entries(i))Array.isArray(c)&&c.every(u=>typeof u=="string")&&(s[l]=c);Object.keys(s).length>0&&(o[a]=s)}Object.keys(o).length>0&&(t[n]=o)}return t}function la(e,t,n){if(!t||!n)return e;let r=!1;const o=e.map((a,i)=>{const s=t[i];if(!s)return a;const l=Wo(s,n[i]);if(l.length===0)return a;const c={...a},u=c;for(const f of l){const d=s[f];d===void 0?delete u[f]:u[f]=d}return r=!0,c});return r?o:e}function ca(e,t,n,r){if(t.length===0)return e;const o={...e},a=e[n];let i=!1;for(const s of t)for(const l of Object.keys(o)){const c=r(o[l][s],s,l);c!==void 0&&(o[l]={...o[l],[s]:l===n?c:la(c,e[l][s],a?.[s])},i=!0)}return i?o:e}function se(e){const t=e?.z;return{...typeof t=="number"&&Number.isSafeInteger(t)&&t!==0?{z:t}:{},...e?.hidden===!0?{hidden:!0}:{}}}function de(e,t){return t.flatMap(n=>e.filter(r=>r.panelId===n.id))}function da(e,t){const n=de(e,t).filter(o=>o.hidden!==!0),r=o=>se(o).z??0;return n.some(o=>r(o)!==0)?n.map((o,a)=>({shot:o,index:a,z:r(o)})).sort((o,a)=>o.z-a.z||o.index-a.index).map(o=>o.shot):n}let fn=0,hn=0;function ua(e,t){const n=(r,o)=>r.reduce((a,i)=>{const s=i.startsWith(o)?Number.parseInt(i.slice(o.length),10):NaN;return Number.isFinite(s)&&s>a?s:a},0);fn=Math.max(fn,n(e,"shot-")),hn=Math.max(hn,n(t,"panel-"))}const fa=.49,ha=e=>Math.round(e*100)/100,He=(e,t,n)=>Math.max(t,Math.min(n,e));function pn(e,t){return{x:e*t.width,y:0,width:t.width,height:t.height}}function pa(e,t,n){if(n<=0||t<=0||e.width<=0)return[];if(e.x+e.width<=0||e.x>=t*n)return[];const r=He(Math.floor(e.x/t),0,n-1),o=He(Math.ceil((e.x+e.width)/t)-1,0,n-1),a=[];for(let i=r;i<=o;i++)a.push(i);return a}function mr(e,t,n,r){const o=n*e.heightFrac,a=r&&r.height>0?r.width*(o/r.height):o*fa,s=e.panelIndex*t+t/2-a/2+e.hOffsetFrac*(t/2),l=(n-o)/2+e.vOffsetFrac*(n/2);return{x:s,y:l,width:a,height:o}}function ma(e,t,n){return mr({panelIndex:e.panelIndex,hOffsetFrac:U("hOffset",e.hOffset)/100,vOffsetFrac:U("vOffset",e.vOffset)/100,heightFrac:Ht(U("deviceSize",e.deviceSize))},t.width,t.height,n!==void 0&&n>0?{width:n,height:1}:void 0)}function ga(e,t,n){const{min:r,max:o}=Ce.hOffset;if(!Number.isFinite(t)||t>=r&&t<=o||n<=0)return{panelIndex:e,hOffset:t};const a=e+.5+t/200,i=He(Math.floor(a),0,n-1);return{panelIndex:i,hOffset:He(ha(t+(e-i)*200),r,o)}}function ya(e,t){const n=new Map(t.map((a,i)=>[a.id,i]));let r=!1;const o=e.map(a=>{const i=n.get(a.panelId);if(i===void 0)return a;const s=Number.parseFloat(a.look.hOffset),l=ga(i,s,t.length);return l.panelIndex===i&&l.hOffset===s?a:(r=!0,{...a,panelId:t[l.panelIndex].id,look:{...a.look,hOffset:String(l.hOffset)}})});return r?de(o,t):e}function va(e,t,n){return e.map(r=>{const o=mr({panelIndex:r.panelIndex,hOffsetFrac:r.hOffset,vOffsetFrac:r.vOffset,heightFrac:r.heightFrac},t,n,{width:r.width,height:r.height});return{shotId:r.shotId,bytes:r.bytes,x:Math.round(o.x),y:Math.round(o.y),width:Math.round(o.width),height:Math.round(o.height),panelIndex:r.panelIndex,...r.clipToFrame===!0?{clipToFrame:!0}:{},...r.layers?{layers:r.layers}:{}}})}function ba(e,t){const n=t.panelBackgrounds??{},r=We(t),o=r.stops[0]?.color??t.gradientFrom;if(!e.some(l=>n[l.id]))return t.bgMode==="gradient"?{kind:"gradient",gradient:r}:{kind:"perPanel",colors:e.map(l=>t.panelColors[l.id]??o)};const i=l=>t.bgMode==="gradient"?{kind:"gradient",gradient:r}:{kind:"solid",color:t.panelColors[l]??o};return{kind:"perPanelFills",fills:e.map(l=>{const c=n[l.id];return c?c.kind==="solid"?{kind:"solid",color:c.color}:{kind:"gradient",gradient:Do(c)}:i(l.id)})}}const wa=9/19.5;function xa(e){return e.deviceFrame!==!1}function Ia(e,t,n,r){const o=e>0&&t>0,a=o?t:Math.max(1,r),i=o?e:a*wa,s=Math.min(1,Math.max(1,r)/a),l=Math.max(1,Math.round(i*s)),c=Math.max(1,Math.round(a*s)),u=Math.min(l*U("screenCornerRadius",n.screenCornerRadius)/100,Math.min(l,c)/2),f=U("roll",n.roll)*Math.PI/180,d=Math.abs(Math.cos(f)),p=Math.abs(Math.sin(f)),g=Math.max(1,Math.ceil(l*d+c*p-1e-6)),h=Math.max(1,Math.ceil(l*p+c*d-1e-6));return{width:g,height:h,cardWidth:l,cardHeight:c,radius:u,rotation:f}}function gr(e,t,n=Y){const r=We(e);return{panelPresetId:e.panelPresetId,bgMode:e.bgMode,gradientStops:r.stops,gradientAngle:r.angle,...Ue(r),panelColors:e.panelColors,shadow:e.shadow,floorReflection:e.floorReflection??!1,panelBackgrounds:e.panelBackgrounds??{},captionStyles:{...Xt(e.captionStyles),...ur(t,n)}}}function Sa(e){const t=Aa(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 Aa(e){const t=e.caption.reserveLines,n=e.caption.maxWidth??.86,r=n<.86||(e.caption.align??"center")!=="center";return typeof t!="number"?{column:r}:{lines:t,characters:Math.round(t*18*n/.86),column:r}}function yr(e){return Wt.find(t=>t.id===e)}function ka(e){const t={};for(const n of Io)t[n]=e.caption[n];return t.bandCenter=void 0,t.widthMode=void 0,{shotLook:{...e.shotLook},caption:t}}function nt(e,t){const n=typeof t=="number"?t:Number.parseFloat(String(t??"")),r=Number.isFinite(n)?n:Number.parseFloat(_[e]),{min:o,max:a}=Ce[e];return Math.max(o,Math.min(a,r))}function vr(e){return{deviceSize:nt("deviceSize",e.deviceSize),hOffset:nt("hOffset",e.hOffset),vOffset:nt("vOffset",e.vOffset)}}function mn(e){const t=Ht(e.deviceSize),n=Xn*e.deviceSize/100,r=.5+e.hOffset/200,o=.5+e.vOffset/200;return{left:r-n/2,right:r+n/2,top:o-t/2,bottom:o+t/2}}const Pa=.06;function Oa(e){let t=!1;return{placements:e.map((r,o)=>{const a=e.slice(0,o).filter(s=>Yn.every(l=>s[l]===r[l])).length;if(a===0)return r;t=!0;const i=2*Xn*r.deviceSize*(1+Pa);return{...r,hOffset:r.hOffset+a*i}}),moved:t}}function gn(e,t){const n=-e,r=t-1;return Math.abs(n-r)<1e-9?"centre":n>r?"start":"end"}const ze=(e,t,n)=>e==="start"?t:e==="end"?n:(t+n)/2;function yn(e,t){const{min:n,max:r}=Ce[t],o=e.map(l=>l[t]),a=Math.max(...o),i=Math.min(...o),s=a>r?r-a:i<n?n-i:0;return s===0?e:e.map(l=>({...l,[t]:l[t]+s}))}function Ca(e,t){const n=mn(vr(e.shotLook)),r=t.map(mn),o={left:Math.min(...r.map(h=>h.left)),right:Math.max(...r.map(h=>h.right)),top:Math.min(...r.map(h=>h.top)),bottom:Math.max(...r.map(h=>h.bottom))},a=Math.min((n.right-n.left)/(o.right-o.left),(n.bottom-n.top)/(o.bottom-o.top)),i=gn(n.left,n.right),s=gn(n.top,n.bottom),l=ze(i,o.left,o.right),c=ze(i,n.left,n.right),u=ze(s,o.top,o.bottom),f=ze(s,n.top,n.bottom),d=t.map(h=>({deviceSize:h.deviceSize*a,hOffset:(c+(.5+h.hOffset/200-l)*a-.5)*200,vOffset:(f+(.5+h.vOffset/200-u)*a-.5)*200})),{min:p,max:g}=Ce.deviceSize;return yn(yn(d,"hOffset"),"vOffset").map(h=>({...h,deviceSize:Math.max(p,Math.min(g,h.deviceSize))}))}const rt=e=>String(Math.round(e*100)/100),Ma=.05;function Ta(e,t){const n=ka(e).shotLook;if(t.length<2)return t.map(()=>({...n}));const r=t.map(vr),o=Oa(r),a=Ca(e,o.placements),i=!o.moved&&a.every((s,l)=>Yn.every(c=>Math.abs(s[c]-r[l][c])<=Ma));return t.map((s,l)=>({...n,...i?{deviceSize:s.deviceSize,hOffset:s.hOffset,vOffset:s.vOffset}:{deviceSize:rt(a[l].deviceSize),hOffset:rt(a[l].hOffset),vOffset:rt(a[l].vOffset)}}))}const Ea=e=>({...e,...e.anchor?{anchor:{...e.anchor}}:{}}),ot=(e,t)=>JSON.stringify(e)===JSON.stringify(t),ee=e=>typeof e=="object"&&e!==null&&!Array.isArray(e);function vn(e){if(!ee(e))return null;const[t]=Xt({layer:[e]}).layer,{text:n,...r}=t;return Object.fromEntries(Object.entries(r).sort(([o],[a])=>o<a?-1:o>a?1:0))}function La(e,t){if(!ee(e)||!ee(e.frameTemplates))return null;const n=e.frameTemplates[t];if(!ee(n)||typeof n.templateId!="string"||!yr(n.templateId))return null;const r=n.templateId,o=Array.isArray(n.shots)?n.shots.filter(ee):[],a=Array.isArray(e.shots)?e.shots.filter(u=>ee(u)&&u.panelId===t):[];let i=a.length!==o.length||o.some((u,f)=>{const d=a[f];return d?.id!==u.id||!ot(d?.look,u.look)});const s=ee(e.captionSlotIds)?e.captionSlotIds:{},l=Array.isArray(s[t])?s[t]:[],c=Array.isArray(n.captionSlotIds)?n.captionSlotIds:[];if(!i&&!ot(l,c)&&(i=!0),!i){const u=ee(e.captionText)?e.captionText:{},f=ee(n.captions)?n.captions:{},d=typeof n.baseLocale=="string"?n.baseLocale:"",p=new Set([...Object.keys(u),...Object.keys(f)]);for(const g of Array.from(p)){const h=ee(u[g])?u[g]:{},v=Array.isArray(h[t])?h[t]:[],m=Array.isArray(f[g])?f[g]:Array.isArray(f[d])?f[d]:[];if(v.length!==c.length||m.length!==c.length){i=!0;break}if(m.some((b,y)=>!ot(vn(v[y]),vn(b)))){i=!0;break}}}return{templateId:r,modified:i,resettable:!0}}function Fa(e,t){return Math.max(0,...Object.values(e).map(n=>n[t]?.length??0))}function br(e,t,n){const r=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=new Set,a={};let i=1;const s=()=>{for(;o.has(`caption-${i}`);)i+=1;const l=`caption-${i}`;return o.add(l),i+=1,l};for(const l of n){const c=Fa(t,l);if(c===0)continue;const u=Array.isArray(r[l])?r[l]:[];a[l]=Array.from({length:c},(f,d)=>{const p=u[d];return typeof p=="string"&&p.length>0&&!o.has(p)?(o.add(p),p):s()})}return a}function Ra(e,t,n){const r={};for(const[o,a]of Object.entries(e.captionText)){const i=a[t];i?.length&&(r[o]=i.map(Ea))}return{templateId:n,baseLocale:e.baseLocale,shots:e.shots.filter(o=>o.panelId===t).map(o=>({id:o.id,frameNodeId:o.frameNodeId,frameName:o.frameName,look:{...o.look},...o.inputAnchor?{inputAnchor:o.inputAnchor}:{},...o.outputAnchor?{outputAnchor:o.outputAnchor}:{}})),captionSlotIds:[...e.captionSlotIds[t]??[]],captions:r}}function za(e,t){return La(e,t)}const wr=2;function Na(e){if(!e||typeof e!="object"||Array.isArray(e))return!1;const t=e;return t.schema===wr&&Array.isArray(t.shots)&&Array.isArray(t.panels)&&t.panels.length>0}function Ba(e){let t;try{t=JSON.parse(e)}catch{return null}if(!Na(t))return null;const n=t,r=new Set(n.panels.map(p=>p.id)),o=n.shots.filter(p=>r.has(p.panelId)).map(p=>({id:p.id,panelId:p.panelId,frameNodeId:p.frameNodeId,frameName:p.frameName,bytes:null,look:nr(p.look),thumb:null,thumbStale:!0,inputAnchor:p.inputAnchor,outputAnchor:p.outputAnchor,...se(p)})),a=n.panels.map(p=>({id:p.id}));ua(o.map(p=>p.id),a.map(p=>p.id));const i=n.selectedShotId&&o.some(p=>p.id===n.selectedShotId)?n.selectedShotId:o[0]?.id??null,{captionText:s,locales:l,baseLocale:c}=aa(n),u=Co(n),f=br(n.captionSlotIds,s,a.map(p=>p.id)),d=Ke(n.gradientStops,n.gradientAngle);return{shots:ya(de(o,a),a),panels:a,selectedShotId:i,panelPresetId:u.panelPresetId,bgMode:n.bgMode==="perPanel"?"perPanel":"gradient",...d?{gradientStops:d.stops,gradientAngle:d.angle,...Ue(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:sr(n.panelBackgrounds),captionText:s,locales:l,baseLocale:c,staleCaptionTranslations:cr(n.staleCaptionTranslations,l,c,s),outputs:u.outputs,localeScreens:{},outputCaptions:pr(n.outputCaptions),captionSlotIds:f,frameTemplates:n.frameTemplates&&typeof n.frameTemplates=="object"&&!Array.isArray(n.frameTemplates)?n.frameTemplates:{}}}function xr(e){const n=de(e.shots,e.panels).map(a=>({id:a.id,panelId:a.panelId,frameNodeId:a.frameNodeId,frameName:a.frameName,look:rr(a.look),inputAnchor:a.inputAnchor,outputAnchor:a.outputAnchor,...se(a)})),r=Kt(e.baseLocale),o=Ye(e.captionText,e.captionStyles,r);return{schema:wr,shots:n,panels:e.panels,selectedShotId:e.selectedShotId,captionText:o,locales:kt(o,e.locales,r),baseLocale:r,staleCaptionTranslations:cr(e.staleCaptionTranslations,kt(o,e.locales,r),r,o),outputs:er(e.outputs,e.panelPresetId),outputCaptions:pr(e.outputCaptions),...(()=>{const a=br(e.captionSlotIds,o,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}:{},...gr(e,o,r)}}const _a=1;function Da(e){const t=de(e.shots,e.panels),n=Ye(e.captionText,e.captionStyles),r=Kt(e.baseLocale);return{schema:_a,shots:t.map(o=>({panelId:o.panelId,look:rr(o.look),...se(o)})),...gr(e,n,r)}}Jn.map(e=>({id:e.id,label:e.label,description:e.blurb}));Wt.map(e=>({id:e.id,label:e.label,description:Sa(e),character:e.character}));const ja=[{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","setShotLayering"],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.","A device’s paint order and hiding it are not writable; the user sets them in Studio or through edit_project."],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"]}],Ua="unknown",Wa=[{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."}],Ha=ja.map(e=>e.id);[...Ha,...Wa.map(e=>e.id)];const Ga=7,bn={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 Ir(e){const t=bn[e]??bn.front,n=Math.hypot(t.x,t.y,t.z),r=Ga/n;return{x:t.x*r,y:t.y*r,z:t.z*r}}function $a(e){return Math.atan2(e.x,-e.z)*180/Math.PI}const Sr=[{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"}];Sr.map(e=>e.code);Object.fromEntries(Sr.map(e=>[e.code,e]));({...Gt});function Va(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(U("finish",t.finish)),e.setClearcoat(U("clearcoat",t.clearcoat)))}function qa(e,t,n){e.screen.setGlare(!n&&t?e.device.environmentMap():null)}async function Xa(e,t,n,r){const{stage:o,device:a,screen:i}=e,s=t.material==="clay";if(t.cameraPos?o.setCameraPosition(t.cameraPos):o.setAngle(t.angle),a.setRoll(U("roll",t.roll)),Va(a,t),i.restoreScreen(),n||i.clearWallpaper(),o.setStudioLighting(t.lighting),a.setReflections(t.reflections),i.setFlatScreen(t.flatScreen),n){try{await i.applyWallpaper(n)}catch{r()&&i.clearWallpaper()}if(!r())return}qa(e,t.glare,s)}const Ka=""+new URL("iphone-optimized-BdcJzlHi.glb",import.meta.url).href,Ya="data:model/gltf-binary;base64,Z2xURgIAAADUAAAAwAAAAEpTT057ImFzc2V0Ijp7InZlcnNpb24iOiIyLjAiLCJnZW5lcmF0b3IiOiJTaG90T3BzIHBsYWNlaG9sZGVyIOKAlCB0aGUgUGl4ZWwgbW9kZWwgaXMgZGVsaWJlcmF0ZWx5IG5vdCBidW5kbGVkIGluIHRoZSBucG0gcGFja2FnZSJ9LCJzY2VuZXMiOlt7Im5hbWUiOiJwaXhlbC1ub3QtYnVuZGxlZCIsIm5vZGVzIjpbXX1dLCJzY2VuZSI6MH0gICA=",Ja=[{id:"grey",label:"Grey",color:11579568},{id:"white",label:"White",color:15263458},{id:"charcoal",label:"Charcoal",color:3815996}],Za=[{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}],Qa=[{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}],Ge={id:"iphone-17-pro",glb:Ka,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:Za},wn={id:"pixel-10-pro",glb:Ya,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:Qa},ei={[Ge.id]:Ge,[wn.id]:wn};function Yt(e){return e&&ei[e]||Ge}function Pt(e){const t=Ir(e);return new ce(t.x,t.y,t.z)}const ti=1.4;function ni(e,t){return(t?new ce(t.x,t.y,t.z):Pt(e)).multiplyScalar(ti)}const Jt=35;function ri(e){e.traverse(t=>{const n=t;n.geometry?.dispose();const r=n.material;Array.isArray(r)?r.forEach(xn):r&&xn(r)}),e.clear()}function xn(e){for(const t of Object.values(e))t&&typeof t=="object"&&t.isTexture&&t.dispose();e.dispose()}function Ar(e,t){const n=document.createElement("canvas"),r=new uo({canvas:n,antialias:!0,preserveDrawingBuffer:!0,alpha:!0});r.setSize(e,t,!1),r.shadowMap.enabled=!0;const o=new to;o.background=null;const{ambient:a,directionals:i}=oi(o),s=new jt(Jt,e/t,.01,100);s.position.copy(Pt("front")),s.lookAt(0,0,0);function l(p){s.position.copy(Pt(p)),s.lookAt(0,0,0)}function c(p){s.position.set(p.x,p.y,p.z),s.lookAt(0,0,0)}function u(p){i.forEach(g=>g.visible=p),a.intensity=p?.75:1.6}let f=!1;function d(){f||(f=!0,o.environment?.dispose(),o.environment=null,ri(o),r.dispose(),r.forceContextLoss())}return{scene:o,camera:s,renderer:r,dispose:d,setAngle:l,setCameraPosition:c,getCameraPosition:()=>({x:s.position.x,y:s.position.y,z:s.position.z}),onUserPose:()=>{},previewOrbit:()=>{},commitOrbit:()=>{},setOrbitEnabled:()=>{},setBackground:()=>{},setStudioLighting:u,resize:()=>{},invalidate:()=>{}}}function oi(e){const t=new ro(16777215,.75);e.add(t);const n=new tt(16777215,2.2);n.position.set(3,5,5);const r=new tt(12571903,.7);r.position.set(-4,1,2);const o=new tt(16777215,1);o.position.set(0,3,-5);const a=[n,r,o];return a.forEach(i=>e.add(i)),{ambient:t,directionals:a}}function kr(e,t){const n=Yt(t);return new Promise((r,o)=>{new no().load(n.glb,a=>{const i=a.scene;if(n.pruneNamePrefixes.length){const d=[];i.traverse(p=>{n.pruneNamePrefixes.some(g=>p.name.startsWith(g))&&d.push(p)}),d.forEach(p=>p.removeFromParent())}i.rotation.set(n.baseEuler.x,n.baseEuler.y,n.baseEuler.z),i.updateMatrixWorld(!0);const s=new fo().setFromObject(i),l=s.getSize(new ce),c=s.getCenter(new ce),u=n.fitSize/Math.max(l.x,l.y,l.z);i.scale.multiplyScalar(u),i.position.copy(c.multiplyScalar(-u));const f=new ho;f.add(i),e.scene.add(f),e.setAngle("front"),r(f)},void 0,o)})}function ai(e){return kr(e)}const In=1900,Sn=2800,ii=8192,si=2;async function li(e,t,n,r={}){const o=e.renderer,a=o.getPixelRatio(),i=o.getSize(new qn);o.setDrawingBufferSize(t,n,1);let s;r.cameraPosition?(s=new jt(Jt,t/n,.01,100),s.position.copy(r.cameraPosition),s.lookAt(0,0,0)):(s=e.camera.clone(),s.aspect=t/n,s.updateProjectionMatrix());try{const l=e.scene.background;e.scene.background=null;try{o.render(e.scene,s)}finally{e.scene.background=l}const c=document.createElement("canvas");let u=null;try{c.width=t,c.height=n,c.getContext("2d")?.drawImage(o.domElement,0,0);const f=Pr(c),d=f.canvas;u=d;const p=d.width,g=d.height;return{bytes:await new Promise((v,m)=>{d.toBlob(b=>{if(!b){m(new Error("toBlob returned null"));return}b.arrayBuffer().then(y=>v(new Uint8Array(y)),m)},"image/png")}),width:p,height:g,frame:{width:t,height:n,cropX:f.x,cropY:f.y}}}finally{u&&u!==c&&(u.width=0,u.height=0),c.width=0,c.height=0}}finally{o.setDrawingBufferSize(i.x,i.y,a),e.invalidate()}}function Pr(e,t=si){const n=e.getContext("2d",{willReadFrequently:!0});if(!n)return{canvas:e,x:0,y:0};const{width:r,height:o}=e,a=n.getImageData(0,0,r,o).data;let i=r,s=o,l=-1,c=-1;for(let p=0;p<o;p++)for(let g=0;g<r;g++)a[(p*r+g)*4+3]!==0&&(g<i&&(i=g),g>l&&(l=g),p<s&&(s=p),p>c&&(c=p));if(l<i||c<s)return{canvas:e,x:0,y:0};i=Math.max(0,i-t),s=Math.max(0,s-t),l=Math.min(r-1,l+t),c=Math.min(o-1,c+t);const u=l-i+1,f=c-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 ci(e){const t=URL.createObjectURL(new Blob([e],{type:"image/png"}));return new Promise((n,r)=>{const o=new Image;o.onload=()=>{URL.revokeObjectURL(t),n(o)},o.onerror=()=>{URL.revokeObjectURL(t),r(new Error("Screenshot could not be decoded for the flat card"))},o.src=t})}function di(e,t,n,r){if(e.beginPath(),r<=0){e.rect(0,0,t,n);return}e.moveTo(r,0),e.arcTo(t,0,t,n,r),e.arcTo(t,n,0,n,r),e.arcTo(0,n,0,0,r),e.arcTo(0,0,t,0,r),e.closePath()}function ui(e,t,n,r){const o=t?"naturalWidth"in t?t.naturalWidth:t.width:0,a=t?"naturalHeight"in t?t.naturalHeight:t.height:0,i=Ia(o,a,n,r),{width:s,height:l,cardWidth:c,cardHeight:u,radius:f,rotation:d}=i;e.width=s,e.height=l;const p=e.getContext("2d");if(!p)throw new Error("2D context unavailable for the flat card");return p.translate(s/2,l/2),p.rotate(d),p.translate(-c/2,-u/2),di(p,c,u,f),p.clip(),t?(p.imageSmoothingQuality="high",p.drawImage(t,0,0,c,u)):(p.fillStyle="#000",p.fillRect(0,0,c,u)),i}async function fi(e,t,n){return(await Or(e,t,n)).out}async function Or(e,t,n){const r=e?await ci(e):null,o=document.createElement("canvas");try{const a=ui(o,r,t,n),{width:i,height:s}=a;return{out:{bytes:await new Promise((c,u)=>{o.toBlob(f=>{if(!f){u(new Error("toBlob returned null"));return}f.arrayBuffer().then(d=>c(new Uint8Array(d)),u)},"image/png")}),width:i,height:s,frame:{width:i,height:s,cropX:0,cropY:0}},geometry:a}}finally{o.width=0,o.height=0}}const An=24*1024*1024,Ot=new WeakMap;async function hi(e){const t=await ta(e.bytes);return Ct({look:e.look,screenshot:t,width:e.width,height:e.height,physicalBody:e.physicalBody,screenLayers:e.screenLayers})}function pi(e,t){const n=Ot.get(e);if(!n)return;const r=n.entries.get(t);if(r)return n.entries.delete(t),n.entries.set(t,r),r}function mi(e,t,n){const r=n.bytes.byteLength;if(r>An)return;let o=Ot.get(e);o||(o={entries:new Map,bytes:0},Ot.set(e,o));const a=o.entries.get(t);a&&(o.bytes-=a.bytes.byteLength),o.entries.delete(t),o.entries.set(t,n),o.bytes+=r;const i=Array.from(o.entries.keys());for(let s=0;s<i.length&&o.bytes>An;s++){const l=o.entries.get(i[s]);l&&(o.bytes-=l.bytes.byteLength,o.entries.delete(i[s]))}}function Ct(e){if(e===null||typeof e!="object")return JSON.stringify(e)??"null";if(Array.isArray(e))return`[${e.map(Ct).join(",")}]`;const t=e;return`{${Object.keys(t).filter(r=>t[r]!==void 0).sort().map(r=>`${JSON.stringify(r)}:${Ct(t[r])}`).join(",")}}`}function gi(e,t,n,r,o){return{x:(e.x+1)/2*t-r,y:(1-e.y)/2*n-o}}function yi(e){const{width:t,height:n,cardWidth:r,cardHeight:o,rotation:a}=e,i=Math.cos(a),s=Math.sin(a),l=(f,d)=>({x:t/2+f*i-d*s,y:n/2+f*s+d*i}),c=r/2,u=o/2;return{tl:l(-c,-u),tr:l(c,-u),br:l(c,u),bl:l(-c,u)}}function at(e){return new Promise((t,n)=>{e.toBlob(r=>{if(!r){n(new Error("toBlob returned null"));return}r.arrayBuffer().then(o=>t(new Uint8Array(o)),n)},"image/png")})}function kn(e,t,n,r,o){const a=document.createElement("canvas");return a.width=r,a.height=o,a.getContext("2d")?.drawImage(e,t,n,r,o,0,0,r,o),a}function vi(e,t){const n=Math.hypot(e.tr.x-e.tl.x,e.tr.y-e.tl.y),r=Math.hypot(e.bl.x-e.tl.x,e.bl.y-e.tl.y);return n>0?Math.min(n,r)*t/n:0}async function bi(e,t,n,r,o,a={}){const i=e.renderer,s=i.getPixelRatio(),l=i.getSize(new qn);i.setDrawingBufferSize(n,r,1);let c;a.cameraPosition?(c=new jt(Jt,n/r,.01,100),c.position.copy(a.cameraPosition),c.lookAt(0,0,0)):(c=e.camera.clone(),c.aspect=n/r,c.updateProjectionMatrix()),c.updateMatrixWorld();const u=[],f=()=>{const d=document.createElement("canvas");return d.width=n,d.height=r,u.push(d),d};try{const d=f(),p=f(),g=f(),h=e.scene.background;e.scene.background=null;try{i.render(e.scene,c),d.getContext("2d")?.drawImage(i.domElement,0,0);try{t.setLayerPass("device"),i.render(e.scene,c),p.getContext("2d")?.drawImage(i.domElement,0,0),t.setLayerPass("screen"),i.render(e.scene,c),g.getContext("2d")?.drawImage(i.domElement,0,0)}finally{t.restoreLayerPass()}}finally{e.scene.background=h}const v=Pr(d);v.canvas!==d&&u.push(v.canvas);const m=v.canvas.width,b=v.canvas.height,y=kn(p,v.x,v.y,m,b),w=kn(g,v.x,v.y,m,b);u.push(y,w),e.scene.updateMatrixWorld();const x=t.screenCornersWorld(),P=C=>{const M=C.clone().project(c);return gi(M,n,r,v.x,v.y)},S={x:0,y:0},A=x?{tl:P(x.tl),tr:P(x.tr),br:P(x.br),bl:P(x.bl)}:{tl:S,tr:S,br:S,bl:S},[O,I,k]=[await at(v.canvas),await at(y),await at(w)];return{bytes:O,width:m,height:b,frame:{width:n,height:r,cropX:v.x,cropY:v.y},layers:{width:m,height:b,device:I,screen:{bytes:k,quad:A,cornerRadiusFrac:vi(A,t.cornerRatio),sourceNodeId:o}}}}finally{u.forEach(d=>{d.width=0,d.height=0}),i.setDrawingBufferSize(l.x,l.y,s),e.invalidate()}}async function wi(e,t,n,r){const{out:o,geometry:a}=await Or(e,t,n);return xi(o,a,r)}function xi(e,t,n){const r=yi(t);return{...e,layers:{width:e.width,height:e.height,device:null,screen:{bytes:e.bytes,quad:r,cornerRadiusFrac:t.cardWidth>0?t.radius/t.cardWidth:0,sourceNodeId:n}}}}function Ii(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 Si(e,t){return e.usesPhysicalFinish()?!0:t.material!=="clay"&&U("clearcoat",t.clearcoat)>0}async function Ai(e,t,n,r,o,a){const i=de(n,r),s=da(n,r).filter(g=>g.bytes);if(s.length===0)return null;const l=Me(o.panelPresetId),c=new Map(r.map((g,h)=>[g.id,h])),u=o.renderScale!=null&&Number.isFinite(o.renderScale)&&o.renderScale>0?o.renderScale:1,f=Math.min(u,ii/Math.max(In,Sn)),d=Math.max(1,Math.round(In*f)),p=Math.max(1,Math.round(Sn*f));{const g=[];for(let b=0;b<s.length;b++){const y=s[b];a(`Rendering ${b+1}/${s.length}${o.locale?` (${o.locale})`:""}…`);let w,x;const P=y.frameNodeId||null,S=o.screenLayers||!y.bytes?null:await hi({look:y.look,bytes:y.bytes,width:d,height:p,physicalBody:Si(t.device,y.look),screenLayers:!1}),A=S?pi(e,S):void 0;if(A)w=A;else if(xa(y.look)){await Xa(t,y.look,y.bytes,()=>!0);const O=ni(y.look.angle,y.look.cameraPos);if(o.screenLayers){const I=await bi(e,t.screen,d,p,P,{cameraPosition:O});w=I,x=I.layers}else w=await li(e,d,p,{cameraPosition:O})}else if(o.screenLayers){const O=await wi(y.bytes,y.look,p,P);w=O,x=O.layers}else w=await fi(y.bytes,y.look,p);S&&!A&&mi(e,S,w),g.push({shotId:y.id,bytes:w.bytes,width:w.width,height:w.height,heightFrac:Ht(U("deviceSize",y.look.deviceSize)),hOffset:U("hOffset",y.look.hOffset)/100,vOffset:U("vOffset",y.look.vOffset)/100,panelIndex:c.get(y.panelId)??0,...y.look.clipToFrame===!0?{clipToFrame:!0}:{},...x?{layers:x}:{}})}const h=va(g,l.width,l.height),v=ba(r,o);a("Saving project…");const m=xr(Ii(i,r,o));return{panelWidth:l.width,panelHeight:l.height,count:r.length,background:v,phones:h,shadow:o.shadow,floorReflection:o.floorReflection??!1,project:JSON.stringify(m)}}}function $e(e){return/^[0-9a-fA-F]{3,8}$/.test(e)?`#${e}`:e}function Mt(e,t,n,r){const{x0:o,y0:a,x1:i,y1:s}=Bo(n,r,t.angle),l=e.createLinearGradient(o,a,i,s);for(const c of t.stops)l.addColorStop(Math.min(1,Math.max(0,c.at)),$e(c.color));return l}function Ne(e,t,n,r,o,a,i){const s=document.createElement("canvas");s.width=n,s.height=r;try{const l=s.getContext("2d");if(!l)return;l.fillStyle=Mt(l,t,n,r),l.fillRect(o,0,a,r),e.drawImage(s,o,0,a,r,i,0,a,r)}finally{s.width=0,s.height=0}}function Pn(e){return URL.createObjectURL(new Blob([e],{type:"image/png"}))}function On(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>t(r),r.onerror=n,r.src=e})}const ki=128,Pi=32;function Oi(e){const t=e.naturalWidth,n=e.naturalHeight;if(!(t>0&&n>0))return{rows:[]};const r=Math.min(ki,n),o=Math.max(1,Math.min(t,Math.round(r*t/n)*2)),a=document.createElement("canvas");a.width=o,a.height=r;try{const i=a.getContext("2d",{willReadFrequently:!0});if(!i)return{rows:[]};i.drawImage(e,0,0,o,r);const s=i.getImageData(0,0,o,r).data,l=[];for(let c=0;c<r;c++){let u=-1,f=-1;for(let d=0;d<o;d++)s[(c*o+d)*4+3]<Pi||(u<0&&(u=d),f=d);l.push(u<0?null:[u/o,(f+1)/o])}return{rows:l}}finally{a.width=0,a.height=0}}const Ci=16*1024*1024;function Cn(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 Cr(){let e=0;const t=Array.from(ie.values());for(const o of t)e+=Cn(o);const n=Array.from(ie.keys());let r=0;for(;e>Ci&&r<n.length-1;){const o=ie.get(n[r]);o&&(e-=Cn(o),o.reflection&&(o.reflection.canvas.width=0,o.reflection.canvas.height=0),ie.delete(n[r])),r++}}const ie=new Map,it=new Map;async function Mi(e,t){if(!t){const a=Pn(e);try{return{img:await On(a)}}finally{URL.revokeObjectURL(a)}}const n=ie.get(e);if(n)return ie.delete(e),ie.set(e,n),n;const r=it.get(e);if(r)return r;const o=(async()=>{const a=Pn(e);try{return{img:await On(a)}}finally{URL.revokeObjectURL(a)}})();it.set(e,o);try{const a=await o;return ie.set(e,a),Cr(),a}finally{it.delete(e)}}async function Ti(e,t,n){const r={},o=t.panelWidth*t.count,a=t.panelHeight,i=n?.backgroundViewport,s=i?t.panelWidth*i.panelCount:o,l=i?t.panelWidth*i.panelIndex:0,c=n?.panelViewport,u=c===void 0?0:c*t.panelWidth,f=c===void 0?o:t.panelWidth;e.width=f,e.height=a;const d=e.getContext("2d");if(!d)return{silhouettes:r};n?.transparentBg?d.clearRect(0,0,o,a):t.background.kind==="gradient"?c!==void 0?Ne(d,t.background.gradient,o,a,u,f,0):i?Ne(d,t.background.gradient,s,a,l,o,0):(d.fillStyle=Mt(d,t.background.gradient,o,a),d.fillRect(0,0,o,a)):t.background.kind==="perPanel"?t.background.colors.forEach((v,m)=>{d.fillStyle=$e(v),d.fillRect(m*t.panelWidth-u,0,t.panelWidth,a)}):t.background.fills.forEach((v,m)=>{const b=m*t.panelWidth-u;c!==void 0&&m!==c||(v.kind==="solid"?(d.fillStyle=$e(v.color),d.fillRect(b,0,t.panelWidth,a)):c!==void 0?Ne(d,v.gradient,o,a,u,f,0):i?Ne(d,v.gradient,s,a,l+b,t.panelWidth,b):(d.fillStyle=Mt(d,v.gradient,o,a),d.fillRect(b,0,t.panelWidth,a)))}),d.save(),d.translate(-u,0);const p=n?.phoneRange?Math.max(0,n.phoneRange.start):0,g=n?.phoneRange?Math.min(t.phones.length,n.phoneRange.end):t.phones.length,h=n?.reuseDecodedPhones===!0;for(let v=p;v<g;v++){const m=t.phones[v],b=n?.clip==="panel"||n?.clip===void 0&&m.clipToFrame===!0;if(n?.skipShotId&&m.shotId===n.skipShotId)continue;const y=await Mi(m.bytes,h),w=y.img,x=y.silhouette??Oi(w);h&&(y.silhouette=x),r[m.shotId]=x,Ei(d,y,m,t,b,h)}return d.restore(),{silhouettes:r}}function Ei(e,t,n,r,o=n.clipToFrame===!0,a=!1,i=1){const s=t.img;o&&(e.save(),e.beginPath(),e.rect(n.panelIndex*r.panelWidth,0,r.panelWidth,r.panelHeight),e.clip()),r.floorReflection&&Li(e,t,n,a),e.save(),r.shadow&&(e.shadowColor="rgba(0,0,0,0.35)",e.shadowBlur=r.panelWidth*.03*i,e.shadowOffsetY=r.panelHeight*.012*i),e.drawImage(s,n.x,n.y,n.width,n.height),e.restore(),o&&e.restore()}function Li(e,t,n,r){const o=Math.round(n.height*.45);if(o<=0||n.width<=0)return;const a=r?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,o);return}const i=t.img,s=document.createElement("canvas");s.width=Math.max(1,n.width),s.height=Math.max(1,o);const l=s.getContext("2d");if(!l)return;l.save(),l.translate(0,o),l.scale(1,-1),l.drawImage(i,0,o-n.height,n.width,n.height),l.restore();const c=l.createLinearGradient(0,0,0,o);c.addColorStop(0,"rgba(0,0,0,0.34)"),c.addColorStop(1,"rgba(0,0,0,0)"),l.globalCompositeOperation="destination-in",l.fillStyle=c,l.fillRect(0,0,n.width,o),e.drawImage(s,n.x,n.y+n.height,n.width,o),r&&(t.reflection={width:n.width,height:n.height,canvas:s},Cr())}const Mr=pe.lineHeight,Fi=pe.bandInset;function Ri(e,t,n){if(!e)return[t];const r=t.split(/\s+/).filter(Boolean),o=[];let a="";for(const i of r){const s=a?`${a} ${i}`:i;a&&e.measureText(s).width>n?(o.push(a),a=i):a=s}return a&&o.push(a),o}function zi(e,t){if(!e)return 0;let n=0;for(const r of t)n=Math.max(n,e.measureText(r).width);return n}function Mn(e,t,n){return e==="center"?t+n/2:e==="right"?t+n:t}function Tr(e,t,n,r){const o=t.map((g,h)=>{const v=g.text.trim();if(!v)return null;const m=g.sizePt*(r/Xe),b=Ut(g.fontId).family;e&&(e.font=`${Ie} ${m}px "${b}"`);const w=(te(g.anchor)?Te(g):g.maxWidth)*n,x=Ri(e,v,w),P=m*(g.lineHeight??Mr),S=x.length*P,A=Math.max(S,(g.reserveLines??x.length)*P);return{layer:g,index:h,lines:x,px:m,lineH:P,width:zi(e,x),blockH:S,reservedH:A,boxWidth:w}}),a=o.filter(g=>g!==null&&te(g.layer.anchor)),i=a.filter(g=>g.layer.band==="bottom"),s=a.filter(g=>g.layer.band!=="bottom"),l=g=>g[0]?.layer.bandInset??Fi,c=(1-l(i))*r-i.reduce((g,h)=>g+h.reservedH,0);let u=l(s)*r,f=c,d=0;const p=[];for(const g of o){if(!g)continue;if(!te(g.layer.anchor)){const w=g.layer.anchor.x*n,x=g.layer.anchor.y*r;p.push({layer:g.layer,index:g.index,x:Mn(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 h=g.layer.band==="bottom",v=h?f:u,m=v+(g.reservedH-g.blockH)/2,b=lr(g.layer)*n,y=Mn(g.layer.align,b,g.boxWidth);p.push({layer:g.layer,index:g.index,x:y,yTop:m,lines:g.lines,px:g.px,lineH:g.lineH,width:g.width,boxLeft:b,boxWidth:g.boxWidth,boxTop:v,boxHeight:g.reservedH}),h?f+=g.reservedH:u+=g.reservedH,d=Math.max(d,m+g.blockH)}return{placed:p,bandBottom:d}}function Ni(e,t,n,r){e.save(),e.textBaseline="top";const{placed:o}=Tr(e,t,n,r);for(const a of o){e.fillStyle=$e(a.layer.color),e.textAlign=a.layer.align,e.font=`${Ie} ${a.px}px "${Ut(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 Bi(e,t){return e.sizePt*(t/Xe)*(e.lineHeight??Mr)}function _i(e,t,n,r){const o=Tr(e,t,n,r).placed;e?.save(),e&&(e.textBaseline="top");const a=o.map(i=>{const s=i.layer.align==="center"?i.x-i.width/2:i.layer.align==="right"?i.x-i.width:i.x,l=i.lines.length*i.lineH;let c=i.yTop,u=i.yTop+l;if(e){e.font=`${Ie} ${i.px}px "${Ut(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)&&(c=i.yTop-f,u=i.yTop+(i.lines.length-1)*i.lineH+d)}return{index:i.index,anchorX:i.boxLeft/n,top:i.yTop/r,boxLeft:i.boxLeft/n,boxTop:i.boxTop/r,boxWidth:i.boxWidth/n,boxHeight:i.boxHeight/r,left:s/n,width:i.width/n,height:l/r,inkTop:c/r,inkHeight:(u-c)/r}});return e?.restore(),a}function Di(e,t,n,r,o){t.forEach((a,i)=>{const s=o[a];!s||s.length===0||(e.save(),e.translate(i*n,0),Ni(e,s,n,r),e.restore())})}const ji=""+new URL("Inter-SemiBold-B9yU462S.woff2",import.meta.url).href,Ui=""+new URL("Manrope-SemiBold-44nuYf5T.woff2",import.meta.url).href,Wi=""+new URL("Poppins-SemiBold-DJVo7c07.woff2",import.meta.url).href,Hi=""+new URL("Fraunces-SemiBold-BtraKtER.woff2",import.meta.url).href,Gi=""+new URL("SpaceGrotesk-SemiBold-CyO2J5Y0.woff2",import.meta.url).href,$i={inter:ji,manrope:Ui,poppins:Wi,fraunces:Hi,"space-grotesk":Gi},Vi=je.map(e=>({...e,url:$i[e.id]}));let Be=null;function qi(){return Be||(Be=(async()=>{const e=new Set;document.fonts.forEach(t=>e.add(`${t.family}/${t.weight}`)),await Promise.all(Vi.filter(t=>!e.has(`${t.family}/${String(Ie)}`)).map(async t=>{const n=new FontFace(t.family,`url(${t.url})`,{weight:String(Ie)});await n.load(),document.fonts.add(n)})),await document.fonts.ready})().catch(e=>{throw Be=null,e})),Be}const Xi=22/Xe,Ki=1.1,Tn=4,Yi=.063,Ji=.167,xe=Math.round(Xi*Xe),Zi=.02,Qi=50;function Je(e,t){const n=re(e,t.box);if(!n||!t.silhouette||t.silhouette.rows.length===0)return n;const{frame:r}=t,o=t.silhouette.rows,a=r.height/o.length;let i=1/0,s=1/0,l=-1/0,c=-1/0;const u=Math.max(0,Math.floor((n.y-r.y)/a)),f=Math.min(o.length-1,Math.ceil((n.y+n.height-r.y)/a)-1);for(let d=u;d<=f;d++){const p=o[d];if(!p)continue;const g=re(n,{x:r.x+p[0]*r.width,y:r.y+d*a,width:(p[1]-p[0])*r.width,height:a});g&&(i=Math.min(i,g.x),s=Math.min(s,g.y),l=Math.max(l,g.x+g.width),c=Math.max(c,g.y+g.height))}return l>i&&c>s?{x:i,y:s,width:l-i,height:c-s}:null}function re(e,t){const n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),o=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height);return o<=n||a<=r?null:{x:n,y:r,width:o-n,height:a-r}}function Ve(e,t){return re(e,t)}function En(e,t){const n=Math.abs(e-t)%360;return n>180?360-n:n}function Ln(e){return $a(e.cameraPos??Ir(e.angle))}function Ee(e,t,n,r,o,a,i){if(t.length===0)return[];const s=[];for(const l of _i(e,t,o,a)){const c=t[l.index];if(!c)continue;const u=Ve({x:(r+l.left)*o,y:l.top*a,width:l.width*o,height:l.height*a},i);u&&s.push({ref:{panelId:n,panelIndex:r,layerIndex:l.index,band:te(c.anchor)},box:u,lineHeightPx:Bi(c,a)})}return s}function Er(e,t,n,r){return n.height<=Tt(e,t,r)}function Tt(e,t,n){const r=e.y+e.height/2<=t.y+t.height/2;return n*(r?Ji:Yi)}function Et(e,t,n){return n.height<=Tt(e.box,t.box,e.lineHeightPx)+Tt(t.box,e.box,t.lineHeightPx)}function Lr(e){const{ctx:t,panelIds:n,panelWidth:r,panelHeight:o}=e,a={x:0,y:0,width:r*n.length,height:o};t?.save();try{return ts(e,a)}finally{t?.restore()}}function es(e){const{ctx:t,panelIds:n,panelWidth:r,panelHeight:o,captionLayers:a}=e,i={x:0,y:0,width:r*n.length,height:o};t?.save();try{return n.flatMap((s,l)=>Ee(t,a[s]??[],s,l,r,o,i)).map(({ref:s,box:l})=>({ref:s,box:l}))}finally{t?.restore()}}function ts(e,t){const{ctx:n,panelIds:r,panelWidth:o,panelHeight:a,captionLayers:i}=e,s=r.flatMap((h,v)=>Ee(n,i[h]??[],h,v,o,a,t)),l=[];for(const h of e.phones){const m=e.clip==="panel"||e.clip===void 0&&h.clipToFrame===!0?{x:h.panelIndex*o,y:0,width:o,height:a}:t,b={x:h.x,y:h.y,width:h.width,height:h.height},y=Ve(b,m);y&&l.push({shotId:h.shotId,box:y,frame:b,silhouette:e.silhouettes?.[h.shotId],layoutHeight:h.height})}const c=[];for(let h=0;h<s.length;h++)for(let v=h+1;v<s.length;v++){const m=re(s[h].box,s[v].box);m&&c.push({a:s[h].ref,b:s[v].ref,overlap:m,depthFrac:a>0?m.height/a:0,inkUncertain:Et(s[h],s[v],m)})}const u=[];for(const h of s)for(const v of l){const m=Je(h.box,v);m&&u.push({caption:h.ref,shotId:v.shotId,overlap:m,depthFrac:a>0?m.height/a:0,inkUncertain:Er(h.box,v.box,m,h.lineHeightPx)})}const f=[];for(let h=0;h<l.length;h++)for(let v=h+1;v<l.length;v++){const m=l[h],b=l[v],y=re(m.box,b.box);if(!y)continue;const w=[],x=Math.max(m.layoutHeight,b.layoutHeight),P=Math.min(m.layoutHeight,b.layoutHeight);P>0&&x/P>=Ki&&w.push("scale");const S=e.looks?.[m.shotId],A=e.looks?.[b.shotId],O=!!S&&!!A;S&&A&&(En(Ln(S),Ln(A))>=Tn&&w.push("angle"),En(U("roll",S.roll),U("roll",A.roll))>=Tn&&w.push("roll"));const I=Math.min(m.box.width*m.box.height,b.box.width*b.box.height);f.push({shotIdA:m.shotId,shotIdB:b.shotId,overlap:y,coverage:I>0?y.width*y.height/I:0,deliberate:w.length>0,signals:w,anglesKnown:O})}const d=new Set;for(const h of c)h.a.band&&d.add(h.a.panelId),h.b.band&&d.add(h.b.panelId);for(const h of u)h.caption.band&&d.add(h.caption.panelId);const p=[],g=[];return r.forEach((h,v)=>{if(!d.has(h))return;const m=rs(e,h,v,t,s,l);m!==null&&g.push({panelId:h,maxWidth:m});const b=os(e,h,v,t,s,l);b&&p.push(b)}),{captionsMeasurable:n!=null,captionOverlaps:c,captionDeviceOverlaps:u,deviceOverlaps:f,suggestions:p,widthSuggestions:g,hasWarning:c.length>0||u.length>0||f.some(h=>!h.deliberate)}}function ns(e){const{ctx:t,panelIds:n,panelWidth:r,panelHeight:o}=e,a={x:0,y:0,width:r*n.length,height:o},i=[];for(const c of e.phones){const f=e.clip==="panel"||e.clip===void 0&&c.clipToFrame===!0?{x:c.panelIndex*r,y:0,width:r,height:o}:a,d={x:c.x,y:c.y,width:c.width,height:c.height},p=Ve(d,f);p&&i.push({shotId:c.shotId,box:p,frame:d,silhouette:e.silhouettes?.[c.shotId],layoutHeight:c.height})}const s=(c,u,f)=>{const d=n.indexOf(c);if(d<0||!t)return[];t.save();try{return Ee(t,u,c,d,r,o,f?a:{x:-1e9,y:-1e9,width:2e9,height:2e9})}finally{t.restore()}},l=new Map(n.map(c=>[c,s(c,e.captionLayers[c]??[],!0)]));return{measurable:t!=null,commit(c,u){l.set(c,s(c,u,!0))},probe(c,u){const f=s(c,u,!1),d=f.flatMap(h=>{const v=Ve(h.box,a);return v?[{...h,box:v}]:[]}),p=n.flatMap(h=>h===c?[]:l.get(h)??[]),g=[];for(const h of d){for(const v of i){const m=Je(h.box,v);m&&g.push({layerIndex:h.ref.layerIndex,band:h.ref.band,against:"device",samePanelBand:!1,depthFrac:o>0?m.height/o:0,inkUncertain:Er(h.box,v.box,m,h.lineHeightPx)})}for(const v of p){const m=re(h.box,v.box);m&&g.push({layerIndex:h.ref.layerIndex,band:h.ref.band,against:"caption",samePanelBand:!1,depthFrac:o>0?m.height/o:0,inkUncertain:Et(h,v,m)})}}for(let h=0;h<d.length;h++)for(let v=h+1;v<d.length;v++){const m=re(d[h].box,d[v].box);if(!m)continue;const b=o>0?m.height/o:0,y=Et(d[h],d[v],m);for(const[w,x]of[[d[h],d[v]],[d[v],d[h]]])g.push({layerIndex:w.ref.layerIndex,band:w.ref.band,against:"caption",samePanelBand:x.ref.band,depthFrac:b,inkUncertain:y})}return{hits:g,boxes:f.map(h=>({layerIndex:h.ref.layerIndex,band:h.ref.band,box:h.box}))}}}}function rs(e,t,n,r,o,a){const i=e.captionLayers[t]??[];if(!i.length||i.some(u=>!te(u.anchor)))return null;const s=o.filter(u=>u.ref.panelId!==t).map(u=>u.box),l=u=>a.some(f=>Je(u,f))||s.some(f=>re(u,f)),c=Math.min(...i.map(u=>u.maxWidth));for(let u=Math.ceil(c*100)-1;u>=10;u--){const f=u/100,d=Ee(e.ctx,i.map(p=>({...p,maxWidth:f})),t,n,e.panelWidth,e.panelHeight,r);if(d.length&&d.every((p,g)=>!l(p.box)&&!d.slice(g+1).some(h=>re(p.box,h.box))))return f}return null}function os(e,t,n,r,o,a){const i=e.captionLayers[t]??[],s=i.flatMap((f,d)=>te(f.anchor)&&f.text.trim()?[d]:[]);if(s.length===0||!(Math.min(...s.map(f=>i[f].sizePt))>xe))return null;const c=o.filter(f=>!(f.ref.panelId===t&&f.ref.band)).map(f=>f.box),u=f=>a.some(d=>Je(f,d))||c.some(d=>re(f,d));for(let f=1;f<=Qi;f++){const d=Math.round((1-f*Zi)*100)/100,p=new Map(s.map(m=>[m,i[m].sizePt*d]));if(Math.min(...Array.from(p.values()))<xe)return null;const g=i.map((m,b)=>{const y=p.get(b);return y===void 0?m:{...m,sizePt:y}});if(Ee(e.ctx,g,t,n,e.panelWidth,e.panelHeight,r).filter(m=>m.ref.band).every(m=>!u(m.box)))return{panelId:t,scale:d,layers:s.map(m=>({layerIndex:m,fromSizePt:i[m].sizePt,toSizePt:p.get(m)}))}}return null}Ge.colorways;class Fr{frame=[];back=[];accent=[];allBody=[];model;scene;renderer;profile;envTexture=null;constructor(t,n,r,o){this.model=t,this.scene=n,this.renderer=r,this.profile=Yt(o);const{frame:a,back:i,accent:s}=this.profile.body;t.traverse(l=>{const c=l;if(!c.isMesh)return;(Array.isArray(c.material)?c.material:[c.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 r=n instanceof V?n:new V(n);t.forEach(o=>{o.color=r.clone(),o.needsUpdate=!0})}setColorway(t){if(t==="custom")return;const n=this.profile.colorways.find(r=>r.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 V(t),r=n.clone().lerp(new V(16777215),.2),o=n.clone().multiplyScalar(.6);this.paint(this.frame,n),this.paint(this.back,r),this.paint(this.accent,o)}setFinish(t){const n=Number.isFinite(t)?Math.max(0,Math.min(1,t)):0;this.finishMaterials.forEach(r=>{r.userData.baseRoughness===void 0&&(r.userData.baseRoughness=r.roughness);const o=r.userData.baseRoughness;r.roughness=o*(1-n),r.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(r=>{const o=r;o.clearcoat=n,o.clearcoatRoughness=.1,o.needsUpdate=!0})}upgradeFinishToPhysical(){this.clearcoatUpgraded=!0;const t=new Map;for(const r of Array.from(new Set(this.finishMaterials))){const o=new oo;o.color.copy(r.color),o.metalness=r.metalness,o.roughness=r.roughness,o.map=r.map,o.normalMap=r.normalMap,o.normalScale.copy(r.normalScale),o.roughnessMap=r.roughnessMap,o.metalnessMap=r.metalnessMap,o.aoMap=r.aoMap,o.aoMapIntensity=r.aoMapIntensity,o.emissive.copy(r.emissive),o.emissiveMap=r.emissiveMap,o.emissiveIntensity=r.emissiveIntensity,o.envMapIntensity=r.envMapIntensity,o.transparent=r.transparent,o.opacity=r.opacity,o.alphaTest=r.alphaTest,o.side=r.side,o.flatShading=r.flatShading,o.vertexColors=r.vertexColors,o.name=r.name,o.userData={...r.userData},o.clearcoat=0,t.set(r,o)}this.model.traverse(r=>{const o=r;if(o.isMesh)if(Array.isArray(o.material))o.material=o.material.map(a=>t.get(a)??a);else{const a=t.get(o.material);a&&(o.material=a)}});const n=r=>r.map(o=>t.get(o)??o);this.frame=n(this.frame),this.back=n(this.back),this.allBody=n(this.allBody)}environmentMap(){if(!this.envTexture){const t=new po(this.renderer);this.envTexture=t.fromScene(new ao,.04).texture,t.dispose()}return this.envTexture}setClay(t){const n=Ja.find(o=>o.id===t),r=n?new V(n.color):new V(t);this.allBody.forEach(o=>{o.userData.clayStashedMap===void 0&&(o.userData.clayStashedMap=o.map),o.color=r.clone(),o.metalness=0,o.roughness=.85,o.map=null,o.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}}var D=Uint8Array,$=Uint16Array,Zt=Int32Array,Ze=new D([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Qe=new D([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Lt=new D([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Rr=function(e,t){for(var n=new $(31),r=0;r<31;++r)n[r]=t+=1<<e[r-1];for(var o=new Zt(n[30]),r=1;r<30;++r)for(var a=n[r];a<n[r+1];++a)o[a]=a-n[r]<<5|r;return{b:n,r:o}},zr=Rr(Ze,2),Nr=zr.b,Ft=zr.r;Nr[28]=258,Ft[258]=28;var Br=Rr(Qe,0),as=Br.b,Fn=Br.r,Rt=new $(32768);for(var z=0;z<32768;++z){var ae=(z&43690)>>1|(z&21845)<<1;ae=(ae&52428)>>2|(ae&13107)<<2,ae=(ae&61680)>>4|(ae&3855)<<4,Rt[z]=((ae&65280)>>8|(ae&255)<<8)>>1}var ne=(function(e,t,n){for(var r=e.length,o=0,a=new $(t);o<r;++o)e[o]&&++a[e[o]-1];var i=new $(t);for(o=1;o<t;++o)i[o]=i[o-1]+a[o-1]<<1;var s;if(n){s=new $(1<<t);var l=15-t;for(o=0;o<r;++o)if(e[o])for(var c=o<<4|e[o],u=t-e[o],f=i[e[o]-1]++<<u,d=f|(1<<u)-1;f<=d;++f)s[Rt[f]>>l]=c}else for(s=new $(r),o=0;o<r;++o)e[o]&&(s[o]=Rt[i[e[o]-1]++]>>15-e[o]);return s}),le=new D(288);for(var z=0;z<144;++z)le[z]=8;for(var z=144;z<256;++z)le[z]=9;for(var z=256;z<280;++z)le[z]=7;for(var z=280;z<288;++z)le[z]=8;var ke=new D(32);for(var z=0;z<32;++z)ke[z]=5;var is=ne(le,9,0),ss=ne(le,9,1),ls=ne(ke,5,0),cs=ne(ke,5,1),st=function(e){for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},X=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(t&7)&n},lt=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(t&7)},Qt=function(e){return(e+7)/8|0},_r=function(e,t,n){return(n==null||n>e.length)&&(n=e.length),new D(e.subarray(t,n))},ds=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],K=function(e,t,n){var r=new Error(t||ds[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,K),!n)throw r;return r},us=function(e,t,n,r){var o=e.length,a=0;if(!o||t.f&&!t.l)return n||new D(0);var i=!n,s=i||t.i!=2,l=t.i;i&&(n=new D(o*3));var c=function(ge){var ye=n.length;if(ge>ye){var he=new D(Math.max(ye*2,ge));he.set(n),n=he}},u=t.f||0,f=t.p||0,d=t.b||0,p=t.l,g=t.d,h=t.m,v=t.n,m=o*8;do{if(!p){u=X(e,f,1);var b=X(e,f+1,3);if(f+=3,b)if(b==1)p=ss,g=cs,h=9,v=5;else if(b==2){var P=X(e,f,31)+257,S=X(e,f+10,15)+4,A=P+X(e,f+5,31)+1;f+=14;for(var O=new D(A),I=new D(19),k=0;k<S;++k)I[Lt[k]]=X(e,f+k*3,7);f+=S*3;for(var C=st(I),M=(1<<C)-1,T=ne(I,C,1),k=0;k<A;){var E=T[X(e,f,M)];f+=E&15;var y=E>>4;if(y<16)O[k++]=y;else{var F=0,L=0;for(y==16?(L=3+X(e,f,3),f+=2,F=O[k-1]):y==17?(L=3+X(e,f,7),f+=3):y==18&&(L=11+X(e,f,127),f+=7);L--;)O[k++]=F}}var B=O.subarray(0,P),R=O.subarray(P);h=st(B),v=st(R),p=ne(B,h,1),g=ne(R,v,1)}else K(1);else{var y=Qt(f)+4,w=e[y-4]|e[y-3]<<8,x=y+w;if(x>o){l&&K(0);break}s&&c(d+w),n.set(e.subarray(y,x),d),t.b=d+=w,t.p=f=x*8,t.f=u;continue}if(f>m){l&&K(0);break}}s&&c(d+131072);for(var J=(1<<h)-1,j=(1<<v)-1,q=f;;q=f){var F=p[lt(e,f)&J],W=F>>4;if(f+=F&15,f>m){l&&K(0);break}if(F||K(2),W<256)n[d++]=W;else if(W==256){q=f,p=null;break}else{var H=W-254;if(W>264){var k=W-257,N=Ze[k];H=X(e,f,(1<<N)-1)+Nr[k],f+=N}var Z=g[lt(e,f)&j],ue=Z>>4;Z||K(3),f+=Z&15;var R=as[ue];if(ue>3){var N=Qe[ue];R+=lt(e,f)&(1<<N)-1,f+=N}if(f>m){l&&K(0);break}s&&c(d+131072);var fe=d+H;if(d<R){var Le=a-R,Fe=Math.min(R,fe);for(Le+d<0&&K(3);d<Fe;++d)n[d]=r[Le+d]}for(;d<fe;++d)n[d]=n[d-R]}}t.l=p,t.p=q,t.b=d,t.f=u,p&&(u=1,t.m=h,t.d=g,t.n=v)}while(!u);return d!=n.length&&i?_r(n,0,d):n.subarray(0,d)},oe=function(e,t,n){n<<=t&7;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8},be=function(e,t,n){n<<=t&7;var r=t/8|0;e[r]|=n,e[r+1]|=n>>8,e[r+2]|=n>>16},ct=function(e,t){for(var n=[],r=0;r<e.length;++r)e[r]&&n.push({s:r,f:e[r]});var o=n.length,a=n.slice();if(!o)return{t:jr,l:0};if(o==1){var i=new D(n[0].s+1);return i[n[0].s]=1,{t:i,l:1}}n.sort(function(x,P){return x.f-P.f}),n.push({s:-1,f:25001});var s=n[0],l=n[1],c=0,u=1,f=2;for(n[0]={s:-1,f:s.f+l.f,l:s,r:l};u!=o-1;)s=n[n[c].f<n[f].f?c++:f++],l=n[c!=u&&n[c].f<n[f].f?c++:f++],n[u++]={s:-1,f:s.f+l.f,l:s,r:l};for(var d=a[0].s,r=1;r<o;++r)a[r].s>d&&(d=a[r].s);var p=new $(d+1),g=zt(n[u-1],p,0);if(g>t){var r=0,h=0,v=g-t,m=1<<v;for(a.sort(function(P,S){return p[S.s]-p[P.s]||P.f-S.f});r<o;++r){var b=a[r].s;if(p[b]>t)h+=m-(1<<g-p[b]),p[b]=t;else break}for(h>>=v;h>0;){var y=a[r].s;p[y]<t?h-=1<<t-p[y]++-1:++r}for(;r>=0&&h;--r){var w=a[r].s;p[w]==t&&(--p[w],++h)}g=t}return{t:new D(p),l:g}},zt=function(e,t,n){return e.s==-1?Math.max(zt(e.l,t,n+1),zt(e.r,t,n+1)):t[e.s]=n},Rn=function(e){for(var t=e.length;t&&!e[--t];);for(var n=new $(++t),r=0,o=e[0],a=1,i=function(l){n[r++]=l},s=1;s<=t;++s)if(e[s]==o&&s!=t)++a;else{if(!o&&a>2){for(;a>138;a-=138)i(32754);a>2&&(i(a>10?a-11<<5|28690:a-3<<5|12305),a=0)}else if(a>3){for(i(o),--a;a>6;a-=6)i(8304);a>2&&(i(a-3<<5|8208),a=0)}for(;a--;)i(o);a=1,o=e[s]}return{c:n.subarray(0,r),n:t}},we=function(e,t){for(var n=0,r=0;r<t.length;++r)n+=e[r]*t[r];return n},Dr=function(e,t,n){var r=n.length,o=Qt(t+2);e[o]=r&255,e[o+1]=r>>8,e[o+2]=e[o]^255,e[o+3]=e[o+1]^255;for(var a=0;a<r;++a)e[o+a+4]=n[a];return(o+4+r)*8},zn=function(e,t,n,r,o,a,i,s,l,c,u){oe(t,u++,n),++o[256];for(var f=ct(o,15),d=f.t,p=f.l,g=ct(a,15),h=g.t,v=g.l,m=Rn(d),b=m.c,y=m.n,w=Rn(h),x=w.c,P=w.n,S=new $(19),A=0;A<b.length;++A)++S[b[A]&31];for(var A=0;A<x.length;++A)++S[x[A]&31];for(var O=ct(S,7),I=O.t,k=O.l,C=19;C>4&&!I[Lt[C-1]];--C);var M=c+5<<3,T=we(o,le)+we(a,ke)+i,E=we(o,d)+we(a,h)+i+14+3*C+we(S,I)+2*S[16]+3*S[17]+7*S[18];if(l>=0&&M<=T&&M<=E)return Dr(t,u,e.subarray(l,l+c));var F,L,B,R;if(oe(t,u,1+(E<T)),u+=2,E<T){F=ne(d,p,0),L=d,B=ne(h,v,0),R=h;var J=ne(I,k,0);oe(t,u,y-257),oe(t,u+5,P-1),oe(t,u+10,C-4),u+=14;for(var A=0;A<C;++A)oe(t,u+3*A,I[Lt[A]]);u+=3*C;for(var j=[b,x],q=0;q<2;++q)for(var W=j[q],A=0;A<W.length;++A){var H=W[A]&31;oe(t,u,J[H]),u+=I[H],H>15&&(oe(t,u,W[A]>>5&127),u+=W[A]>>12)}}else F=is,L=le,B=ls,R=ke;for(var A=0;A<s;++A){var N=r[A];if(N>255){var H=N>>18&31;be(t,u,F[H+257]),u+=L[H+257],H>7&&(oe(t,u,N>>23&31),u+=Ze[H]);var Z=N&31;be(t,u,B[Z]),u+=R[Z],Z>3&&(be(t,u,N>>5&8191),u+=Qe[Z])}else be(t,u,F[N]),u+=L[N]}return be(t,u,F[256]),u+L[256]},fs=new Zt([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),jr=new D(0),hs=function(e,t,n,r,o,a){var i=a.z||e.length,s=new D(r+i+5*(1+Math.ceil(i/7e3))+o),l=s.subarray(r,s.length-o),c=a.l,u=(a.r||0)&7;if(t){u&&(l[0]=a.r>>3);for(var f=fs[t-1],d=f>>13,p=f&8191,g=(1<<n)-1,h=a.p||new $(32768),v=a.h||new $(g+1),m=Math.ceil(n/3),b=2*m,y=function(et){return(e[et]^e[et+1]<<m^e[et+2]<<b)&g},w=new Zt(25e3),x=new $(288),P=new $(32),S=0,A=0,O=a.i||0,I=0,k=a.w||0,C=0;O+2<i;++O){var M=y(O),T=O&32767,E=v[M];if(h[T]=E,v[M]=T,k<=O){var F=i-O;if((S>7e3||I>24576)&&(F>423||!c)){u=zn(e,l,0,w,x,P,A,I,C,O-C,u),I=S=A=0,C=O;for(var L=0;L<286;++L)x[L]=0;for(var L=0;L<30;++L)P[L]=0}var B=2,R=0,J=p,j=T-E&32767;if(F>2&&M==y(O-j))for(var q=Math.min(d,F)-1,W=Math.min(32767,O),H=Math.min(258,F);j<=W&&--J&&T!=E;){if(e[O+B]==e[O+B-j]){for(var N=0;N<H&&e[O+N]==e[O+N-j];++N);if(N>B){if(B=N,R=j,N>q)break;for(var Z=Math.min(j,N-2),ue=0,L=0;L<Z;++L){var fe=O-j+L&32767,Le=h[fe],Fe=fe-Le&32767;Fe>ue&&(ue=Fe,E=fe)}}}T=E,E=h[T],j+=T-E&32767}if(R){w[I++]=268435456|Ft[B]<<18|Fn[R];var ge=Ft[B]&31,ye=Fn[R]&31;A+=Ze[ge]+Qe[ye],++x[257+ge],++P[ye],k=O+B,++S}else w[I++]=e[O],++x[e[O]]}}for(O=Math.max(O,k);O<i;++O)w[I++]=e[O],++x[e[O]];u=zn(e,l,c,w,x,P,A,I,C,O-C,u),c||(a.r=u&7|l[u/8|0]<<3,u-=7,a.h=v,a.p=h,a.i=O,a.w=k)}else{for(var O=a.w||0;O<i+c;O+=65535){var he=O+65535;he>=i&&(l[u/8|0]=c,he=i),u=Dr(l,u+1,e.subarray(O,he))}a.i=i}return _r(s,0,r+Qt(u)+o)},Ur=function(){var e=1,t=0;return{p:function(n){for(var r=e,o=t,a=n.length|0,i=0;i!=a;){for(var s=Math.min(i+2655,a);i<s;++i)o+=r+=n[i];r=(r&65535)+15*(r>>16),o=(o&65535)+15*(o>>16)}e=r,t=o},d:function(){return e%=65521,t%=65521,(e&255)<<24|(e&65280)<<8|(t&255)<<8|t>>8}}},ps=function(e,t,n,r,o){if(!o&&(o={l:1},t.dictionary)){var a=t.dictionary.subarray(-32768),i=new D(a.length+e.length);i.set(a),i.set(e,a.length),e=i,o.w=a.length}return hs(e,t.level==null?6:t.level,t.mem==null?o.l?Math.ceil(Math.max(8,Math.min(13,Math.log(e.length)))*1.5):20:12+t.mem,n,r,o)},Wr=function(e,t,n){for(;n;++t)e[t]=n,n>>>=8},ms=function(e,t){var n=t.level,r=n==0?0:n<6?1:n==9?3:2;if(e[0]=120,e[1]=r<<6|(t.dictionary&&32),e[1]|=31-(e[0]<<8|e[1])%31,t.dictionary){var o=Ur();o.p(t.dictionary),Wr(e,2,o.d())}},gs=function(e,t){return((e[0]&15)!=8||e[0]>>4>7||(e[0]<<8|e[1])%31)&&K(6,"invalid zlib data"),(e[1]>>5&1)==1&&K(6,"invalid zlib data: "+(e[1]&32?"need":"unexpected")+" dictionary"),(e[1]>>3&4)+2};function ys(e,t){t||(t={});var n=Ur();n.p(e);var r=ps(e,t,t.dictionary?6:2,4);return ms(r,t),Wr(r,r.length-4,n.d()),r}function vs(e,t){return us(e.subarray(gs(e),-4),{i:2},t,t)}var bs=typeof TextDecoder<"u"&&new TextDecoder,ws=0;try{bs.decode(jr,{stream:!0}),ws=1}catch{}const Nt=[137,80,78,71,13,10,26,10],xs=2,Is=6;function Bt(e,t){return(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])>>>0}function qe(e,t,n){e[t]=n>>>24&255,e[t+1]=n>>>16&255,e[t+2]=n>>>8&255,e[t+3]=n&255}function Hr(e,t){return String.fromCharCode(e[t],e[t+1],e[t+2],e[t+3])}function Gr(e){if(!e||e.length<29)return null;for(let t=0;t<Nt.length;t+=1)if(e[t]!==Nt[t])return null;return Hr(e,12)!=="IHDR"?null:{width:Bt(e,16),height:Bt(e,20),bitDepth:e[24],colorType:e[25],interlace:e[28]}}const Ss=(()=>{const e=[];for(let t=0;t<256;t+=1){let n=t;for(let r=0;r<8;r+=1)n=n&1?3988292384^n>>>1:n>>>1;e.push(n>>>0)}return e})();function As(e,t,n){let r=4294967295;for(let o=t;o<n;o+=1)r=Ss[(r^e[o])&255]^r>>>8;return(r^4294967295)>>>0}function dt(e,t){const n=new Uint8Array(12+t.length);qe(n,0,t.length);for(let r=0;r<4;r+=1)n[4+r]=e.charCodeAt(r);return n.set(t,8),qe(n,8+t.length,As(n,4,8+t.length)),n}function $r(e,t,n){const r=e+t-n,o=Math.abs(r-e),a=Math.abs(r-t),i=Math.abs(r-n);return o<=a&&o<=i?e:a<=i?t:n}function ks(e,t,n,r){const o=new Uint8Array(t*n);for(let a=0;a<t;a+=1){const i=e[a*(n+1)],s=a*(n+1)+1,l=a*n,c=l-n;for(let u=0;u<n;u+=1){const f=u>=r?o[l+u-r]:0,d=a>0?o[c+u]:0,p=a>0&&u>=r?o[c+u-r]:0,g=e[s+u];let h;if(i===0)h=g;else if(i===1)h=g+f;else if(i===2)h=g+d;else if(i===3)h=g+(f+d>>1);else if(i===4)h=g+$r(f,d,p);else throw new Error("opaquePng: unknown PNG filter "+i);o[l+u]=h&255}}return o}function Ps(e,t,n){const o=t*3,a=new Uint8Array(n*(o+1)),i=new Uint8Array(o),s=new Uint8Array(o);for(let l=0;l<n;l+=1){const c=l*o,u=c-o;let f=0,d=1/0;for(let p=0;p<5;p+=1){let g=0;for(let h=0;h<o;h+=1){const v=h>=3?e[c+h-3]:0,m=l>0?e[u+h]:0,b=l>0&&h>=3?e[u+h-3]:0,y=e[c+h];let w;if(p===0?w=y:p===1?w=y-v:p===2?w=y-m:p===3?w=y-(v+m>>1):w=y-$r(v,m,b),w&=255,i[h]=w,g+=w<128?w:256-w,g>=d)break}g<d&&(d=g,f=p,s.set(i))}a[l*(o+1)]=f,a.set(s,l*(o+1)+1)}return a}function Os(e){const t=Gr(e);if(!t)throw new Error("opaquePng: not a PNG");if(t.colorType!==Is)return e;if(t.bitDepth!==8||t.interlace!==0)throw new Error("opaquePng: only 8-bit non-interlaced RGBA can be rewritten");const n=t.width,r=t.height,o=[];let a=0;const i=[],s=[];let l=!1,c=8;for(;c+8<=e.length;){const y=Bt(e,c),w=Hr(e,c+4),x=c+12+y;if(x>e.length)throw new Error("opaquePng: truncated "+w+" chunk");if(w==="IDAT"?(l=!0,o.push(e.subarray(c+8,c+8+y)),a+=y):w!=="IHDR"&&w!=="IEND"&&w!=="tRNS"&&(l?s:i).push(e.subarray(c,x)),c=x,w==="IEND")break}const u=new Uint8Array(a);let f=0;for(let y=0;y<o.length;y+=1)u.set(o[y],f),f+=o[y].length;const d=ks(vs(u),r,n*4,4),p=new Uint8Array(n*r*3);for(let y=0,w=0;y<d.length;y+=4,w+=3){const x=d[y+3];x===255?(p[w]=d[y],p[w+1]=d[y+1],p[w+2]=d[y+2]):(p[w]=Math.round(d[y]*x/255),p[w+1]=Math.round(d[y+1]*x/255),p[w+2]=Math.round(d[y+2]*x/255))}const g=new Uint8Array(13);qe(g,0,n),qe(g,4,r),g[8]=8,g[9]=xs;const h=[Uint8Array.from(Nt),dt("IHDR",g)];for(let y=0;y<i.length;y+=1)h.push(i[y]);h.push(dt("IDAT",ys(Ps(p,n,r),{level:6})));for(let y=0;y<s.length;y+=1)h.push(s[y]);h.push(dt("IEND",new Uint8Array(0)));let v=0;for(let y=0;y<h.length;y+=1)v+=h[y].length;const m=new Uint8Array(v);let b=0;for(let y=0;y<h.length;y+=1)m.set(h[y],b),b+=h[y].length;return m}const Nn=1.35;class Vr{materials=[];glassOverlays=[];screenMesh=null;flatPlane=null;texture=null;stock=[];appliedBytes=null;flatScreenOn=!1;profile;model;passRestore=[];constructor(t,n){this.profile=Yt(n),this.model=t;const r=this.profile.screen.material;t.traverse(o=>{const a=o;if(!a.isMesh)return;(Array.isArray(a.material)?a.material:[a.material]).forEach(s=>{const l=s;l&&l.name===r&&!this.materials.includes(l)&&(this.materials.push(l),this.screenMesh=a)})}),this.stock=this.materials.map(o=>({map:o.map,emissiveMap:o.emissiveMap})),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 y=this.flatPlane.material;y.map?.dispose(),y.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 r=n.max.x-n.min.x,o=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,l=(n.max.z+n.min.z)/2,c=o<=r&&o<=a?"y":a<=r&&a<=o?"z":"x",u=this.texture.clone();u.needsUpdate=!0,u.colorSpace=nn,u.flipY=!1,u.center.set(.5,.5),u.wrapS=Re,u.wrapT=Re;const{coverFill:f,coverCornerRatio:d,coverRepeat:p}=this.profile.screen;u.repeat.set(p.x,p.y);const g=c==="x"?a:r,h=c==="z"||c==="x"?o:a,v=Math.min(g,h)*f*d,m=Cs(g*f,h*f,v),b=new mo(m,new io({map:u,emissive:new V(16777215),emissiveMap:u,emissiveIntensity:Nn,color:new V(0),toneMapped:!1,side:go,depthTest:!0,depthWrite:!0,polygonOffset:!0,polygonOffsetFactor:-4,polygonOffsetUnits:-4}));c==="y"?(b.rotation.x=-Math.PI/2,b.position.set(i,n.max.y,l)):c==="x"?(b.rotation.y=Math.PI/2,b.position.set(n.max.x,s,l)):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(l=>{l&&!this.materials.includes(l)&&n(l)})});return}this.glassOverlays.forEach(n);const r=a=>new vo({blending:xo,blendEquation:wo,blendSrc:rn,blendDst:rn,depthTest:!0,depthWrite:!0,side:a?.side??bo,polygonOffset:a?.polygonOffset??!1,polygonOffsetFactor:a?.polygonOffsetFactor??0,polygonOffsetUnits:a?.polygonOffsetUnits??0}),o=(a,i)=>{const s=a.material;if(!(Array.isArray(s)?s:[s]).some(i))return;const l=[],c=u=>{if(!i(u))return u;const f=r(u);return l.push(f),f};a.material=Array.isArray(s)?s.map(c):c(s),this.passRestore.push(()=>{a.material=s,l.forEach(u=>u.dispose())})};this.model.traverse(a=>{const i=a;i.isMesh&&(i===this.flatPlane?o(i,()=>!0):o(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 r=n.boundingBox,o=n.attributes.position,a=n.attributes.uv;if(!r||!o||!a)return null;const i=r.getSize(new ce),s=r.getCenter(new ce),l=i.y<=i.x&&i.y<=i.z?"y":i.z<=i.x&&i.z<=i.y?"z":"x",[c,u]=l==="y"?["x","z"]:l==="z"?["x","y"]:["z","y"],f=this.profile.screen.coverFill,{repeat:d}=this.profile.screen,p={};for(const b of[-1,1])for(const y of[-1,1]){const w=new ce;w[l]=r.max[l],w[c]=s[c]+b*i[c]*f/2,w[u]=s[u]+y*i[u]*f/2;let x=-1,P=1/0;for(let I=0;I<o.count;I++){const k=Math.hypot(o.getComponent(I,"xyz".indexOf(c))-w[c],o.getComponent(I,"xyz".indexOf(u))-w[u]);k<P&&(P=k,x=I)}if(x<0)return null;const S=.5+(a.getX(x)-.5)*d.x,A=.5+(a.getY(x)-.5)*d.y;if(S===.5||A===.5)return null;const O=`${A<.5?"t":"b"}${S<.5?"l":"r"}`;if(p[O])return null;p[O]=w}const{tl:g,tr:h,br:v,bl:m}=p;return!g||!h||!v||!m?null:(t.updateWorldMatrix(!0,!1),{tl:g.applyMatrix4(t.matrixWorld),tr:h.applyMatrix4(t.matrixWorld),br:v.applyMatrix4(t.matrixWorld),bl:m.applyMatrix4(t.matrixWorld)})}get cornerRatio(){return this.profile.screen.coverCornerRatio}restoreScreen(){this.prepareScreen()}clearWallpaper(){this.texture&&(this.materials.forEach((t,n)=>{t.map=this.stock[n]?.map??null,t.emissiveMap=this.stock[n]?.emissiveMap??null}),this.texture.dispose(),this.texture=null,this.appliedBytes=null,this.prepareScreen(),this.flatScreenOn&&this.setFlatScreen(!0))}prepareScreen(){this.materials.forEach(t=>{t.color=new V(0),t.emissive=new V(16777215),t.emissiveIntensity=1,t.roughness=1,t.metalness=0,t.needsUpdate=!0})}dimGlassOverlay(t){t.traverse(n=>{const r=n;if(!r.isMesh)return;(Array.isArray(r.material)?r.material:[r.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"}),r=URL.createObjectURL(n),o=this.texture;return new Promise((a,i)=>{const s=new Image;s.onload=()=>{try{const l=document.createElement("canvas");l.width=s.naturalWidth,l.height=s.naturalHeight;const c=l.getContext("2d");if(!c)throw new Error("2D context unavailable for wallpaper blit");c.drawImage(s,0,0);const u=new so(l);u.colorSpace=nn,u.flipY=!1,u.center.set(.5,.5),u.wrapS=Re,u.wrapT=Re,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),o?.dispose(),URL.revokeObjectURL(r),a()}catch(l){URL.revokeObjectURL(r),i(l)}},s.onerror=()=>{URL.revokeObjectURL(r),i(new Error("wallpaper image failed to decode"))},s.src=r})}lightScreen(t){this.materials.forEach(n=>{n.map=t,n.emissiveMap=t,n.emissive=new V(16777215),n.emissiveIntensity=Nn,n.color=new V(0),n.needsUpdate=!0})}}function Cs(e,t,n){const r=e/2,o=t/2,a=Math.min(n,r,o),i=new lo;i.moveTo(-r+a,-o),i.lineTo(r-a,-o),i.quadraticCurveTo(r,-o,r,-o+a),i.lineTo(r,o-a),i.quadraticCurveTo(r,o,r-a,o),i.lineTo(-r+a,o),i.quadraticCurveTo(-r,o,-r,o-a),i.lineTo(-r,-o+a),i.quadraticCurveTo(-r,-o,-r+a,-o);const s=new co(i,16),l=s.attributes.position,c=new Float32Array(l.count*2);for(let u=0;u<l.count;u++)c[u*2]=(l.getX(u)+r)/e,c[u*2+1]=(l.getY(u)+o)/t;return s.setAttribute("uv",new yo(c,2)),s}function Pe(e){return`build-shot-${e+1}`}function en(e){const t=[...e.panelIds??[]];for(const n of e.shots)t.includes(n.panelId)||t.push(n.panelId);return t}function Ms(e,t){return{...e,panelIds:t.map(n=>n.id)}}const Ts=1900,Es=2800;function Ls(e){return new Promise((t,n)=>{e.toBlob(r=>{if(!r)return n(new Error("canvas toBlob returned null"));r.arrayBuffer().then(o=>t(new Uint8Array(o)),n)},"image/png")})}async function qr(e,t,n,r={}){await qi();const o=en(e);if(r.panelViewport!==void 0&&(!Number.isInteger(r.panelViewport)||r.panelViewport<0||r.panelViewport>=o.length))throw new Error("buildStrip: panel viewport is outside the strip");const a=o.map(d=>({id:d})),i=e.shots.map((d,p)=>({id:Pe(p),panelId:d.panelId,frameNodeId:"",frameName:`screen-${p+1}`,bytes:t.screens[p]??null,look:d.look,thumb:null,thumbStale:!1,...se(d)})),l={panelPresetId:Me(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:r.renderScale,locale:n},c=r.onProgress??(()=>{});let u=r.refs,f=null;if(!u){const d=ko(e.panelPresetId);f=Ar(Ts,Es);const p=await kr(f,d);u={stage:f,device:new Fr(p,f.scene,f.renderer,d),screen:new Vr(p,d)}}try{const d=await Ai(u.stage,u,i,a,l,c);if(!d)throw new Error("buildStrip: nothing renderable (no shots)");const p=document.createElement("canvas");try{const g={...r.panelViewport!==void 0?{panelViewport:r.panelViewport}:{},...r.clip?{clip:r.clip}:{},...r.backgroundViewport?{backgroundViewport:r.backgroundViewport}:{}},h=await Ti(p,d,Object.keys(g).length>0?g:void 0),v=d.panelWidth,m=d.panelHeight,b=p.getContext("2d");if(!b)throw new Error("buildStrip: 2D context unavailable");b.save(),r.panelViewport!==void 0&&b.translate(-r.panelViewport*v,0),Di(b,o,v,m,t.captionText??{}),b.restore();const y=Lr({phones:d.phones,panelIds:o,captionLayers:t.captionText??{},panelWidth:v,panelHeight:m,ctx:b,looks:Object.fromEntries(i.map(I=>[I.id,I.look])),clip:r.clip,silhouettes:h.silhouettes}),w=r.renderScale&&r.renderScale>0&&r.renderScale<1?r.renderScale:1,x=[],P=r.panelViewport??0,S=r.panelViewport===void 0?d.count:P+1;for(let I=P;I<S;I++){const k=document.createElement("canvas");k.width=Math.max(1,Math.round(v*w)),k.height=Math.max(1,Math.round(m*w));const C=k.width,M=k.height;try{const T=k.getContext("2d",{alpha:!1});if(!T)throw new Error("buildStrip: 2D context unavailable");T.fillStyle="#000",T.fillRect(0,0,C,M),T.drawImage(p,r.panelViewport===void 0?I*v:0,0,v,m,0,0,C,M);const E=await Ls(k),F=Gr(E)?Os(E):E;x.push({index:I,bytes:F,width:C,height:M})}finally{k.width=0,k.height=0}}const A=d.phones.map(({shotId:I,panelIndex:k,x:C,y:M,width:T,height:E})=>({shotId:I,panelIndex:k,x:C,y:M,width:T,height:E})),O={panelIds:[...o],panelWidth:v,panelHeight:m,phones:d.phones.map(({shotId:I,panelIndex:k,x:C,y:M,width:T,height:E,clipToFrame:F})=>({shotId:I,panelIndex:k,x:C,y:M,width:T,height:E,...F===!0?{clipToFrame:!0}:{}})),silhouettes:h.silhouettes,...r.clip?{clip:r.clip}:{}};return{panels:x,layout:y,phones:A,geometry:O}}finally{p.width=0,p.height=0}}finally{f&&f.dispose()}}function Fs(e){if(!e||e.length===0)return null;const t=Array.from(new Set(e.flatMap(r=>r.frames))).sort((r,o)=>r-o).map(r=>`Frame ${r+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 _t=.005,Rs=.02,zs=12;function ut(e){return Math.max(1,Math.round(e*100))}function ft(e){return`${e.kind}:${e.frames.join(",")}:${e.anchored}`}function Ns(e,t){const n=new Map(e.suggestions.map(i=>[i.panelId,i.scale])),r=new Map((e.widthSuggestions??[]).map(i=>[i.panelId,i.maxWidth])),o=[];for(const i of e.captionOverlaps){if(i.inkUncertain||i.depthFrac<_t)continue;const[s,l]=i.a.band===i.b.band?[i.a,i.b]:i.a.band?[i.a,i.b]:[i.b,i.a],c=ht([t.frameOfPanel(s.panelId),t.frameOfPanel(l.panelId)]);c.length!==0&&o.push({kind:"caption-caption",frames:c,depthPct:ut(i.depthFrac),anchored:!i.a.band||!i.b.band,...Bn(n,s.band?s.panelId:null),..._n(r,s.band?s.panelId:null)})}for(const i of e.captionDeviceOverlaps){if(i.inkUncertain||i.depthFrac<_t)continue;const s=ht([t.frameOfPanel(i.caption.panelId),t.frameOfShot(i.shotId)]);s.length!==0&&o.push({kind:"caption-device",frames:s,depthPct:ut(i.depthFrac),anchored:!i.caption.band,...Bn(n,i.caption.band?i.caption.panelId:null),..._n(r,i.caption.band?i.caption.panelId:null)})}for(const i of e.deviceOverlaps){if(i.deliberate||i.coverage<Rs)continue;const s=ht([t.frameOfShot(i.shotIdA),t.frameOfShot(i.shotIdB)]);s.length!==0&&o.push({kind:"device-device",frames:s,depthPct:ut(i.coverage),anchored:!1})}const a=new Map;for(const i of o){const s=a.get(ft(i));s?i.depthPct>s.depthPct?a.set(ft(i),{...i,clearAtScale:i.clearAtScale??s.clearAtScale,clearAtMaxWidth:i.clearAtMaxWidth??s.clearAtMaxWidth}):s.clearAtScale==null&&i.clearAtScale!=null&&(s.clearAtScale=i.clearAtScale):a.set(ft(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,zs).sort((i,s)=>i.frames[0]-s.frames[0]||i.kind.localeCompare(s.kind))}function ht(e){const[t,...n]=e;return t<0?[]:[t,...n.filter(r=>r>=0&&r!==t)]}function Bn(e,t){const n=t==null?void 0:e.get(t);return n==null?{}:{clearAtScale:Math.round(n*100)/100}}function _n(e,t){const n=t==null?void 0:e.get(t);return n==null?{}:{clearAtMaxWidth:n}}function Bs(e,t){if(t.length===0)return e;const n=e.captionStyles;if(!n)return e;const r={};for(const[o,a]of Object.entries(n))r[o]=a.map(i=>({...i}));for(const o of t){const a=r[o.panelId];if(a)for(const i of o.layers){const s=a[i.layerIndex];s&&(s.sizePt=i.toSizePt)}}return{...e,captionStyles:r}}function pt(e){return e.frames.map(t=>`frame ${t+1}`).join(" + ")}function _s(e,t,n){if(!e.captionsMeasurable)return null;const r=Ns(e,t);if(r.length===0)return null;const o=r.filter(c=>c.kind==="device-device"),a=r.filter(c=>c.kind!=="device-device"&&c.clearAtScale==null);if(o.length>0||a.length>0||!n){const c=[];o.length>0&&c.push(`${o.map(pt).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)c.push(u.anchored?`${pt(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.`:`${pt(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 c.length===0&&c.push("The rendered look was not available here, so no corrected look could be built."),{findings:r,note:`No corrected look is offered. ${c.join(" ")}`}}const i=new Set(r.filter(c=>c.kind!=="device-device").map(c=>c.frames[0])),s=e.suggestions.filter(c=>i.has(t.frameOfPanel(c.panelId))),l=s.flatMap(c=>{const u=t.frameOfPanel(c.panelId)+1;return c.layers.map(f=>`frame ${u} layer ${f.layerIndex+1}: sizePt ${f.fromSizePt} → ${f.toSizePt}`)}).join("; ");return{findings:r,correctedLook:Bs(n,s),note:`\`layout.correctedLook\` is this same look with every caption shrunk to the largest size that was verified to clear the overlap (${l}). Nothing here is applied for you — re-render with it, or show the user the finding and let them decide. On render 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 Ds(e){return String(Math.max(-100,Math.min(100,e*35)))}const js=["roll","deviceSize","hOffset","vOffset","finish","clearcoat"];function Dn(e){if(!e||typeof e!="object")return{};const t={...e};for(const n of js)typeof t[n]=="number"&&(t[n]=String(t[n]));return t}function Us(e){const{subtitle:t,sizePt:n,maxWidth:r,...o}=e;return{...o,...n!==void 0?{sizePt:Number(n)}:{},...r!==void 0?{maxWidth:Number(r)}:{}}}function jn(e){const t={};for(const[n,r]of Object.entries(e))r!==void 0&&(t[n]=r);return t}function mt(e,t,n){const r={};return e&&t.forEach((o,a)=>{const i=n[a];i!==void 0&&e[o]!==void 0&&(r[i]=e[o])}),r}function Ws(e){const t=Array.isArray(e.sourcePanelIds)&&e.sourcePanelIds.length===e.slotSizes.length?e.sourcePanelIds:null,n=t?e.slotSizes.map(I=>Number.isInteger(I)&&I>0?I:0):e.slotSizes.filter(I=>Number.isInteger(I)&&I>0),r=n.map((I,k)=>`panel-${k+1}`);let o={};const a=e.look&&typeof e.look=="object"?e.look:null,i=e.style??null,s=a&&Array.isArray(a.shots)?a.shots:[],l=s.length>0,c=i?Dn(i.shotLook):null,u=!l&&typeof i?.layout=="string"?yr(i.layout):void 0,f=I=>{if(!u||I<2)return null;const k={...u.shotLook,...c},C={..._,...k};return Ta({...u,shotLook:k},Array.from({length:I},()=>C))},d=[];let p=0;n.forEach((I,k)=>{const C=f(I);for(let M=0;M<I;M++){const T=l?Dn(s[p]?.look??s[0]?.look??{}):{...c,...C?.[M]},E=T.hOffset!==void 0&&T.hOffset!==null?String(T.hOffset):Ds(M),{z:F}=l?se(s[p]):{};d.push({panelId:r[k],look:{..._,...T,hOffset:E},...F!==void 0?{z:F}:{}}),p++}});let g={},h={},v={},m="gradient",b=Eo,y=Lo,w="vertical",x,P,S=!0,A=!1;if(a){m=a.bgMode==="perPanel"?"perPanel":"gradient";const I=We({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:b,gradientTo:typeof a.gradientTo=="string"?a.gradientTo:y,gradientDir:a.gradientDir==="horizontal"?"horizontal":w});x=I.stops,P=I.angle,{gradientFrom:b,gradientTo:y,gradientDir:w}=Ue(I),a.shadow===!1&&(S=!1),a.floorReflection===!0&&(A=!0);const k=t?[...t]:[];if(!t)for(const C of s){const M=typeof C?.panelId=="string"?C.panelId:null;M&&!k.includes(M)&&k.push(M)}g=mt(a.panelColors,k,r),h=mt(Xt(a.captionStyles),k,r),v=mt(sr(a.panelBackgrounds),k,r)}else if(i){const I=i.background??{};m=I.mode==="perPanel"?"perPanel":"gradient";const k=We({gradientStops:I.stops,gradientAngle:I.angle,gradientFrom:b,gradientTo:y,gradientDir:w});x=k.stops,P=k.angle,{gradientFrom:b,gradientTo:y,gradientDir:w}=Ue(k),I.shadow===!1&&(S=!1),I.floorReflection===!0&&(A=!0),Array.isArray(I.panelColors)&&I.panelColors.forEach((C,M)=>{typeof C=="string"&&C&&r[M]!==void 0&&(g[r[M]]=C)})}if(i&&Array.isArray(i.captions)){const I=h,k=(E,F)=>({...I[E]?.[F]??{}}),C={},M={};i.captions.forEach((E,F)=>{const L=r[F];if(!(L===void 0||E===null||E===void 0)){if(Array.isArray(E)){const B=E.filter(R=>!!R&&typeof R=="object"&&typeof R.text=="string"&&R.text.trim()!=="").map((R,J)=>It(k(L,J),jn(Us(R))));B.length>0&&(M[L]=B)}else if(typeof E=="object"){const{text:B,subtitle:R,sizePt:J,maxWidth:j,...q}=E;C[L]=It(k(L,0),jn({...q,...J!==void 0?{sizePt:Number(J)}:{},...j!==void 0?{maxWidth:Number(j)}:{}})),typeof B=="string"&&B.trim()&&(M[L]={headline:B,...typeof R=="string"&&R?{subtitle:R}:{}})}}});const T=Ye({[Y]:M},dr(C));h=ur(T),o=Ae(T)}return{look:{panelPresetId:e.panelPresetId??(typeof a?.panelPresetId=="string"?a.panelPresetId:void 0)??"r69",bgMode:m,gradientStops:x,gradientAngle:P,gradientFrom:b,gradientTo:y,gradientDir:w,panelColors:g,shadow:S,floorReflection:A,panelBackgrounds:v,captionStyles:h,shots:d,...t?{panelIds:r}:{}},panelIds:r,captionText:o}}function Hs(e){const t=e?.trim();return t?/\.(png|jpe?g|webp)$/i.test(t)?t:`${t}.png`:null}function Gs(e,t){const n=new Map;return e.map((r,o)=>{const a=Hs(t?.[o]);if(!a)return`screen-${o+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 $s(e){const{look:t,panelIds:n,captionText:r,locale:o,shotNames:a,outputs:i,locales:s,baseLocale:l}=e,c=n.map(d=>({id:d})),u=Gs(t.shots,a),f=t.shots.map((d,p)=>({id:`shot-${p+1}`,panelId:d.panelId,frameNodeId:u[p],frameName:u[p],bytes:null,look:d.look,thumb:null,thumbStale:!0}));return xr({shots:f,panels:c,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}:{},...l?{baseLocale:l}:{},captionText:r&&Object.keys(r).length>0?{[o||Y]:r}:{}})}const Vs=1900,qs=2800,Un=new Map;async function Xs(e){e("booting headless stage + loading model (once)…");const t=Ar(Vs,qs),n=await ai(t);return{stage:t,device:new Fr(n,t.scene,t.renderer),screen:new Vr(n)}}function Xr(e,t,n={}){let r=Un.get(e);r||(r={refs:Xs(n.onProgress??(()=>{})),tail:Promise.resolve()},Un.set(e,r));const{refs:o}=r,a=r.tail.then(async()=>t(await o));return r.tail=a.catch(()=>{}),a}function Kr(e,t){return t===e.baseLocale||!e.locales||e.locales.includes(t)}function Wn(e,t){const n={...e,...t.set};for(const r of t.unset??[])delete n[r];return n}function gt(e,t){if(t.edits.length===0)return e;const n=Object.keys(e.captionText).filter(f=>!Kr(e,f)),r=n.length===0?e.captionText:Object.fromEntries(Object.entries(e.captionText).filter(([f])=>!n.includes(f))),o=t.edits.filter(f=>f.locale===void 0||f.locale===e.baseLocale),a=new Map;for(const f of o)a.set(f.panelId,[...a.get(f.panelId)??[],f]);let i=ca(r,Array.from(a.keys()),e.baseLocale,(f,d)=>{const p=a.get(d);if(!(!f?.length||!p))return f.map((g,h)=>p.filter(v=>v.layerIndex===h).reduce(Wn,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((p,g)=>g===f.layerIndex?Wn(p,f):p)}})}if(i===r)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 l={...e.frameTemplates},c=new Set(t.edits.map(f=>f.panelId));let u=!1;for(const f of Array.from(c)){const d=e.frameTemplates[f];if(!d)continue;const p=za({...e,shots:e.shots,captionSlotIds:e.captionSlotIds??{},frameTemplates:e.frameTemplates},f);!p||p.modified||(l[f]=Ra({shots:e.shots,captionText:i,captionSlotIds:e.captionSlotIds??{},baseLocale:e.baseLocale},f,d.templateId),u=!0)}return u?{...s,frameTemplates:l}:s}const Ks=.4,Hn=.02,Ys=.02,Gn=[.04,.02],_e=.5,Oe=e=>Math.round(e*100)/100;function Js(e){const t=new Map,n=r=>{const o=`${e.font}\0${e.textBaseline}\0${r}`;let a=t.get(o);return a||(a=e.measureText(r),t.set(o,a)),a};return new Proxy(e,{get(r,o){if(o==="measureText")return n;const a=Reflect.get(r,o,r);return typeof a=="function"?a.bind(r):a},set(r,o,a){return Reflect.set(r,o,a,r)}})}const Dt=e=>!e.inkUncertain&&e.depthFrac>=_t;function Yr(e){if(e.boxAlign)return e.boxAlign;if(e.bandCenter===void 0)return"center";const t=lr(e),n=Te(e),r=t+n/2;return Math.abs(r-.5)<.01?"center":r<.5?"left":"right"}function Zs(e,t,n){return e.map((r,o)=>{if(!t.has(o))return r;let a={...r};const i=Te(r);return n.width<i-1e-9&&(delete a.widthMode,a.maxWidth=Oe(n.width)),n.align&&n.align!==Yr(r)&&(a=It(a,{boxAlign:n.align})),n.flip&&(a.band==="bottom"?delete a.band:a.band="bottom"),n.inset!==null&&(a.bandInset=n.inset),a})}function Qs(e,t,n){return e.hits.some(r=>t.has(r.layerIndex)&&Dt(r))?!1:e.boxes.every(({layerIndex:r,box:o})=>!t.has(r)||o.y>=-_e&&o.y+o.height<=n.height+_e&&o.x>=n.left-_e&&o.x+o.width<=n.right+_e)}function $n(e,t,n){const r=n?[e]:[];for(let o=Oe(e-Hn);o>=t-1e-9;o=Oe(o-Hn))r.push(o);return r}function el(e,t,n){const r=Array.from(t),o=r.map(p=>Te(e[p])),a=Math.max(...o),i=Math.min(Ks,Math.min(...o)),s=$n(a,i,!1).map(p=>({width:p,align:null,flip:!1,inset:null}));if(n)return s;const l=Yr(e[r[0]]),c=[l,...["left","right","center"].filter(p=>p!==l)],u=e[r[0]].bandInset??.06,f=Gn.filter(p=>p<u-1e-9),d=(p,g,h)=>{for(const v of $n(a,i,!0))s.push({width:v,align:p,flip:g,inset:h})};return c.slice(1).forEach(p=>d(p,!1,null)),f.forEach(p=>c.forEach(g=>d(g,!1,p))),[null,...Gn].forEach(p=>c.forEach(g=>d(g,!0,p))),s}function tl(e,t,n,r,o){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:{...o?{locale:o}:{},panelId:n,layerIndex:r,set:a,...i.length>0?{unset:i}:{}}}function nl(e,t){const n=h=>({state:e,resolution:{edits:[]},measured:h,remaining:[],remainingSentence:null});if(!t.ctx||t.panelIds.length===0)return n(!1);const r=Js(t.ctx),o=h=>e.panels?e.panels.findIndex(v=>v.id===h):t.panelIds.indexOf(h),a=h=>{const v=t.panelIds.indexOf(h);return{left:v*t.panelWidth,right:(v+1)*t.panelWidth,height:t.panelHeight}},i=h=>ns({phones:t.phones,panelIds:t.panelIds,captionLayers:h,panelWidth:t.panelWidth,panelHeight:t.panelHeight,ctx:r,...t.clip?{clip:t.clip}:{},...t.silhouettes?{silhouettes:t.silhouettes}:{}}),s=(h,v)=>new Set(h.flatMap((m,b)=>te(m.anchor)&&m.text.trim()&&!(v&&m.widthMode==="fill")?[b]:[])),l=(h,v,m,b)=>{const y=i(v),w=[];for(const x of t.panelIds){const P=v[x];if(!P?.length||!b(x))continue;const S=s(P,m);if(S.size===0)continue;const A=a(x);if(y.probe(x,P).hits.some(I=>S.has(I.layerIndex)&&Dt(I)))for(const I of el(P,S,m)){const k=Zs(P,S,I);if(Qs(y.probe(x,k),S,A)){y.commit(x,k),k.forEach((C,M)=>{const T=tl(P[M],C,x,M,m?h:void 0);T&&w.push(T)});break}}}return w},c=e.baseLocale,u=(h,v)=>t.family?sa(h.captionText,h.outputCaptions,t.family,v,c):Ae(h.captionText,v,c),f=h=>Object.keys(h.captionText).filter(v=>Kr(h,v)),d=h=>{const v=new Map,m=f(h);for(const b of m.length>0?m:[c]){const y=u(h,b),w=i(y);for(const x of t.panelIds){const P=y[x];if(!P?.length)continue;const S=s(P,!1),A=o(x);if(!(A<0))for(const O of w.probe(x,P).hits){if(!S.has(O.layerIndex)||!Dt(O))continue;const I=O.against==="device"?"caption-device":"caption-caption",k=Math.max(1,Math.round(O.depthFrac*100)),C=`${I}:${A}`,M=v.get(C);(!M||M.depthPct<k)&&v.set(C,{kind:I,frames:[A],depthPct:k,anchored:!1})}}}return Array.from(v.values()).sort((b,y)=>b.frames[0]-y.frames[0]||b.kind.localeCompare(y.kind))},p=h=>{const v=l(c,u(h,c),!1,()=>!0);let m=gt(h,{edits:v});const b=[];for(const y of f(m)){if(y===c)continue;const w=m.captionText[y]??{};b.push(...l(y,u(m,y),!0,x=>w[x]!==void 0))}return b.length>0&&(m=gt(m,{edits:b})),{state:m,edits:[...v,...b],remaining:d(m)}};let g=p(e);if(g.remaining.length>0){const h=e.captionText[c]??{},v=Object.keys(h).flatMap(m=>h[m].flatMap((b,y)=>te(b.anchor)&&b.text.trim()&&b.sizePt>xe?[{panelId:m,layerIndex:y,sizePt:b.sizePt}]:[]));for(let m=1;v.length>0;m++){const b=Oe(1-m*Ys),y=v.map(({panelId:x,layerIndex:P,sizePt:S})=>({panelId:x,layerIndex:P,set:{sizePt:Math.max(xe,Oe(S*b))}})),w=p(gt(e,{edits:y}));if(w.remaining.length===0){g={...w,edits:[...y,...w.edits]};break}if(v.every(({sizePt:x})=>x*b<=xe))break}}return{state:g.state,resolution:{edits:g.edits},measured:!0,remaining:g.remaining,remainingSentence:Fs(g.remaining)}}function rl(e,t){const n=Math.max(e.x,t.x),r=Math.max(e.y,t.y),o=Math.min(e.x+e.width,t.x+t.width),a=Math.min(e.y+e.height,t.y+t.height);return o<=n||a<=r?null:{x:n,y:r,width:o-n,height:a-r}}const yt=e=>Math.max(0,e.width)*Math.max(0,e.height);function vt(e,t,n,r,o){const a=yt(r),i=Math.min(yt(n[0]),yt(n[1]));return{kind:e,subjects:t,objectBounds:n,intersectionBounds:r,overlapPx:a,overlapPct:i>0?Math.round(a/i*1e4)/100:0,...o}}const bt=e=>({kind:"caption",panelId:e.panelId,panelIndex:e.panelIndex,layerIndex:e.layerIndex});function ol(e){const{geometry:t}=e,{panelIds:n,panelWidth:r,panelHeight:o}=t,a={width:r,height:o},i=n.length,s=r*i,l={x:0,y:0,width:s,height:o},c=new Map,u=t.phones.map(m=>{const b=t.clip==="panel"||t.clip===void 0&&m.clipToFrame===!0,y={x:m.x,y:m.y,width:m.width,height:m.height},w=rl(y,b?pn(m.panelIndex,a):l);return c.set(m.shotId,w),{shotId:m.shotId,rect:y,panelIndex:m.panelIndex,panelIndices:w?pa(w,r,i):[],z:se(e.layering?.[m.shotId]).z??0,hidden:!1,clipToFrame:m.clipToFrame===!0}});for(const m of e.hiddenDevices??[])u.push({shotId:m.shotId,rect:ma(m.placement,a,m.cropAspect),panelIndex:m.placement.panelIndex,panelIndices:[],z:se(m).z??0,hidden:!0,clipToFrame:!1});const f=e.ctx??null,d=e.captionLayers??{},p=Lr({phones:t.phones,panelIds:n,captionLayers:d,panelWidth:r,panelHeight:o,ctx:f,looks:e.looks,clip:t.clip,silhouettes:t.silhouettes}),g=new Map(es({ctx:f,panelIds:n,captionLayers:d,panelWidth:r,panelHeight:o}).map(({ref:m,box:b})=>[`${m.panelId}\0${m.layerIndex}`,b])),h=m=>g.get(`${m.panelId}\0${m.layerIndex}`),v=[];for(const m of p.deviceOverlaps){const b=c.get(m.shotIdA),y=c.get(m.shotIdB);!b||!y||v.push(vt("device-device",[{kind:"device",shotId:m.shotIdA},{kind:"device",shotId:m.shotIdB}],[b,y],m.overlap,{deliberate:m.deliberate}))}for(const m of p.captionDeviceOverlaps){const b=h(m.caption),y=c.get(m.shotId);!b||!y||v.push(vt("caption-device",[bt(m.caption),{kind:"device",shotId:m.shotId}],[b,y],m.overlap,{inkUncertain:m.inkUncertain}))}for(const m of p.captionOverlaps){const b=h(m.a),y=h(m.b);!b||!y||v.push(vt("caption-caption",[bt(m.a),bt(m.b)],[b,y],m.overlap,{inkUncertain:m.inkUncertain}))}return{panelWidth:r,panelHeight:o,stripWidth:s,panels:n.map((m,b)=>({panelId:m,index:b,bounds:pn(b,a)})),devices:u,overlaps:v,captionsMeasured:f!=null}}function G(e){console.log("[render]",e)}function Jr(e){const t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return n}function tn(e){let t="";for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);return btoa(t)}function al(e){return new Promise((t,n)=>{e.toBlob(async r=>{if(!r)return n(new Error("toBlob null"));t(tn(new Uint8Array(await r.arrayBuffer())))},"image/png")})}function Zr(e,t){const n=en(t),r=new Map(t.shots.map((a,i)=>[Pe(i),n.indexOf(a.panelId)])),o=_s(e.layout,{frameOfPanel:a=>n.indexOf(a),frameOfShot:a=>r.get(a)??-1},t);if(o)return{layout:{findings:o.findings,...o.correctedLook?{correctedLook:o.correctedLook}:{}},layoutNote:o.note}}async function Qr(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 r=n.getContext("2d");let o=0;for(const a of t)r.drawImage(a,o,0),o+=a.width,a.close();return{base64:await al(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(y=>Array.isArray(y)?y:[y]),{look:r,panelIds:o,captionText:a}=Ws({slotSizes:n.map(y=>y.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(Jr),s=Array.isArray(t.captionLayers)&&o[0]?{[o[0]]:t.captionLayers}:a,l=t.preview?.25:1;G(`buildStrip (${n.length} panel${n.length===1?"":"s"}${t.locale?`, ${t.locale}`:""})…`);let c=0;const u=await Xr("visible",y=>(c=performance.now(),qr(r,{screens:i,captionText:s},t.locale,{refs:y,renderScale:l,onProgress:w=>G(" "+w),...t.clip?{clip:t.clip}:{},...Number.isInteger(t.panelViewport)?{panelViewport:t.panelViewport}:{},...t.backgroundViewport?{backgroundViewport:t.backgroundViewport}:{}})),{onProgress:G});G("encoding panels + stitching the strip preview…");const f=u.panels.map(y=>tn(y.bytes)),d=await Qr(u.panels),p=Me(r.panelPresetId),g=Math.round(performance.now()-c),h=Zr(u,r),v=u.layout.captionsMeasurable,m=Array.isArray(t.screenshotNames)?t.screenshotNames.flat():void 0,b=t.buildRecord?$s({look:r,panelIds:o,captionText:a,locale:t.locale,shotNames:m,outputs:t.outputs}):void 0;return G(`done: ${u.panels.length} panels, strip ${d.width}x${d.height}, ${g}ms`),{ok:!0,ms:g,count:u.panels.length,panelPresetId:p.id,panelWidth:p.width,panelHeight:p.height,stripWidth:d.width,stripHeight:d.height,panels:f,stripBase64:d.base64,preview:l<1,...b?{projectRecord:b}:{},...h??{},layoutMeasured:v,...t.layerBoxes?{layerBoxes:u.phones.map(({shotId:y,...w})=>({shot:r.shots.findIndex((x,P)=>Pe(P)===y),...w}))}:{}}}catch(n){const r=n&&n.stack?n.stack:String(n);return G("ERROR: "+r),{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=Ba(JSON.stringify(t.projectFile));if(!n)throw new Error("renderProject: the saved project could not be restored (wrong schema or malformed record)");const r=t.locale||n.baseLocale||n.locales?.[0]||"en-US",o=de(n.shots,n.panels),a=St(t.variant||{},n.baseLocale),i=new Map((t.screenManifest||[]).map(S=>[`${S.shotId} ${dn(St(S.variant||{},n.baseLocale))}`,S])),s=(S,A)=>i.get(`${S} ${dn(A)}`),l=o.map(S=>fr(s,S.id,a,Jo,n.baseLocale)),c=o.map((S,A)=>({frameName:S.frameName,matched:l[A].value!==void 0,requestedVariant:a,resolvedAt:l[A].resolvedAt,inherited:l[A].inherited,...l[A].value?.source?{source:l[A].value.source}:{}})),u=l.map(({value:S})=>S?.bytes?Jr(S.bytes):null),f=Ae(n.captionText,r,n.baseLocale),d=Ms(Da({...n,selectedShotId:null,panelPresetId:t.panelPresetId??n.panelPresetId,captionText:{[r]:f}}),n.panels),p=t.preview?.25:1;G(`renderProject (${o.length} shot${o.length===1?"":"s"}, ${r})…`);let g=0;const h=await Xr("visible",S=>(g=performance.now(),qr(d,{screens:u,captionText:f},r,{refs:S,renderScale:p,onProgress:A=>G(" "+A)})),{onProgress:G});G("encoding panels + stitching the strip preview…");const v=h.panels.map(S=>tn(S.bytes)),m=await Qr(h.panels),b=Me(d.panelPresetId),y=Math.round(performance.now()-g),w=Zr(h,d),x=h.layout.captionsMeasurable,P=t.settleCaptions?il(n,h.geometry,a.family):null;return G(`done: ${h.panels.length} panels, strip ${m.width}x${m.height}, ${y}ms`),{ok:!0,ms:y,count:h.panels.length,panelPresetId:b.id,panelWidth:b.width,panelHeight:b.height,stripWidth:m.width,stripHeight:m.height,panels:v,stripBase64:m.base64,preview:p<1,shots:c,locale:r,...w??{},layoutMeasured:x,...t.layoutGeometry?{layoutGeometry:h.geometry}:{},...P?P.wire:{},...t.stripGeometry?{stripGeometry:sl(h,d,o,P?.state?Ae(P.state.captionText,r,P.state.baseLocale):f)}:{}}}catch(n){const r=n&&n.stack?n.stack:String(n);return G("ERROR: "+r),{ok:!1,error:String(n&&n.message?n.message:n)}}};let Vn=null;function eo(){return Vn??=document.createElement("canvas").getContext("2d"),Vn}function il(e,t,n){if(!t)return{wire:{captionResolution:{edits:[]},captionsMeasured:!1,captionRemaining:null},state:null};const r=nl(e,{...t,...n?{family:n}:{},ctx:eo()});return{wire:{captionResolution:r.resolution,captionsMeasured:r.measured,captionRemaining:r.remainingSentence},state:r.state}}function sl(e,t,n,r){const o=en(t),a=new Map(n.map((f,d)=>[Pe(d),f.id])),i={},s={},l=[];t.shots.forEach((f,d)=>{const p=Pe(d);s[p]=f.look,typeof f.z=="number"&&(i[p]={z:f.z}),f.hidden===!0&&l.push({shotId:p,placement:{panelIndex:Math.max(0,o.indexOf(f.panelId)),hOffset:Number.parseFloat(f.look.hOffset)||0,vOffset:Number.parseFloat(f.look.vOffset)||0,deviceSize:Number.parseFloat(f.look.deviceSize)||100},...typeof f.z=="number"?{z:f.z}:{}})});const c=ol({geometry:e.geometry,layering:i,hiddenDevices:l,captionLayers:r,ctx:eo(),looks:s}),u=f=>a.get(f)??f;return{...c,devices:c.devices.map(f=>({...f,shotId:u(f.shotId)})),overlaps:c.overlaps.map(f=>({...f,subjects:f.subjects.map(d=>d.kind==="device"?{...d,shotId:u(d.shotId)}:d)}))}}window.__RENDER_READY=!0;G("harness ready ✓");
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <title>shotops-mcp headless render harness</title>
6
- <script type="module" crossorigin src="./assets/index-DsyBFowq.js"></script>
6
+ <script type="module" crossorigin src="./assets/index-CuLGhrQs.js"></script>
7
7
  <link rel="modulepreload" crossorigin href="./assets/three-webgl-BAyyruEx.js">
8
8
  <link rel="modulepreload" crossorigin href="./assets/three-addons-zF8BveTt.js">
9
9
  </head>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shotops-mcp",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "The bundle-emitting MCP server over the @engine/@sync spine. Exposes ShotOps tools to ChatGPT, Claude Code, Cursor, and CI over Streamable HTTP with OAuth or personal API tokens. Hosted and MCP tool paths never accept, store, or forward a store-signing credential; the explicit local release CLI validates the user's existing key directly with Apple and records only its path. Renders via headless Playwright Chromium, the engine's native non-browser habitat (same path as mockup-mcp). Also ships as a free LOCAL stdio server (`npx shotops-mcp`) — same render, on your own machine, no account needed.",