@liveroom-tech/react-immersive 6.2.1 → 6.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/AnimationsTab-IKAAKT3P.mjs +1 -0
  2. package/dist/AnnotationsTab-NEJIXCOM.mjs +1 -0
  3. package/dist/CinematicTab-TIQXCPFE.mjs +1 -0
  4. package/dist/ConfigureTab-NYRMOFW4.mjs +6 -0
  5. package/dist/RulesTab-2U4MFYOZ.mjs +1 -0
  6. package/dist/SequencesTab-LTMJTB76.mjs +1 -0
  7. package/dist/SequencesTab-O7USMDFP.css +1 -0
  8. package/dist/{StreamingTilesModel-6Z7SIC2J.mjs → StreamingTilesModel-IM2DDWO5.mjs} +1 -1
  9. package/dist/binding-builder.css +1 -1
  10. package/dist/binding-builder.d.mts +3 -3
  11. package/dist/binding-builder.d.ts +3 -3
  12. package/dist/binding-builder.js +45 -45
  13. package/dist/binding-builder.mjs +1 -1
  14. package/dist/{chunk-25WC5KDO.mjs → chunk-2LGQKX6Z.mjs} +1 -1
  15. package/dist/chunk-37QOMZW6.mjs +1 -0
  16. package/dist/chunk-3PLML3PO.mjs +1 -0
  17. package/dist/chunk-5C4H7SRF.mjs +1 -0
  18. package/dist/chunk-IT2PUTJS.mjs +1 -0
  19. package/dist/chunk-LEOHZ5HM.mjs +69 -0
  20. package/dist/chunk-RSUXTWM6.mjs +1 -0
  21. package/dist/{chunk-3OCHN3CA.mjs → chunk-SOAUR4DL.mjs} +1 -1
  22. package/dist/chunk-SXN3YYD3.mjs +1 -0
  23. package/dist/chunk-WU3SQZGD.mjs +3 -0
  24. package/dist/{chunk-UTVFRMYW.mjs → chunk-XKJQC3N5.mjs} +2 -2
  25. package/dist/exportSceneMesh-MSQIMBFF.mjs +1 -0
  26. package/dist/hosted.css +1 -1
  27. package/dist/hosted.d.mts +5 -3
  28. package/dist/hosted.d.ts +5 -3
  29. package/dist/hosted.js +44 -44
  30. package/dist/hosted.mjs +1 -1
  31. package/dist/index.css +1 -1
  32. package/dist/index.d.mts +4 -4
  33. package/dist/index.d.ts +4 -4
  34. package/dist/index.js +42 -42
  35. package/dist/index.mjs +1 -1
  36. package/dist/{modelFileResolver-CVmON8hg.d.mts → modelFileResolver-Bq4pW9vc.d.mts} +39 -29
  37. package/dist/{modelFileResolver-CVmON8hg.d.ts → modelFileResolver-Bq4pW9vc.d.ts} +39 -29
  38. package/dist/{modelViewerProps-CIY4nsNY.d.mts → modelViewerProps-BnrJO5DK.d.ts} +2 -1
  39. package/dist/{modelViewerProps-BBnZTFO-.d.ts → modelViewerProps-wjBT4fks.d.mts} +2 -1
  40. package/dist/{publicProps-BARVwXu7.d.ts → publicProps-BZPMIRwj.d.ts} +1 -1
  41. package/dist/{publicProps-n0Yvr_Km.d.mts → publicProps-CW5X_HFh.d.mts} +1 -1
  42. package/dist/simple-model-viewer.css +1 -1
  43. package/dist/simple-model-viewer.d.mts +2 -2
  44. package/dist/simple-model-viewer.d.ts +2 -2
  45. package/dist/simple-model-viewer.js +5 -5
  46. package/dist/simple-model-viewer.mjs +1 -1
  47. package/dist/utils.d.mts +4 -4
  48. package/dist/utils.d.ts +4 -4
  49. package/dist/utils.js +1 -1
  50. package/dist/utils.mjs +1 -1
  51. package/package.json +1 -1
  52. package/dist/AnimationsTab-NUJTEMZ5.mjs +0 -1
  53. package/dist/AnnotationsTab-OHRVWRKI.mjs +0 -1
  54. package/dist/CinematicTab-IJAY2BS6.mjs +0 -1
  55. package/dist/ConfigureTab-UQRRATCY.mjs +0 -6
  56. package/dist/RulesTab-YVBZGJZX.mjs +0 -1
  57. package/dist/SequencesTab-IC5LWQ6N.css +0 -1
  58. package/dist/SequencesTab-VZKEKAUG.mjs +0 -1
  59. package/dist/chunk-7OVEHDDE.mjs +0 -1
  60. package/dist/chunk-AL6UIGWP.mjs +0 -1
  61. package/dist/chunk-KYXJG3TX.mjs +0 -1
  62. package/dist/chunk-LD7QWHB4.mjs +0 -3
  63. package/dist/chunk-RKDATTUM.mjs +0 -1
  64. package/dist/chunk-UHRJ2RBF.mjs +0 -1
  65. package/dist/chunk-YKDDNX2D.mjs +0 -69
  66. package/dist/exportSceneMesh-YJFOLFHS.mjs +0 -1
@@ -0,0 +1,3 @@
1
+ import{a as pc,b as bc}from"./chunk-E24EFHB5.mjs";import{a as En}from"./chunk-FXV4CLAK.mjs";import{a as On,b as pt,c as go,d as lc,e as Fa,g as re,h as de,i as dc,j as cc,k as I,l as fe,m as bt,n as uc,o as St,p as kt,q as tn}from"./chunk-SXN3YYD3.mjs";import{a as Oa,c as Ad,d as fr,e as Fd,h as Vd,i as _d,j as Kd,k as Gd,l as qd,m as Wd,n as Yd,o as Jd,p as Da,q as Xd,r as Qd,t as ec,u as tc,v as sc}from"./chunk-LEOHZ5HM.mjs";import{a as Id,b as Ia,c as lt,d as Dd,e as Ot,f as en,g as zd,h as dt,i as Ye}from"./chunk-FGAJ2UT7.mjs";import{e as jd,f as Ld,h as La}from"./chunk-SOAUR4DL.mjs";import{H as Ed,O as $d,a as ld,i as Aa,k as Oo,x as br,y as Od}from"./chunk-XKJQC3N5.mjs";import{a as Hd}from"./chunk-37YITTIK.mjs";import{b as Rd}from"./chunk-2AJK643D.mjs";import{c as Td}from"./chunk-5C4H7SRF.mjs";import{b as et}from"./chunk-3PLML3PO.mjs";import{$ as Nn,B as cr,Ba as hr,C as Zo,Ca as Ud,Da as Zd,Ea as za,F as Qo,Fa as oc,G as xd,Ga as nc,H as vd,Ha as ic,I as yd,Ia as rc,Ja as ac,Y as ur,a as lr,ca as Cd,e as li,n as dd,p as cd,pa as Ea,q as ud,qa as mr,r as pd,ra as gr,s as bd,t as md,ta as ja,u as gd,ua as Nd,v as ci,w as fd,x as Ao,y as hd,za as ui}from"./chunk-2LGQKX6Z.mjs";import{e as dr}from"./chunk-LX3GXQNU.mjs";import{p as pr}from"./chunk-7JCFNZJM.mjs";import{h as Rn,i as Qt,j as _t,k as di}from"./chunk-37QOMZW6.mjs";import{b as Pd,e as Bd}from"./chunk-KFLS7GI6.mjs";import{c as wd,d as Sd,g as kd,h as Na}from"./chunk-BNKTI3CY.mjs";import{e as Md}from"./chunk-UCD76KQ6.mjs";import{a as An}from"./chunk-TUYVYSN5.mjs";function Eo(e){return{annotations:e.annotations,animations:e.animations,activeVariants:e.model.activeVariants,measurements:e.measurements,selectionSets:e.selectionSets,product:e.product,sequences:e.sequences}}function tt(e,t){return{...e,model:{...e.model,activeVariants:t?.activeVariants??[]},annotations:t?.annotations??[],animations:t?.animations??Ao.animations,measurements:t?.measurements,selectionSets:t?.selectionSets,product:t?.product,sequences:t?.sequences}}function gc(e){if(e===void 0)return!0;try{return pr(e),!0}catch{return!1}}function fc(e){if(e===void 0)return!0;try{return Nn(e),!0}catch{return!1}}function hc(e){if(e===void 0)return!0;try{return ur(e),!0}catch{return!1}}var Kg="react-immersive:binding-builder",Gg=2,jn="session",Ln="model",In="textures",xc="current",vc=1;function eo(e){return e.kind==="file"?`file:${e.key}`:`url:${e.url}`}var on=null;function xr(){return on||(on=new Promise((e,t)=>{if(typeof indexedDB>"u"){t(new Error("IndexedDB is not available in this environment."));return}let i=indexedDB.open(Kg,Gg);i.onupgradeneeded=()=>{let r=i.result;r.objectStoreNames.contains(jn)||r.createObjectStore(jn),r.objectStoreNames.contains(Ln)||r.createObjectStore(Ln),r.objectStoreNames.contains(In)||r.createObjectStore(In)},i.onsuccess=()=>{let r=i.result;r.onversionchange=()=>{r.close(),on=null},e(r)},i.onerror=()=>t(i.error??new Error("Failed to open IndexedDB."))}),on.catch(()=>{on=null}),on)}function pi(e){return new Promise((t,i)=>{e.oncomplete=()=>t(),e.onerror=()=>i(e.error??new Error("IndexedDB transaction failed.")),e.onabort=()=>i(e.error??new Error("IndexedDB transaction aborted."))})}function $a(e){return new Promise((t,i)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>i(e.error??new Error("IndexedDB request failed."))})}function mt(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ua(e){return!mt(e)||typeof e.name!="string"?!1:e.kind==="file"?typeof e.key=="string":e.kind==="url"?typeof e.url=="string":!1}function yc(e){return mt(e)&&Ua(e.model)&&typeof e.namePrefix=="string"}function qg(e){if(e===void 0)return!0;try{return hd(e),!0}catch{return!1}}function wc(e){if(e===void 0)return!0;try{return dr(e),!0}catch{return!1}}function Wg(e){return!mt(e)||!Ua(e.model)||!mt(e.bindings)||!mt(e.originalTransforms)||e.modelSettings!==void 0&&(!mt(e.modelSettings)||!Array.isArray(e.modelSettings.annotations)||!mt(e.modelSettings.animations)||!Array.isArray(e.modelSettings.animations.clips)||e.modelSettings.activeVariants!==void 0&&(!Array.isArray(e.modelSettings.activeVariants)||!e.modelSettings.activeVariants.every(t=>typeof t=="string")))||mt(e.modelSettings)&&!hc(e.modelSettings.measurements)||mt(e.modelSettings)&&!fc(e.modelSettings.selectionSets)||mt(e.modelSettings)&&!gc(e.modelSettings.product)||mt(e.modelSettings)&&!wc(e.modelSettings.sequences)?!1:e.mergeModels===void 0?!0:Array.isArray(e.mergeModels)&&e.mergeModels.every(yc)}function vr(e){if(!mt(e)||e.version!==vc)return!1;if(e.composition!==void 0)try{Qo(e.composition)}catch{return!1}return!(typeof e.savedAt!="number"||!mt(e.bindings)||!mt(e.sceneConfig)||!Ua(e.model)||!hc(e.sceneConfig.measurements)||!fc(e.sceneConfig.selectionSets)||!gc(e.sceneConfig.product)||!wc(e.sceneConfig.sequences)||!qg(e.sceneConfig.section)||e.parkedModels!==void 0&&(!Array.isArray(e.parkedModels)||!e.parkedModels.every(Wg))||e.mergeModels!==void 0&&(!Array.isArray(e.mergeModels)||!e.mergeModels.every(yc))||e.modelOrder!==void 0&&(!Array.isArray(e.modelOrder)||!e.modelOrder.every(t=>typeof t=="string")))}function Ha(e,t){return e.kind==="url"?Promise.resolve(null):$a(t.get(e.key)).then(i=>!i||i.key!==e.key?null:new File([i.blob],i.name,{type:i.type,lastModified:i.lastModified}))}async function Sc(e,t){let i=await xr(),r={...e,version:vc,savedAt:Date.now()},o=i.transaction([jn,Ln],"readwrite"),n=pi(o);o.objectStore(jn).put(r,xc);let c=o.objectStore(Ln),d=new Set,s=p=>{p.kind==="file"&&d.add(p.key)};s(r.model),r.mergeModels?.forEach(p=>s(p.model)),r.parkedModels?.forEach(p=>{s(p.model),p.mergeModels?.forEach(x=>s(x.model))});for(let{key:p,file:x}of t??[]){let b={key:p,blob:x,name:x.name,type:x.type,lastModified:x.lastModified};c.put(b,p)}let g=c.getAllKeys();return g.onsuccess=()=>{for(let p of g.result)d.has(p)||c.delete(p)},await n,r}function mc(e,t){return Promise.all(e.map(async i=>({entry:i,file:await Ha(i.model,t)})))}async function kc(){let e=await xr(),t=e.transaction(jn,"readonly"),i=pi(t),r=await $a(t.objectStore(jn).get(xc));if(await i,!vr(r))return null;let o=r.parkedModels??[],n=r.mergeModels??[],c=e.transaction(Ln,"readonly"),d=pi(c),s=c.objectStore(Ln),[g,p,x]=await Promise.all([Ha(r.model,s),mc(n,s),Promise.all(o.map(async b=>({entry:b,file:await Ha(b.model,s),mergeFiles:await mc(b.mergeModels??[],s)})))]);return await d,r.model.kind==="file"&&!g?null:{session:{...r,parkedModels:o,mergeModels:n},file:g,parkedFiles:x,mergeFiles:p}}async function Dn(e,t){let r=(await xr()).transaction(In,"readwrite"),o=pi(r),n={blob:t,name:t.name,type:t.type,savedAt:Date.now()};r.objectStore(In).put(n,e),await o}async function fo(e){let i=(await xr()).transaction(In,"readonly"),r=pi(i),o=await $a(i.objectStore(In).get(e));return await r,o?new File([o.blob],o.name,{type:o.type,lastModified:o.savedAt}):null}function rn(e){return`url:${e}`}function _a(e){return e.models.find(t=>!e.composition.placements[rn(t.url)]?.deleted)??e.models[0]}function Ka(e){return Qo(e.composition)}function wr(e,t){return tt(e,t.modelSettings)}function Yg(e){return{url:e.url,namePrefix:e.namePrefix,resolved:{url:e.url,name:e.namePrefix,format:"glb",cleanup:()=>{}},sessionModel:{kind:"url",url:e.url,name:e.namePrefix},nodeNames:[],loadState:"loading"}}function zn(e){return(e.mergeModels??[]).map(Yg)}function Ga(e){let t=e.name??"model";return{url:e.url,name:t,bindings:e.objectBindings,originalTransforms:{},sessionModel:{kind:"url",url:e.url,name:t},mergedModelSources:zn(e),modelSettings:e.modelSettings}}function qa(e){let t=new Map;for(let i of e.models){let{url:r,name:o,assetId:n,tilesetUrl:c,assetVersion:d}=i;t.set(r,{url:r,name:o,assetId:n,tilesetUrl:c,assetVersion:d});for(let s of i.mergeModels??[])t.set(s.url,{url:s.url,assetId:s.assetId})}return t}function Cc(e){let t=r=>r.map(o=>({url:o.url,assetId:e.sources.get(o.url)?.assetId??null,namePrefix:o.namePrefix})),i=e.modelOrder.flatMap(r=>{if(e.composition.placements[rn(r)]?.deleted)return[];let o=e.sources.get(r)??{url:r};if(r===e.modelUrl)return[{...o,url:r,name:e.modelName,objectBindings:e.bindings,mergeModels:t(e.mergedModelSources),modelSettings:Eo(e.sceneConfig)}];let n=e.parkedModels.find(c=>c.url===r);return n?[{...o,url:r,name:n.name,objectBindings:n.bindings,mergeModels:t(n.mergedModelSources),modelSettings:n.modelSettings}]:[]});return{projectId:e.project.id,baseRevision:e.project.revision,models:i,composition:{...e.composition,placements:Object.fromEntries(Object.entries(e.composition.placements).filter(([,r])=>!r.deleted))},sceneConfig:tt(e.sceneConfig)}}function Va(e){return JSON.stringify(e,(t,i)=>i&&typeof i=="object"&&!Array.isArray(i)?Object.fromEntries(Object.entries(i).sort(([r],[o])=>r<o?-1:r>o?1:0)):i)}function Sr(e,t){return e===t||Va(e)===Va(t)}function Jg(e){return Eo(tt(Ao,e))}function Fn(e){return Va({models:e.models.map(t=>({url:t.url,name:t.name,objectBindings:t.objectBindings,mergeModels:(t.mergeModels??[]).map(({url:i,namePrefix:r})=>({url:i,namePrefix:r})),modelSettings:Jg(t.modelSettings)})),composition:e.composition,sceneConfig:tt(e.sceneConfig)})}function Vy(e){if(!(e.models.length<2))return e.models.flatMap(t=>{let i=e.composition.placements[rn(t.url)]??{};return i.deleted?[]:[{url:t.url,label:i.label??t.name,transform:i,visible:i.visible!==!1,objectBindings:t.objectBindings,sceneConfig:wr(e.sceneConfig,t),mergeModels:t.mergeModels?.map(({url:r,namePrefix:o})=>({url:r,namePrefix:o}))}]})}var Mc=new Set(["path","image","url","poster","src","imageUrl"]);function Xg(e){return e.startsWith("blob:")||e.startsWith("data:")||!!Qt(e)}function nn(e,t=new Set){if(Array.isArray(e))e.forEach(i=>nn(i,t));else if(e&&typeof e=="object")for(let[i,r]of Object.entries(e))typeof r=="string"?Mc.has(i)&&Xg(r)&&t.add(r):nn(r,t);return t}function yr(e,t){return Array.isArray(e)?e.map(i=>yr(i,t)):e&&typeof e=="object"?Object.fromEntries(Object.entries(e).map(([i,r])=>[i,typeof r=="string"&&Mc.has(i)&&t.has(r)?t.get(r):yr(r,t)])):e}async function Pc(e){let t=Qt(e)??e,i=await(await fetch(t)).blob(),r=e.startsWith("blob:")||e.startsWith("data:")?"image":e.split("/").pop()||"image";return new File([i],r,{type:i.type})}async function Bc(e,t){let i=p=>e.session.composition?.placements[eo(p)]?.deleted;e={...e,parkedFiles:e.parkedFiles.filter(p=>!i(p.entry.model))};let r=new Map,o=async(p,x)=>{if(p.kind!=="file")return p;if(!x)throw new Error(`The scene bundle is missing ${p.name}.`);let{url:b}=await t(x);return r.set(`file:${p.key}`,rn(b)),{kind:"url",url:b,name:p.name}},n=async p=>{let x=[];for(let{entry:b,file:h}of p)x.push({entry:{...b,model:await o(b.model,h)},file:null});return x},c=await o(e.session.model,e.file),d=await n(e.mergeFiles),s=[];for(let p of e.parkedFiles){let x=await o(p.entry.model,p.file),b=await n(p.mergeFiles);s.push({entry:{...p.entry,model:x,mergeModels:b.map(h=>h.entry)},file:null,mergeFiles:b})}let g=e.session.composition;return{file:null,mergeFiles:d,parkedFiles:s,session:{...e.session,model:c,mergeModels:d.map(p=>p.entry),parkedModels:s.map(p=>p.entry),modelOrder:e.session.modelOrder?.map(p=>r.get(p)??p),composition:g&&{...g,placements:Object.fromEntries(Object.entries(g.placements).map(([p,x])=>[r.get(p)??p,x]))}}}}import{strFromU8 as Zg,strToU8 as Qg,unzip as ef}from"fflate";var bi=512*1024*1024,Tc=5*1024*1024;function Wa(e){return[e.model,...(e.mergeModels??[]).map(t=>t.model),...(e.parkedModels??[]).flatMap(t=>[t.model,...(t.mergeModels??[]).map(i=>i.model)])]}function Rc(e){let t=o=>o.kind==="file"?`/bundle/${encodeURIComponent(o.key)}.glb`:o.url,i=[{model:e.model,bindings:e.bindings,merges:e.mergeModels,config:e.sceneConfig},...(e.parkedModels??[]).map(o=>({model:o.model,bindings:o.bindings,merges:o.mergeModels,config:tt(e.sceneConfig,o.modelSettings)}))],r=i.map(o=>o.model.kind==="file"?`file:${o.model.key}`:`url:${o.model.url}`);if(new Set(r).size!==r.length||i.length>256)throw new Error("Scene instances must have unique identities (maximum 256).");if(e.modelOrder&&(new Set(e.modelOrder).size!==e.modelOrder.length||e.modelOrder.some(o=>!r.includes(o))))throw new Error("Invalid scene asset order.");for(let o of e.parkedModels??[])for(let n of Object.values(o.originalTransforms))for(let c of["position","rotation","scale"]){let d=n?.[c];if(d!==void 0&&(!Array.isArray(d)||d.length!==3||!d.every(s=>typeof s=="number"&&Number.isFinite(s))))throw new Error("Invalid original node transform.")}for(let o of i)Cd({version:1,objectBindings:o.bindings,configuration:{modelUrl:t(o.model),sceneConfig:o.config,mergeModels:o.merges?.map(n=>({url:t(n.model),namePrefix:n.namePrefix}))}})}async function Nc(e,t){let i=JSON.parse(JSON.stringify({...e,version:1,savedAt:Date.now()})),r={},o=[],n=[],c=0;async function d(b,h){if(c+=h.size,c>bi)throw new Error("Scene bundle exceeds the 512 MiB expanded limit.");r[b]=new Uint8Array(await h.arrayBuffer())}for(let b of Wa(i)){if(b.kind!=="file"||o.some(S=>S.key===b.key))continue;let h=t.get(b.key);if(!h)throw new Error(`Cannot save scene: missing uploaded file ${b.name}.`);let M=`models/${o.length}`;o.push({key:b.key,path:M,name:h.name,type:h.type,lastModified:h.lastModified}),await d(M,h)}let s=new Map;async function g(b,h=0){if(h>64)throw new Error("Scene data is too deeply nested.");if(!(!b||typeof b!="object"))for(let[M,S]of Object.entries(b)){if(["__proto__","prototype","constructor"].includes(M))throw new Error("Reserved scene property.");if(M!=="metadata")if(typeof S=="string"){if(!["path","image","url","poster","src","imageUrl","customEnvironmentUrl"].includes(M))continue;let B=Qt(S),y=B||S.startsWith("blob:")||S.startsWith("data:")?null:await fo(S);if(!y&&!B&&!S.startsWith("blob:")&&!S.startsWith("data:"))continue;let u=s.get(S);if(u){b[M]=u;continue}if(!y){let N=await fetch(B??S);if(!N.ok)throw new Error("Cannot read an uploaded texture for this scene.");let A=await N.blob();y=new File([A],`texture-${n.length}`,{type:A.type})}let v=`textures/${n.length}`,m=`/__ri_bundle_texture__/${n.length}`;n.push({ref:m,path:v,name:y.name,type:y.type}),await d(v,y),s.set(S,m),b[M]=m}else await g(S,h+1)}}for(let b of Wa(i))if(b.kind==="url"&&b.url.startsWith("blob:"))throw new Error("Cannot save a temporary model URL without its original file.");if(await g(i),!vr(i))throw new Error("Invalid scene snapshot.");Rc(i);let p=Qg(JSON.stringify({format:"react-immersive-scene",version:1,session:i,files:o,textures:n}));if(p.byteLength>Tc)throw new Error("Scene settings exceed the 5 MiB limit.");if(c+p.byteLength>bi||Object.keys(r).length+1>1024)throw new Error("Scene bundle exceeds its size or file-count limit.");r["scene.json"]=p;let x=await fr(r);if(x.byteLength>bi)throw new Error("Compressed scene bundle exceeds 512 MiB.");return new Blob([x],{type:"application/zip"})}async function Ac(e){if(e.size>bi)throw new Error("Scene ZIP exceeds 512 MiB.");let t=0,i=0,r="",o=new Set,n=new Uint8Array(await e.arrayBuffer()),c=await new Promise((S,B)=>ef(n,{filter(y){return t+=y.originalSize,i++,o.has(y.name)?(r="Duplicate scene ZIP entry.",!1):(o.add(y.name),i>1024||t>bi||y.name==="scene.json"&&y.originalSize>Tc||!/^(scene\.json|models\/\d+|textures\/\d+)$/.test(y.name)?(r="Invalid or oversized scene ZIP entries.",!1):!0)}},(y,u)=>y?B(y):r?B(new Error(r)):S(u)));if(!c["scene.json"])throw new Error("This ZIP does not contain a React Immersive scene.");let d=JSON.parse(Zg(c["scene.json"]));if(d.format!=="react-immersive-scene"||d.version!==1||!vr(d.session)||!Array.isArray(d.files)||!Array.isArray(d.textures))throw new Error("Invalid scene bundle manifest.");Rc(d.session);let s=new Map,g=new Set;for(let S of d.files){if(!S||typeof S.key!="string"||!/^models\/\d+$/.test(S.path)||!c[S.path]||typeof S.name!="string"||typeof S.type!="string"||!Number.isFinite(S.lastModified)||g.has(S.path)||s.has(S.key))throw new Error("Invalid model file in scene bundle.");g.add(S.path),s.set(S.key,new File([c[S.path]],S.name,{type:S.type,lastModified:S.lastModified}))}for(let S of Wa(d.session))if(S.kind==="file"&&!s.has(S.key))throw new Error(`Scene bundle is missing ${S.name}.`);let p=new Map,x=crypto.randomUUID();for(let S of d.textures){if(!S||typeof S.ref!="string"||!/^\/__ri_bundle_texture__\/\d+$/.test(S.ref)||!/^textures\/\d+$/.test(S.path)||!c[S.path]||typeof S.name!="string"||typeof S.type!="string"||g.has(S.path)||p.has(S.ref))throw new Error("Invalid texture in scene bundle.");g.add(S.path),p.set(S.ref,{path:`materials/scene-${x}/${p.size}`,file:new File([c[S.path]],S.name,{type:S.type})})}function b(S,B=0){if(B>64)throw new Error("Scene data is too deeply nested.");if(!(!S||typeof S!="object"))for(let[y,u]of Object.entries(S)){if(["__proto__","constructor","prototype"].includes(y))throw new Error("Reserved scene property.");if(y!=="metadata")if(typeof u=="string"&&u.startsWith("/__ri_bundle_texture__/")){let v=p.get(u);if(!v)throw new Error("Scene bundle is missing a texture.");if(y==="path")S[y]=v.path;else{let m=c[[...d.textures].find(A=>A.ref===u).path],N="";for(let A=0;A<m.length;A+=32768)N+=String.fromCharCode(...m.subarray(A,A+32768));S[y]=`data:${v.file.type||"application/octet-stream"};base64,${btoa(N)}`}}else b(u,B+1)}}b(d.session),await Promise.all([...p.values()].map(S=>Dn(S.path,S.file)));let h=S=>S.kind==="file"?s.get(S.key):null,M=S=>S.map(B=>({entry:B,file:h(B.model)}));return{session:d.session,file:h(d.session.model),mergeFiles:M(d.session.mergeModels??[]),parkedFiles:(d.session.parkedModels??[]).map(S=>({entry:S,file:h(S.model),mergeFiles:M(S.mergeModels??[])}))}}import{useCallback as Y,useEffect as je,useMemo as He,useRef as ie,useState as _}from"react";import{Box3 as Ks,Plane as Xv,Raycaster as Zv,Vector2 as Qv,Vector3 as Ei}from"three";import{Box as ey,Check as ty,ClipboardPaste as oy,Copy as ny,Ellipsis as iy,Eye as ry,PanelLeftClose as ay,PanelLeftOpen as sy,PanelRightClose as ly,PanelRightOpen as dy,Pin as cy,PinOff as uy,Trash2 as py}from"lucide-react";import{useEffect as tf,useId as of,useRef as Oc,useState as Ec}from"react";import{Check as nf,ChevronDown as rf,History as af,ListRestart as sf,Plus as lf,Trash2 as df,Upload as cf}from"lucide-react";import{Fragment as Lc,jsx as gt,jsxs as Et}from"react/jsx-runtime";function Hn({label:e,icon:t,title:i,align:r="left",children:o}){let[n,c]=Ec(!1),d=Oc(null),s=Oc(null),g=of();return tf(()=>{if(!n)return;let p=b=>{d.current?.contains(b.target)||c(!1)},x=b=>{b.key==="Escape"&&(c(!1),s.current?.focus())};return window.addEventListener("pointerdown",p),window.addEventListener("keydown",x),()=>{window.removeEventListener("pointerdown",p),window.removeEventListener("keydown",x)}},[n]),Et("div",{className:"bb-headerMenuWrapper",ref:d,children:[Et("button",{ref:s,type:"button",className:`bb-headerButton ${e?"":"bb-headerButton--icon"} ${n?"bb-headerButton--open":""}`,onClick:()=>c(p=>!p),title:i,"aria-label":e?void 0:i,"aria-expanded":n,"aria-controls":n?g:void 0,children:[t,e?Et(Lc,{children:[e,gt(rf,{size:12,"aria-hidden":"true"})]}):null]}),n?gt("div",{id:g,className:`bb-headerMenu bb-headerMenu--${r}`,role:"group","aria-label":i,children:o(()=>c(!1))}):null]})}function jc({models:e,activeModelUrl:t,onSelectModel:i,onRestore:r,onRemove:o,onAddModel:n,onUpload:c,onReset:d,resetLabel:s,restoreDisabled:g,addModelDisabled:p,confirmRemove:x=!0,close:b}){let[h,M]=Ec(!1);return h&&o?Et("div",{className:"bb-headerMenuConfirm",role:"alertdialog","aria-label":"Remove model",children:[gt("p",{children:"Remove the model and its bindings from the editor? This also clears the saved session. Export your work first if you want to keep it."}),Et("div",{className:"bb-headerMenuConfirmActions",children:[gt("button",{type:"button",className:"bb-headerMenuItem",onClick:()=>M(!1),children:"Cancel"}),gt("button",{type:"button",className:"bb-headerMenuItem bb-headerMenuItem--danger",onClick:()=>{b(),o()},autoFocus:!0,children:"Remove"})]})]}):Et(Lc,{children:[e?gt("div",{className:"bb-modelMenuList",role:"radiogroup","aria-label":"Active model",children:e.map(S=>Et("button",{type:"button",role:"radio","aria-checked":S.url===t,className:"bb-headerMenuItem bb-modelMenuItem",title:S.label,onClick:()=>{b(),i?.(S.url)},children:[gt("span",{className:"bb-modelMenuCheck",children:S.url===t?gt(nf,{size:14,"aria-hidden":"true"}):null}),gt("span",{className:"bb-modelMenuName",children:S.label})]},S.url))}):null,c?Et("button",{type:"button",className:"bb-headerMenuItem",disabled:p,onClick:()=>{b(),c()},children:[gt(cf,{size:14,"aria-hidden":"true"}),"Open model\u2026"]}):null,n?Et("button",{type:"button",className:"bb-headerMenuItem",disabled:p,onClick:()=>{b(),n()},title:"Add another model, as a separate model or merged into this one",children:[gt(lf,{size:14,"aria-hidden":"true"}),"Add model\u2026"]}):null,r?Et("button",{type:"button",className:"bb-headerMenuItem",disabled:g,onClick:()=>{b(),r()},title:"Restore your last session: the model, its object bindings, and scene settings saved in this browser",children:[gt(af,{size:14,"aria-hidden":"true"}),"Restore last session"]}):null,d?Et("button",{type:"button",className:"bb-headerMenuItem",onClick:()=>{b(),d()},children:[gt(sf,{size:14,"aria-hidden":"true"}),s]}):null,o?Et("button",{type:"button",className:"bb-headerMenuItem bb-headerMenuItem--danger",onClick:()=>{if(x){M(!0);return}b(),o()},children:[gt(df,{size:14,"aria-hidden":"true"}),"Remove model\u2026"]}):null]})}import{useCallback as uf,useEffect as pf,useMemo as bf,useRef as Ic}from"react";import{jsx as Ya,jsxs as mf}from"react/jsx-runtime";function Dc({liveViewerRef:e,renderBefore:t,split:i,onSplitChange:r,labels:o,beforeAction:n,report:c,selected:d,onSelect:s,matchBy:g,onMatchByChange:p,showOutlines:x,onShowOutlinesChange:b}){let h=Ic(null),M=Ic(null),S=bf(()=>Qd(),[]);pf(()=>()=>S.detach(),[S]);let B=uf(y=>{M.current=y;let u=e.current;u&&S.attach(0,u.raw.controls,u.invalidate),S.attach(1,y.raw.controls,y.invalidate)},[S,e]);return mf("div",{ref:h,className:"ri-compare ri-compare--overlay",style:{"--ri-compare-split":`${i*100}%`},children:[Ya("div",{className:"ri-compare__layer ri-compare__layer--before",children:t(B)}),c&&Ya(Xd,{showOutlines:x,onShowOutlinesChange:b,matchBy:g,onMatchByChange:p,report:c,selected:d,onClear:()=>s?.(null),onSelect:y=>{let u=y.afterObjectId?0:1,v=u===0?e.current:M.current,m=u===0?y.afterObjectId:y.beforeObjectId,N=m?v?.raw.nodes[m]:null;S.setLeader(u),s?.(y),v&&N&&(v.raw.controls.fitToBox(N,!0),v.invalidate())}}),Ya(ec,{split:i,onSplitChange:r,labels:o,containerRef:h,beforeAction:n})]})}import{useCallback as ho,useEffect as zc,useMemo as Fc,useRef as kr,useState as Hc}from"react";var gf={currentClip:null,isPlaying:!1,speed:1,time:0,duration:0,active:[]};function ff(e,t){let i=[],r=new Map,o=new Map,n=new Map,c=new Set;for(let d of e){let s=t.get(d);if(!s)continue;let g=s.clipDetails??s.clips.map(x=>({sourceName:x,duration:0}));n.set(d,g);let p=new Map;for(let x of g){let b=x.sourceName;for(let h=2;c.has(b);h+=1)b=`${x.sourceName} (${h})`;c.add(b),i.push({sourceName:b,duration:x.duration}),r.set(b,{url:d,sourceName:x.sourceName}),p.set(x.sourceName,b)}o.set(d,p)}return{clipDetails:i,targets:r,displayNamesByUrl:o,clipDetailsByUrl:n}}function hf(e,t,i){let r=[];for(let o of e){let n=t.get(o),c=i.get(o);if(!(!n||!c))for(let d of n.active){let s=c.get(d.clip);s&&r.push({...d,clip:s})}}return r}function $c(e){let t=kr(new Map),i=kr(new Map),r=kr(new Map),[o,n]=Hc(0),[c,d]=Hc(0),s=ho((T,D)=>{if(t.current.get(T)===D)return;r.current.get(T)?.(),r.current.delete(T),t.current.set(T,D),i.current.set(T,D.getState?.()??gf);let k=D.subscribe?.(Q=>{i.current.set(T,Q),d(G=>G+1)});k&&r.current.set(T,k),n(Q=>Q+1)},[]);zc(()=>{let T=new Set(e),D=!1;for(let k of[...t.current.keys()])T.has(k)||(r.current.get(k)?.(),r.current.delete(k),t.current.delete(k),i.current.delete(k),D=!0);D&&n(k=>k+1)},[e]),zc(()=>()=>r.current.forEach(T=>T()),[]);let{clipDetails:g,targets:p,displayNamesByUrl:x,clipDetailsByUrl:b,hasModels:h}=Fc(()=>({...ff(e,t.current),hasModels:t.current.size>0}),[e,o]),M=kr(p);M.current=p;let S=Fc(()=>hf(e,i.current,x),[e,x,c]),B=ho((T,D,k)=>{k(),!D.subscribe&&D.getState&&(i.current.set(T,D.getState()),d(Q=>Q+1))},[]),y=ho(T=>{t.current.forEach((D,k)=>B(k,D,()=>T(D,k)))},[B]),u=ho((T,D)=>{let k=M.current.get(T);if(!k)return;let Q=t.current.get(k.url);Q&&B(k.url,Q,()=>D(Q,k))},[B]),v=ho((T,D)=>u(T,(k,Q)=>k.play(Q.sourceName,D)),[u]),m=ho(T=>T===void 0?y(D=>D.pause()):u(T,(D,k)=>D.pause(k.sourceName)),[y,u]),N=ho(T=>T===void 0?y(D=>D.stop()):u(T,(D,k)=>D.stop(k.sourceName)),[y,u]),A=ho((T,D)=>D===void 0?y(k=>k.setSpeed(T)):u(D,(k,Q)=>k.setSpeed(T,Q.sourceName)),[y,u]),K=ho((T,D)=>D===void 0?y(k=>k.seek?.(T)):u(D,(k,Q)=>k.seek?.(T,Q.sourceName)),[y,u]);return{clipDetails:g,clipDetailsByUrl:b,displayNamesByUrl:x,hasModels:h,active:S,play:v,pause:m,stop:N,setSpeed:A,seek:K,handleModelAnimationsReady:s}}import{useEffect as wf,useMemo as Sf}from"react";function mi(e,t){let i=new Map(e.animations.clips.map(n=>[n.sourceName,n])),r=t.map(({sourceName:n})=>i.get(n)??{sourceName:n,displayName:n,hidden:!1,loopMode:"repeat",speed:1}),o=e.animations.autoplayClip&&r.some(n=>n.sourceName===e.animations.autoplayClip&&!n.hidden)?e.animations.autoplayClip:null;return o===e.animations.autoplayClip&&r.length===e.animations.clips.length&&r.every((n,c)=>n===e.animations.clips[c])?e.animations:{clips:r,autoplayClip:o}}function Cr(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function gi(e,t){if(!Cr(e)||!Cr(t))return t??e;let i={...e};for(let[r,o]of Object.entries(t)){if(o===void 0)continue;if(r==="section"){i[r]=cr(i[r],o);continue}if(r==="sequences"){i[r]=dr(o);continue}if(r==="limits"){i[r]=o;continue}let n=i[r];i[r]=Cr(n)&&Cr(o)?gi(n,o):o}return i}import{useCallback as jo,useReducer as xf,useRef as vf}from"react";var yf=100;function xo(e,t){switch(t.type){case"history":return t.updater(e);case"set":{let i=typeof t.updater=="function"?t.updater(e.present):t.updater;if(i===e.present)return e;let r=t.track?e.edits+1:e.edits,o=!t.track&&e.edits===0?i:e.baseline;return t.track?t.coalesce?{...e,present:i,future:[],edits:r,baseline:o}:{past:[...e.past,e.present].slice(-yf),present:i,future:[],edits:r,baseline:o}:{...e,present:i,baseline:o}}case"undo":{if(e.past.length===0)return e;let i=e.past[e.past.length-1];return{...e,past:e.past.slice(0,-1),present:i,future:[e.present,...e.future],edits:e.edits+1}}case"redo":{if(e.future.length===0)return e;let[i,...r]=e.future;return{...e,past:[...e.past,e.present],present:i,future:r,edits:e.edits+1}}case"reset":return{past:[],present:t.value,future:[],edits:t.track?e.edits+1:0,baseline:t.track?e.baseline:t.value}}}function fi(e,t=600){let[i,r]=xf(xo,{past:[],present:e,future:[],edits:0,baseline:e}),o=vf(0),n=jo(h=>{let M=Date.now(),S=M-o.current<t;o.current=M,r({type:"set",updater:h,coalesce:S,track:!0})},[t]),c=jo(h=>{let M=Date.now()-o.current<t;r({type:"set",updater:h,coalesce:M,track:!1})},[t]),d=jo(h=>{o.current=0,r({type:"set",updater:h,coalesce:!1,track:!0})},[]),s=jo(h=>{r({type:"history",updater:h})},[]),g=jo(h=>{o.current=0,r({type:"history",updater:typeof h=="function"?h:()=>h})},[]),p=jo(()=>{o.current=0,r({type:"undo"})},[]),x=jo(()=>{o.current=0,r({type:"redo"})},[]),b=jo((h,M)=>{o.current=0,r({type:"reset",value:h,track:M?.asEdit??!1})},[]);return{value:i.present,setValue:n,setValueUntracked:c,setValueAsStep:d,updateHistory:s,restoreSnapshot:g,snapshot:i,undo:p,redo:x,reset:b,canUndo:i.past.length>0,canRedo:i.future.length>0,edits:i.edits,baseline:i.baseline}}function kf(e,t){return e.sourceName===t.sourceName&&e.displayName===t.displayName&&e.hidden===t.hidden&&e.loopMode===t.loopMode&&e.speed===t.speed}function Uc(e,t,i,r){let o=tt(t,e.modelSettings);if(o.animations===i)return e;let n={...o,animations:i},c=e.sceneHistory??{past:[],present:o,future:[],baseline:o,edits:0};return{...e,modelSettings:Eo(n),sceneHistory:xo(c,{type:"set",updater:n,track:r,coalesce:!1})}}function Vc({modelUrl:e,sceneConfig:t,setSceneConfig:i,setSceneConfigUntracked:r,parkedModels:o,setParkedModels:n,animations:c,markSessionEdited:d}){let{clipDetailsByUrl:s,displayNamesByUrl:g}=c;wf(()=>{let b=e?s.get(e):void 0;b&&r(h=>{let M=mi(h,b);return M===h.animations?h:{...h,animations:M}}),n(h=>{let M=!1,S=h.map(B=>{let y=s.get(B.url);if(!y)return B;let u=tt(t,B.modelSettings),v=Uc(B,t,mi(u,y),!1);return M||(M=v!==B),v});return M?S:h})},[s,e,t,r,n]);let p=Sf(()=>{let b=[],h=null;for(let[M,S]of g){let B=M===e?t:tt(t,o.find(u=>u.url===M)?.modelSettings),y=mi(B,s.get(M)??[]);for(let u of y.clips){let v=S.get(u.sourceName);v&&b.push({...u,sourceName:v,displayName:u.displayName===u.sourceName?v:u.displayName})}h??(h=y.autoplayClip?S.get(y.autoplayClip)??null:null)}return{clips:b,autoplayClip:h}},[g,s,e,t,o]);return{config:p,onChange:b=>{let h=new Map(p.clips.map(B=>[B.sourceName,B])),M=new Map(b.clips.map(B=>[B.sourceName,B])),S=(B,y)=>{let u=g.get(B);if(!u)return y.animations;let v=mi(y,s.get(B)??[]),m=v.clips.map(A=>{let K=u.get(A.sourceName),T=K?M.get(K):void 0;if(!T)return A;let D={...T,sourceName:A.sourceName,displayName:T.displayName===h.get(K)?.displayName?A.displayName:T.displayName};return kf(A,D)?A:D}),N=b.autoplayClip===p.autoplayClip?v.autoplayClip:[...u].find(([,A])=>A===b.autoplayClip)?.[0]??null;return N===v.autoplayClip&&m.every((A,K)=>A===v.clips[K])?v:{clips:m,autoplayClip:N}};e&&i(B=>{let y=S(e,B);return y===B.animations?B:{...B,animations:y}}),n(B=>B.map(y=>Uc(y,t,S(y.url,tt(t,y.modelSettings)),!0))),d()}}}import{useEffect as sn,useRef as ou,useState as Io}from"react";import{ChevronLeft as Af,ChevronRight as Of,Crosshair as Ef,FileUp as jf,RotateCcw as Lf,X as nu}from"lucide-react";import{useCallback as _c,useRef as Cf,useState as Kc,useSyncExternalStore as Mf}from"react";import{Copy as Pf}from"lucide-react";async function $n(e){try{return await navigator.clipboard.writeText(e),!0}catch{return!1}}import{Fragment as Rf,jsx as vo,jsxs as Lo}from"react/jsx-runtime";function Gc(){let[e,t]=Kc(null),[i,r]=Kc(null),o=Cf(null),n=_c(d=>{let g=d.target.closest?.("[data-ri-path]")?.dataset.riPath??null;g!==o.current&&(o.current=g,t(g))},[]),c=_c(d=>{let s=d.target.closest?.("[data-ri-path]");s?.dataset.riPath&&(d.preventDefault(),r({x:d.clientX,y:d.clientY,path:s.dataset.riPath}))},[]);return{path:e,menu:i,closeMenu:()=>r(null),onMouseOver:n,onContextMenu:c}}function qc({x:e,y:t,path:i,onClose:r}){return vo("div",{className:"bb-pathMenuScrim",onPointerDown:r,onContextMenu:o=>{o.preventDefault(),r()},children:Lo("div",{className:"bb-pathMenu",style:{left:e,top:t},role:"menu",onPointerDown:o=>o.stopPropagation(),children:[Lo("button",{type:"button",role:"menuitem",autoFocus:!0,onKeyDown:o=>{o.key==="Escape"&&r()},onClick:()=>{$n(i),r()},children:[vo(Pf,{size:13,"aria-hidden":"true"}),"Copy path"]}),vo("code",{children:i})]})})}var Ja=null,Wc=null,Xa=new Set;function Mr(e){e&&(Wc=e);let t=e?`[${e.map(i=>i.toFixed(3)).join(", ")}]`:null;t!==Ja&&(Ja=t,Xa.forEach(i=>i()))}function Pr(){return Wc}function Bf(e){return Xa.add(e),()=>Xa.delete(e)}function Tf({path:e}){let t=e.lastIndexOf(".");return Lo(Rf,{children:[e.slice(0,t+1),vo("em",{children:e.slice(t+1)})]})}function Yc({saveState:e,objectCount:t,selectedCount:i,path:r,hints:o}){let n=Mf(Bf,()=>Ja,()=>null);return Lo("footer",{className:"bb-statusBar",children:[e?Lo("span",{className:"bb-statusSave",children:[vo("i",{"aria-hidden":"true"}),e]}):null,Lo("span",{children:[t," ",t===1?"object":"objects"]}),i>0?Lo("span",{children:[i," selected"]}):null,n?Lo("span",{className:"bb-statusCursor",title:`Cursor ${n}`,children:["Cursor ",vo("code",{children:n})]}):null,vo("span",{className:"bb-statusPath","aria-live":"off",children:r?vo(Tf,{path:r}):null}),vo("span",{className:"bb-statusHints",children:o})]})}import{useSyncExternalStore as Nf}from"react";var ft={active:!1,points:[],floor:0,finished:!1},Za=new Set;function hi(e){ft=e,Za.forEach(t=>t())}function Jc(e){hi({active:!0,points:[],floor:e,finished:!1})}function Xc(e){ft.active&&hi({...ft,points:[...ft.points,e]})}function Qa(){ft.active&&hi({...ft,points:ft.points.slice(0,-1)})}function xi(){ft.active&&ft.points.length>=3&&hi({...ft,finished:!0})}function an(){hi({active:!1,points:[],floor:ft.floor,finished:!1})}function Zc(){return ft}function Br(){return Nf(e=>(Za.add(e),()=>Za.delete(e)),()=>ft,()=>ft)}import{Fragment as vi,jsx as j,jsxs as ue}from"react/jsx-runtime";var If="image/png,image/jpeg,image/webp,image/avif,image/gif";function Df(e){let t=e.trim();return!!(t&&Qt(t))||/^(blob:|data:image\/)/i.test(t)}var zf=["lit","unlit","normals"],Ff=["default","color","image","environment"],Hf={pbr:"PBR",matcap:"Matcap","uv-checker":"UV checker"};function Qc(e){let t=e%360;return t<0?t+360:t}function iu({config:e,onChange:t,diagnostics:i,onDiagnosticsOpenChange:r,materialVariantGroups:o=[]}){let{model:n,wireframe:c}=e,d=Sd(n),s=o.length>0?d.filter(u=>!o.some(v=>v.variants.some(m=>m.name===u))):[],{tier:g}=dt(),p=Hd(),[x,b]=Io({orientation:!0,diagnostics:!1,autoRotate:!1,wireframe:!1,section:!1});sn(()=>(r?.(x.diagnostics),()=>r?.(!1)),[x.diagnostics,r]);let h=u=>b(v=>({...v,[u]:!v[u]})),M=u=>t({...e,model:u}),S=u=>t({...e,wireframe:u}),B=e.section??fd,y=u=>t({...e,section:{...B,...u}});return ue("div",{className:"se-generalContent",children:[ue(re,{title:"Display",open:x.orientation,onToggle:()=>h("orientation"),children:[ue("div",{className:"se-field se-fieldInline",children:[ue("div",{className:"se-fieldLabel se-fieldLabel--action",children:[j("span",{children:"Straighten"}),j("button",{type:"button",className:"se-iconButton",onClick:()=>M({...n,rotation:[0,0,0]}),"aria-label":"Reset model rotation",children:j(Lf,{size:12})})]}),j("div",{className:"se-axisStepperGrid",children:["X","Y","Z"].map((u,v)=>ue("div",{className:"se-axisStepper",children:[j("button",{type:"button",className:"se-axisStepperButton",onClick:()=>{let m=[...n.rotation];m[v]=Qc(m[v]-90),M({...n,rotation:m})},"aria-label":`Rotate ${u} axis backward`,children:j(Af,{size:12})}),j("span",{className:"se-axisStepperLabel",children:u}),j("button",{type:"button",className:"se-axisStepperButton",onClick:()=>{let m=[...n.rotation];m[v]=Qc(m[v]+90),M({...n,rotation:m})},"aria-label":`Rotate ${u} axis forward`,children:j(Of,{size:12})})]},u))})]}),j(kt,{label:"Rotation",path:"sceneConfig.model.rotation",value:n.rotation,min:0,max:360,step:1,onChange:u=>M({...n,rotation:u})}),ue("div",{className:"se-field se-fieldInline","data-ri-path":"sceneConfig.model.renderer",children:[j("span",{className:"se-fieldLabel",children:"Renderer"}),j("div",{className:"se-segmentedControl se-segmentedControl--renderer",children:pd.map(u=>j("button",{type:"button",className:`se-segmentedOption ${n.renderer===u?"se-segmentedOption--active":""}`,onClick:()=>M({...n,renderer:u}),children:Hf[u]},u))})]}),j(bt,{label:"Shading",path:"sceneConfig.model.shading",value:n.shading,options:zf,onChange:u=>M({...n,shading:u})}),o.length>0&&!lt(g,"materialVariants")?j(Ye,{requiredTier:"starter",feature:"Material variants"}):null,(lt(g,"materialVariants")?o:[]).map((u,v)=>{let m=d.find(N=>u.variants.some(A=>A.name===N));return ue("label",{className:"se-field se-fieldInline",children:[j("span",{className:"se-fieldLabel",children:u.name??"Material variant"}),ue(et,{className:"se-select",value:m??"",onChange:N=>{let A=N.target.value,K=d.filter(T=>T!==m);M(Na(n,A?wd(K,A,o):K))},children:[j("option",{value:"",children:"Model default"}),u.variants.map(N=>j("option",{value:N.name,children:N.label},N.name))]})]},u.name??`group-${v}`)}),s.length>0?ue("div",{className:"se-placeholder se-placeholder--spaced",children:["Not in this model: ",s.join(", "),"."," ",j("button",{type:"button",className:"se-linkButton",onClick:()=>M(Na(n,d.filter(u=>!s.includes(u)))),children:"Remove"})]}):null]}),ue(re,{title:"Auto rotate",open:x.autoRotate,onToggle:()=>h("autoRotate"),trailing:j(de,{checked:n.autoRotate??!1,onChange:u=>M({...n,autoRotate:u}),label:"Toggle auto rotate"}),children:[n.autoRotate&&p?j("div",{className:"se-placeholder se-placeholder--spaced",children:"Your device is set to reduce motion, so this preview won't turn. Visitors without that setting will see it."}):null,n.autoRotate?j(I,{label:"Speed",path:"sceneConfig.model.autoRotateSpeed",value:n.autoRotateSpeed??1,min:.1,max:3,step:.1,formatValue:u=>`${u.toFixed(1)}x`,onChange:u=>M({...n,autoRotateSpeed:u})}):j("div",{className:"se-placeholder",children:"Enable auto rotate to adjust its speed."})]}),j(re,{title:"Wireframe",open:x.wireframe,onToggle:()=>h("wireframe"),disabled:!c.enabled,trailing:j(de,{checked:c.enabled,onChange:u=>S({...c,enabled:u}),label:"Toggle wireframe preview"}),children:ue(vi,{children:[j(I,{label:"Opacity",path:"sceneConfig.wireframe.opacity",value:c.opacity,min:0,max:1,step:.01,onChange:u=>S({...c,opacity:u})}),j(St,{label:"Wire color",path:"sceneConfig.wireframe.color",value:c.color,onChange:u=>S({...c,color:u})})]})}),j(re,{title:"Section cut",open:x.section,onToggle:()=>h("section"),disabled:!B.enabled,trailing:j(de,{checked:B.enabled,onChange:u=>{y({enabled:u}),u&&b(v=>({...v,section:!0}))},label:"Toggle section cut"}),children:j("div",{"data-ri-path":"sceneConfig.section",children:j(Wd,{section:B,onChange:y})})}),i&&j(re,{title:"Diagnostics",open:x.diagnostics,onToggle:()=>h("diagnostics"),children:j(sc,{...i})})]})}function eu(e){let t=Ed(e);return t?t.floorOutline?"outline":t.insideModel?"auto":t.aroundModel?"around":"manual":null}function ru({config:e,onChange:t,limitBounds:i}){let{camera:r}=e,[o,n]=Io(!0),[c,d]=Io(!0),s=r.limits??{},[g,p]=Io(()=>eu(s)??"off"),x=eu(s);sn(()=>{p(x||(h=>h==="auto"||h==="around"?"off":h))},[x]);let b=h=>{let M={...s,...h};for(let S of Object.keys(M))M[S]===void 0&&delete M[S];t({...e,camera:{...r,limits:Object.keys(M).length?M:void 0}})};return ue("div",{className:"se-generalContent",children:[j(re,{title:"Lens",open:o,onToggle:()=>n(h=>!h),children:j(I,{label:"Field of view",path:"sceneConfig.camera.fieldOfView",value:r.fieldOfView,min:20,max:100,step:.1,formatValue:h=>`${h.toFixed(1)}\xB0`,onChange:h=>t({...e,camera:{...r,fieldOfView:h}})})}),ue(re,{title:"Limits",open:c,onToggle:()=>d(h=>!h),children:[j(pt,{label:"Mode",path:"sceneConfig.camera.limits.insideModel",children:ue(et,{className:"se-select","aria-label":"Camera limits mode",value:g,onChange:h=>{let M=h.target.value;p(M),t({...e,camera:{...r,limits:M==="auto"?{insideModel:!0}:M==="around"?{aroundModel:!0}:void 0}})},children:[j("option",{value:"off",children:"Off"}),j("option",{value:"around",children:"Auto (around model)"}),j("option",{value:"auto",children:"Auto (inside model)"}),j("option",{value:"outline",children:"Floor outline"}),j("option",{value:"manual",children:"Manual"})]})}),g==="around"?j("p",{className:"bb-note",children:"For objects: the camera orbits around the model from any side, without going inside it, under the floor or so far away that it gets lost."}):null,g==="auto"?j("p",{className:"bb-note",children:"The camera stays inside the model's own floor area wherever you move it, whatever its shape (an L-shaped room included), clear of the walls."}):null,g==="outline"?j(Uf,{outline:s.floorOutline,onChange:h=>t({...e,camera:{...r,limits:h?{floorOutline:h}:void 0}}),limitBounds:i}):null,g==="manual"?j($f,{limits:s,onChange:b,limitBounds:i}):null]})]})}function $f({limits:e,onChange:t,limitBounds:i}){let[r,o]=Io(()=>[e.panBoundary?.[0]??[void 0,void 0,void 0],e.panBoundary?.[1]??[void 0,void 0,void 0]]),n=JSON.stringify(e.panBoundary??null);sn(()=>{e.panBoundary&&o([e.panBoundary[0],e.panBoundary[1]])},[n]);let c=(s,g)=>{let p=s===0?[g,r[1]]:[r[0],g];o(p);let[x,b]=p;tu(x)&&tu(b)?t({panBoundary:[[Math.min(x[0],b[0]),Math.min(x[1],b[1]),Math.min(x[2],b[2])],[Math.max(x[0],b[0]),Math.max(x[1],b[1]),Math.max(x[2],b[2])]]}):e.panBoundary&&t({panBoundary:void 0,boundaryEnclosesCamera:void 0})},d=s=>{let g=i?.get(s);g&&(o([g[0],g[1]]),t({panBoundary:g,boundaryEnclosesCamera:!0}))};return ue(vi,{children:[i?ue("div",{className:"se-limitActions se-limitActions--start",children:[j("button",{type:"button",className:"bb-button",onClick:()=>d("model"),children:"Limit to model"}),j("button",{type:"button",className:"bb-button",disabled:!i.selectedLabel,title:i.selectedLabel?`Keep the camera inside ${i.selectedLabel}`:"Select an object first",onClick:()=>d("selected"),children:"Limit to selected"})]}):null,j(pt,{label:"Zoom distance",path:"sceneConfig.camera.limits.minDistance",children:ue("span",{className:"se-limitPair",children:[j(Kt,{label:"Closest",placeholder:"0",value:e.minDistance,min:0,onChange:s=>t({minDistance:s})}),j(Kt,{label:"Farthest",placeholder:"No limit",value:e.maxDistance,min:0,onChange:s=>t({maxDistance:s})})]})}),j(pt,{label:"Up / down angle",title:"0\xB0 looks down from above, 90\xB0 is level, 180\xB0 looks up from below",path:"sceneConfig.camera.limits.minPolarAngle",children:ue("span",{className:"se-limitPair",children:[j(Kt,{label:"From (\xB0)",placeholder:"0",value:e.minPolarAngle,min:0,max:180,onChange:s=>t({minPolarAngle:s})}),j(Kt,{label:"To (\xB0)",placeholder:"180",value:e.maxPolarAngle,min:0,max:180,onChange:s=>t({maxPolarAngle:s})})]})}),j(pt,{label:"Left / right angle",title:"0\xB0 views from the front (+Z), 90\xB0 from the right (+X), -90\xB0 from the left",path:"sceneConfig.camera.limits.minAzimuthAngle",children:ue("span",{className:"se-limitPair",children:[j(Kt,{label:"From (\xB0)",placeholder:"No limit",value:e.minAzimuthAngle,onChange:s=>t({minAzimuthAngle:s})}),j(Kt,{label:"To (\xB0)",placeholder:"No limit",value:e.maxAzimuthAngle,onChange:s=>t({maxAzimuthAngle:s})})]})}),[0,1].map(s=>j(pt,{label:s===0?"Pan area from":"Pan area to",title:"A corner of the box the camera's target stays in. Hover the 3D view and read the status bar's Cursor, or use the crosshair.",path:"sceneConfig.camera.limits.panBoundary",children:ue("span",{className:"se-limitPoint",children:[["X","Y","Z"].map((g,p)=>j(Kt,{label:g,placeholder:g,value:r[s][p],onChange:x=>{let b=[...r[s]];b[p]=x,c(s,b)}},g)),j("button",{type:"button",className:"se-iconButton",title:"Use the last Cursor point from the status bar","aria-label":`Use the last cursor point for pan area ${s===0?"from":"to"}`,onClick:()=>{let g=Pr();g&&c(s,[...g])},children:j(Ef,{size:13})})]})},s)),e.panBoundary?j(fe,{label:"Keep camera inside area",path:"sceneConfig.camera.limits.boundaryEnclosesCamera",checked:!!e.boundaryEnclosesCamera,onChange:s=>t({boundaryEnclosesCamera:s||void 0})}):null,j("div",{className:"se-limitActions",children:j("button",{type:"button",className:"bb-button",onClick:()=>{o([[void 0,void 0,void 0],[void 0,void 0,void 0]]),t({minDistance:void 0,maxDistance:void 0,minPolarAngle:void 0,maxPolarAngle:void 0,minAzimuthAngle:void 0,maxAzimuthAngle:void 0,boundaryEnclosesCamera:void 0,boundaryFriction:void 0,panBoundary:void 0})},children:"Clear limits"})})]})}function Uf({outline:e,onChange:t,limitBounds:i}){let r=Br(),o=i?.get("model")??null,n=e?.floor??o?.[0][1]??0,c=e?.ceiling??o?.[1][1]??n+3;if(sn(()=>{!r.active||!r.finished||(t({points:r.points,floor:n,ceiling:c}),an())},[r]),sn(()=>an,[]),sn(()=>{if(!r.active)return;let s=g=>{let p=g.target?.closest?.("input, textarea");if(g.key==="Enter")xi();else if(g.key==="Escape")an();else if(g.key==="Backspace"&&!p)Qa();else return;g.preventDefault()};return window.addEventListener("keydown",s),()=>window.removeEventListener("keydown",s)},[r.active]),r.active)return ue(vi,{children:[j("p",{className:"bb-note",children:"Click the floor corners in the 3D view, in order around the area. Click the first corner again or press Enter to finish \xB7 Backspace removes the last \xB7 Esc cancels."}),ue("p",{className:"bb-note",children:[r.points.length," corners"]}),ue("div",{className:"se-limitActions se-limitActions--start",children:[j("button",{type:"button",className:"bb-button",disabled:r.points.length<3,onClick:xi,children:"Finish"}),j("button",{type:"button",className:"bb-button",disabled:!r.points.length,onClick:Qa,children:"Undo last"}),j("button",{type:"button",className:"bb-button",onClick:an,children:"Cancel"})]})]});let d=(s,g)=>{if(!e)return;let p=e.points.flatMap((x,b)=>b!==s?[x]:g?[g]:[]);t(p.length>=3?{...e,points:p}:void 0)};return ue(vi,{children:[j("div",{className:"se-limitActions se-limitActions--start",children:j("button",{type:"button",className:"bb-button",onClick:()=>Jc(n),children:e?"Redraw outline":"Draw outline"})}),e?ue(vi,{children:[e.points.map(([s,g],p)=>j(pt,{label:`Corner ${p+1}`,path:"sceneConfig.camera.limits.floorOutline",children:ue("span",{className:"se-limitPoint",children:[j(Kt,{label:"X",placeholder:"X",value:s,onChange:x=>x!==void 0&&d(p,[x,g])}),j(Kt,{label:"Z",placeholder:"Z",value:g,onChange:x=>x!==void 0&&d(p,[s,x])}),j("span",{}),j("button",{type:"button",className:"se-iconButton",title:"Remove this corner","aria-label":`Remove corner ${p+1}`,disabled:e.points.length<=3,onClick:()=>d(p,null),children:j(nu,{size:13})})]})},p)),j(pt,{label:"Floor / ceiling",title:"World heights the camera stays between",path:"sceneConfig.camera.limits.floorOutline",children:ue("span",{className:"se-limitPair",children:[j(Kt,{label:"Floor",placeholder:"Floor",value:e.floor,onChange:s=>s!==void 0&&s<e.ceiling&&t({...e,floor:s})}),j(Kt,{label:"Ceiling",placeholder:"Ceiling",value:e.ceiling,onChange:s=>s!==void 0&&s>e.floor&&t({...e,ceiling:s})})]})})]}):j("p",{className:"bb-note",children:"Draw the area the camera may move in, by clicking its floor corners. An L-shaped room takes 6 corners."})]})}function tu(e){return e.every(t=>typeof t=="number")}function Kt({label:e,placeholder:t,value:i,min:r,max:o,onChange:n}){let c=i===void 0?"":String(Number(i.toFixed(3))),[d,s]=Io(c),g=ou(!1);sn(()=>{g.current||s(c)},[c]);let p=()=>{let x=d.trim();if(x===""){i!==void 0&&n(void 0);return}let b=Number(x);if(!Number.isFinite(b))return s(c);r!==void 0&&(b=Math.max(r,b)),o!==void 0&&(b=Math.min(o,b)),s(String(Number(b.toFixed(3)))),b!==i&&n(b)};return j("input",{className:"se-numberInput",inputMode:"decimal","aria-label":e,title:e,placeholder:t,value:d,onFocus:()=>{g.current=!0},onChange:x=>s(x.target.value),onBlur:()=>{g.current=!1,p()},onKeyDown:x=>{x.key==="Enter"&&x.currentTarget.blur()}})}function au({config:e,onChange:t,onImageFile:i}){let{background:r,environment:o,groundShadows:n}=e,c=ou(null),[d,s]=Io(null),g=Df(r.imageUrl),{tier:p}=dt(),[x,b]=Io({environment:!0,envShadow:!1,background:!0,groundShadows:!1}),h=u=>b(v=>({...v,[u]:!v[u]})),M=u=>t({...e,background:u}),S=u=>t({...e,environment:u}),B=u=>t({...e,groundShadows:u}),y=u=>{if(!u.type.startsWith("image/")){s("Choose a PNG, JPG, WEBP, AVIF or GIF image.");return}s(null);let v=Rn(u);v===r.imageUrl&&Qt(v)||_t(v,URL.createObjectURL(u)),i?.(v,u),M({...r,imageUrl:v})};return ue("div",{className:"se-generalContent",children:[ue(re,{title:"Environment",open:x.environment,onToggle:()=>h("environment"),children:[ue("div",{className:"se-field se-fieldInline","data-ri-path":"sceneConfig.environment.source",children:[j("span",{className:"se-fieldLabel",children:"Source"}),j("div",{className:"se-segmentedControl",children:["preset","custom"].map(u=>j("button",{type:"button",className:`se-segmentedOption ${o.source===u?"se-segmentedOption--active":""}`,onClick:()=>S({...o,source:u}),children:u==="preset"?"Preset":"Custom"},u))})]}),o.source==="preset"?j(bt,{label:"Preset",path:"sceneConfig.environment.preset",value:o.preset,options:bd,onChange:u=>S({...o,source:"preset",preset:u})}):lt(p,"customEnvironment")?ue("div",{className:"se-field se-fieldInline","data-ri-path":"sceneConfig.environment.customEnvironmentUrl",children:[j("span",{className:"se-fieldLabel",children:"URL"}),j("input",{type:"text",className:"se-textInput","aria-label":"Custom environment URL",placeholder:"https://example.com/studio.hdr",value:o.customEnvironmentUrl,onChange:u=>S({...o,customEnvironmentUrl:u.target.value})}),o.customEnvironmentUrl.trim()&&!cd(o.customEnvironmentUrl)?j("span",{className:"bb-note bb-note--error se-fieldFull",children:"Use an HDR, EXR, JPG, PNG, or WEBP URL."}):null]}):j(Ye,{requiredTier:"starter",feature:"Custom environments"}),j(I,{label:"Intensity",path:"sceneConfig.environment.intensity",value:o.intensity,min:0,max:3,step:.05,onChange:u=>S({...o,intensity:u})}),j(I,{label:"Rotation",path:"sceneConfig.environment.rotation",value:o.rotation,min:0,max:360,step:1,formatValue:u=>`${u}\xB0`,onChange:u=>S({...o,rotation:u})}),j(fe,{label:"As background",path:"sceneConfig.background.type",checked:r.enabled&&r.type==="environment",onChange:u=>M(u?{...r,enabled:!0,type:"environment"}:{...r,type:"color"})}),j("p",{className:"bb-note se-fieldFull",children:"It always lights the model; this also draws it behind."})]}),ue(re,{title:"Environment shadow",open:x.envShadow,onToggle:()=>h("envShadow"),disabled:!o.shadowLight.enabled,trailing:j(de,{checked:o.shadowLight.enabled,onChange:u=>S({...o,shadowLight:{...o.shadowLight,enabled:u}}),label:"Toggle environment shadow light"}),children:[j(I,{label:"Light intensity",path:"sceneConfig.environment.shadowLight.intensity",value:o.shadowLight.intensity,min:0,max:20,step:.1,onChange:u=>S({...o,shadowLight:{...o.shadowLight,intensity:u}})}),j(I,{label:"Shadow bias",path:"sceneConfig.environment.shadowLight.bias",value:o.shadowLight.bias,min:-.01,max:.01,step:1e-4,onChange:u=>S({...o,shadowLight:{...o.shadowLight,bias:u}})})]}),ue(re,{title:"Background",open:x.background,onToggle:()=>h("background"),children:[j(bt,{label:"Show",path:"sceneConfig.background.type",value:r.enabled?r.type:"default",options:Ff,onChange:u=>M(u==="default"?{...r,enabled:!1}:{...r,enabled:!0,type:u})}),r.enabled?r.type==="image"&&!lt(p,"backgroundImages")?j(Ye,{requiredTier:"starter",feature:"Background images"}):r.type==="image"?ue("div",{className:"se-field se-fieldInline","data-ri-path":"sceneConfig.background.imageUrl",children:[j("label",{className:"se-fieldLabel",htmlFor:"se-background-image-url",children:"Image"}),ue("div",{className:"bb-fileField",children:[j("input",{id:"se-background-image-url",type:"text",className:"bb-input bb-fileField-input",placeholder:"Paste a link or upload",value:r.imageUrl,readOnly:g,onChange:u=>{s(null),M({...r,imageUrl:u.target.value})}}),g?j("button",{type:"button",className:"bb-fileFieldButton",onClick:()=>M({...r,imageUrl:""}),"aria-label":"Remove uploaded background image",title:"Remove uploaded image",children:j(nu,{size:13})}):j("button",{type:"button",className:"bb-fileFieldButton",onClick:()=>c.current?.click(),"aria-label":"Upload background image",title:"Upload image",children:j(jf,{size:13})}),j("input",{ref:c,type:"file",accept:If,className:"bb-hiddenInput",onChange:u=>{let v=u.target.files?.[0];u.target.value="",v&&y(v)}})]}),d?j("span",{className:"bb-note bb-note--error se-fieldFull",children:d}):g?j("span",{className:"bb-note se-fieldFull",children:"Uploaded files are bundled into the scene export."}):null]}):null:null,r.enabled&&r.type==="color"?j(St,{label:"Color",path:"sceneConfig.background.color",value:r.color,onChange:u=>M({...r,color:u})}):null]}),ue(re,{title:"Ground shadows",open:x.groundShadows,onToggle:()=>h("groundShadows"),disabled:!n.enabled,trailing:j(de,{checked:n.enabled,onChange:u=>B({...n,enabled:u}),label:"Toggle ground shadows"}),children:[j(I,{label:"Intensity",path:"sceneConfig.groundShadows.intensity",value:n.intensity,min:0,max:1,step:.01,onChange:u=>B({...n,intensity:u})}),j(I,{label:"Border fade",path:"sceneConfig.groundShadows.borderFade",value:n.borderFade,min:0,max:10,step:.1,onChange:u=>B({...n,borderFade:u})}),j(I,{label:"Height",path:"sceneConfig.groundShadows.height",value:n.height,min:-5,max:5,step:.1,onChange:u=>B({...n,height:u})}),j(I,{label:"Size",path:"sceneConfig.groundShadows.size",value:n.size,min:1,max:50,step:.5,onChange:u=>B({...n,size:u})})]})]})}import{useEffect as _f,useRef as Kf,useState as Tr}from"react";import{Lock as Gf,Plus as qf}from"lucide-react";import{jsx as pe,jsxs as Un}from"react/jsx-runtime";var Vf=["linear","reinhard","aces"];function su({pp:e,set:t,open:i,toggle:r}){let{colorAverage:o}=e;return pe(re,{title:"Color average",tooltip:"Blends the frame toward a single average color for a washed-out stylized look.",open:i.colorAverage,onToggle:()=>r("colorAverage"),disabled:!o.enabled,trailing:pe(de,{checked:o.enabled,onChange:n=>t("colorAverage",{...o,enabled:n}),label:"Toggle color average"}),children:pe("div",{className:"se-placeholder",children:"Averages the frame color using the docs default blend mode."})})}function lu({pp:e,set:t,open:i,toggle:r}){let{brightnessContrast:o}=e;return Un(re,{title:"Brightness and contrast",tooltip:"Raises or lowers overall brightness and contrast across the scene.",open:i.brightnessContrast,onToggle:()=>r("brightnessContrast"),disabled:!o.enabled,trailing:pe(de,{checked:o.enabled,onChange:n=>t("brightnessContrast",{...o,enabled:n}),label:"Toggle brightness contrast"}),children:[pe(I,{path:"sceneConfig.postProcessing.brightnessContrast.brightness",label:"Brightness",value:o.brightness,min:-1,max:1,step:.01,onChange:n=>t("brightnessContrast",{...o,brightness:n})}),pe(I,{path:"sceneConfig.postProcessing.brightnessContrast.contrast",label:"Contrast",value:o.contrast,min:-1,max:1,step:.01,onChange:n=>t("brightnessContrast",{...o,contrast:n})})]})}function du({pp:e,set:t,open:i,toggle:r}){let{hueSaturation:o}=e;return Un(re,{title:"Hue and saturation",tooltip:"Shifts the hue and saturation to tint the whole image.",open:i.hueSaturation,onToggle:()=>r("hueSaturation"),disabled:!o.enabled,trailing:pe(de,{checked:o.enabled,onChange:n=>t("hueSaturation",{...o,enabled:n}),label:"Toggle hue saturation"}),children:[pe(I,{path:"sceneConfig.postProcessing.hueSaturation.hue",label:"Hue",value:o.hue,min:-Math.PI,max:Math.PI,step:.01,formatValue:n=>`${n.toFixed(2)} rad`,onChange:n=>t("hueSaturation",{...o,hue:n})}),pe(I,{path:"sceneConfig.postProcessing.hueSaturation.saturation",label:"Saturation",value:o.saturation,min:-1,max:1,step:.01,onChange:n=>t("hueSaturation",{...o,saturation:n})})]})}function cu({pp:e,set:t,open:i,toggle:r}){let{vignette:o}=e;return Un(re,{title:"Vignette",tooltip:"Darkens the edges of the screen so the center feels more focused.",open:i.vignette,onToggle:()=>r("vignette"),disabled:!o.enabled,trailing:pe(de,{checked:o.enabled,onChange:n=>t("vignette",{...o,enabled:n}),label:"Toggle vignette"}),children:[pe(I,{path:"sceneConfig.postProcessing.vignette.offset",label:"Offset",value:o.offset,min:0,max:1,step:.01,onChange:n=>t("vignette",{...o,offset:n})}),pe(I,{path:"sceneConfig.postProcessing.vignette.darkness",label:"Darkness",value:o.darkness,min:0,max:1,step:.01,onChange:n=>t("vignette",{...o,darkness:n})}),pe(fe,{path:"sceneConfig.postProcessing.vignette.eskil",label:"Eskil",checked:o.eskil,onChange:n=>t("vignette",{...o,eskil:n})})]})}function uu({pp:e,set:t,open:i,toggle:r}){let{bloom:o}=e;return Un(re,{title:"Bloom",tooltip:"Makes bright areas glow and bleed softly into nearby pixels.",open:i.bloom,onToggle:()=>r("bloom"),disabled:!o.enabled,trailing:pe(de,{checked:o.enabled,onChange:n=>t("bloom",{...o,enabled:n}),label:"Toggle bloom"}),children:[pe(I,{path:"sceneConfig.postProcessing.bloom.luminanceThreshold",label:"Threshold",value:o.luminanceThreshold,min:0,max:1,step:.01,onChange:n=>t("bloom",{...o,luminanceThreshold:n})}),pe(I,{path:"sceneConfig.postProcessing.bloom.luminanceSmoothing",label:"Smoothing",value:o.luminanceSmoothing,min:0,max:1,step:.01,onChange:n=>t("bloom",{...o,luminanceSmoothing:n})}),pe(I,{path:"sceneConfig.postProcessing.bloom.intensity",label:"Intensity",value:o.intensity,min:0,max:3,step:.05,onChange:n=>t("bloom",{...o,intensity:n})}),pe(fe,{path:"sceneConfig.postProcessing.bloom.mipmapBlur",label:"Mipmap blur",checked:o.mipmapBlur,onChange:n=>t("bloom",{...o,mipmapBlur:n})}),pe(I,{path:"sceneConfig.postProcessing.bloom.radius",label:"Radius",value:o.radius,min:0,max:1,step:.01,onChange:n=>t("bloom",{...o,radius:n})}),pe(I,{path:"sceneConfig.postProcessing.bloom.levels",label:"Levels",value:o.levels,min:1,max:16,step:1,onChange:n=>t("bloom",{...o,levels:n})})]})}function pu({pp:e,set:t,open:i,toggle:r}){let{toneMapping:o}=e;return Un(re,{title:"Tone mapping",tooltip:"Remaps HDR lighting to screen output and controls exposure style.",open:i.toneMapping,onToggle:()=>r("toneMapping"),disabled:!o.enabled,trailing:pe(de,{checked:o.enabled,onChange:n=>t("toneMapping",{...o,enabled:n}),label:"Toggle tone mapping"}),children:[Un("div",{className:"se-field",children:[pe("span",{className:"se-fieldLabel",children:"Mode"}),pe("div",{className:"se-segmentedControl",children:Vf.map(n=>pe("button",{type:"button",className:`se-segmentedOption ${o.mode===n?"se-segmentedOption--active":""}`,onClick:()=>t("toneMapping",{...o,mode:n}),children:n==="aces"?"Filmic":n.charAt(0).toUpperCase()+n.slice(1)},n))})]}),pe(I,{path:"sceneConfig.postProcessing.toneMapping.resolution",label:"Resolution",value:o.resolution,min:64,max:4096,step:64,onChange:n=>t("toneMapping",{...o,resolution:n})}),pe(I,{path:"sceneConfig.postProcessing.toneMapping.whitePoint",label:"White point",value:o.whitePoint,min:0,max:16,step:.01,onChange:n=>t("toneMapping",{...o,whitePoint:n})}),pe(I,{path:"sceneConfig.postProcessing.toneMapping.middleGrey",label:"Middle grey",value:o.middleGrey,min:0,max:1,step:.01,onChange:n=>t("toneMapping",{...o,middleGrey:n})}),pe(I,{path:"sceneConfig.postProcessing.toneMapping.minLuminance",label:"Min luminance",value:o.minLuminance,min:0,max:1,step:.01,onChange:n=>t("toneMapping",{...o,minLuminance:n})}),pe(I,{path:"sceneConfig.postProcessing.toneMapping.averageLuminance",label:"Average luminance",value:o.averageLuminance,min:0,max:4,step:.01,onChange:n=>t("toneMapping",{...o,averageLuminance:n})}),pe(I,{path:"sceneConfig.postProcessing.toneMapping.adaptationRate",label:"Adaptation rate",value:o.adaptationRate,min:0,max:10,step:.01,onChange:n=>t("toneMapping",{...o,adaptationRate:n})}),pe(I,{path:"sceneConfig.postProcessing.toneMapping.exposure",label:"Exposure",value:o.exposure,min:0,max:3,step:.01,onChange:n=>t("toneMapping",{...o,exposure:n})})]})}function bu({pp:e,set:t,open:i,toggle:r}){let{sepia:o}=e;return pe(re,{title:"Sepia",tooltip:"Adds a warm vintage brown tint to the entire image.",open:i.sepia,onToggle:()=>r("sepia"),disabled:!o.enabled,trailing:pe(de,{checked:o.enabled,onChange:n=>t("sepia",{...o,enabled:n}),label:"Toggle sepia"}),children:pe(I,{path:"sceneConfig.postProcessing.sepia.intensity",label:"Intensity",value:o.intensity,min:0,max:1,step:.01,onChange:n=>t("sepia",{...o,intensity:n})})})}import{jsx as J,jsxs as yi}from"react/jsx-runtime";function mu({pp:e,set:t,open:i,toggle:r}){let{ssao:o}=e;return yi(re,{title:"Ambient occlusion",tooltip:"Adds soft contact shadows in corners, creases, and tight spaces.",open:i.ssao,onToggle:()=>r("ssao"),disabled:!o.enabled,trailing:J(de,{checked:o.enabled,onChange:n=>t("ssao",{...o,enabled:n}),label:"Toggle ssao"}),children:[J(I,{path:"sceneConfig.postProcessing.ssao.samples",label:"Samples",value:o.samples,min:1,max:64,step:1,onChange:n=>t("ssao",{...o,samples:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.rings",label:"Rings",value:o.rings,min:1,max:12,step:1,onChange:n=>t("ssao",{...o,rings:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.intensity",label:"Intensity",value:o.intensity,min:0,max:20,step:.5,onChange:n=>t("ssao",{...o,intensity:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.radius",label:"Radius",value:o.radius,min:.01,max:1,step:.01,onChange:n=>t("ssao",{...o,radius:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.bias",label:"Bias",value:o.bias,min:0,max:.1,step:.001,onChange:n=>t("ssao",{...o,bias:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.luminanceInfluence",label:"Luminance influence",value:o.luminanceInfluence,min:0,max:1,step:.01,onChange:n=>t("ssao",{...o,luminanceInfluence:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.fade",label:"Fade",value:o.fade,min:0,max:.1,step:.001,onChange:n=>t("ssao",{...o,fade:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.minRadiusScale",label:"Min radius scale",value:o.minRadiusScale,min:0,max:1,step:.01,onChange:n=>t("ssao",{...o,minRadiusScale:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.worldDistanceThreshold",label:"World distance threshold",value:o.worldDistanceThreshold,min:0,max:100,step:.1,onChange:n=>t("ssao",{...o,worldDistanceThreshold:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.worldDistanceFalloff",label:"World distance falloff",value:o.worldDistanceFalloff,min:0,max:20,step:.1,onChange:n=>t("ssao",{...o,worldDistanceFalloff:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.worldProximityThreshold",label:"World proximity threshold",value:o.worldProximityThreshold,min:0,max:100,step:.1,onChange:n=>t("ssao",{...o,worldProximityThreshold:n})}),J(I,{path:"sceneConfig.postProcessing.ssao.worldProximityFalloff",label:"World proximity falloff",value:o.worldProximityFalloff,min:0,max:20,step:.1,onChange:n=>t("ssao",{...o,worldProximityFalloff:n})})]})}function gu({pp:e,set:t,open:i,toggle:r}){let{autofocus:o}=e;return yi(re,{title:"Auto focus",tooltip:"Keeps the focus plane tracking a subject so the image stays sharp where you want it.",open:i.autofocus,onToggle:()=>r("autofocus"),disabled:!o.enabled,trailing:J(de,{checked:o.enabled,onChange:n=>t("autofocus",{...o,enabled:n}),label:"Toggle autofocus"}),children:[J(I,{path:"sceneConfig.postProcessing.autofocus.focusDistance",label:"Focus distance",value:o.focusDistance,min:0,max:50,step:.1,onChange:n=>t("autofocus",{...o,focusDistance:n})}),J(I,{path:"sceneConfig.postProcessing.autofocus.focusRange",label:"Focus range",value:o.focusRange,min:.1,max:50,step:.1,onChange:n=>t("autofocus",{...o,focusRange:n})}),J(I,{path:"sceneConfig.postProcessing.autofocus.focalLength",label:"Focal length",value:o.focalLength,min:0,max:1,step:.01,onChange:n=>t("autofocus",{...o,focalLength:n})}),J(I,{path:"sceneConfig.postProcessing.autofocus.bokehScale",label:"Bokeh scale",value:o.bokehScale,min:0,max:20,step:.1,onChange:n=>t("autofocus",{...o,bokehScale:n})}),J(kt,{path:"sceneConfig.postProcessing.autofocus.target",label:"Target",value:o.target,min:-100,max:100,step:.1,onChange:n=>t("autofocus",{...o,target:n})}),J(fe,{path:"sceneConfig.postProcessing.autofocus.mouse",label:"Mouse follow",checked:o.mouse,onChange:n=>t("autofocus",{...o,mouse:n})}),J(fe,{path:"sceneConfig.postProcessing.autofocus.manual",label:"Manual update",checked:o.manual,onChange:n=>t("autofocus",{...o,manual:n})}),J(I,{path:"sceneConfig.postProcessing.autofocus.debug",label:"Debug",value:o.debug,min:0,max:1,step:.01,onChange:n=>t("autofocus",{...o,debug:n})}),J(I,{path:"sceneConfig.postProcessing.autofocus.smoothTime",label:"Smooth time",value:o.smoothTime,min:0,max:2,step:.01,onChange:n=>t("autofocus",{...o,smoothTime:n})})]})}function fu({pp:e,set:t,open:i,toggle:r}){let{godRays:o}=e;return yi(re,{title:"God rays",tooltip:"Creates light shafts that streak outward from a bright sun or light source.",open:i.godRays,onToggle:()=>r("godRays"),disabled:!o.enabled,trailing:J(de,{checked:o.enabled,onChange:n=>t("godRays",{...o,enabled:n}),label:"Toggle god rays"}),children:[J(kt,{path:"sceneConfig.postProcessing.godRays.sunPosition",label:"Sun position",value:o.sunPosition,min:-100,max:100,step:.1,onChange:n=>t("godRays",{...o,sunPosition:n})}),J(I,{path:"sceneConfig.postProcessing.godRays.samples",label:"Samples",value:o.samples,min:1,max:128,step:1,onChange:n=>t("godRays",{...o,samples:n})}),J(I,{path:"sceneConfig.postProcessing.godRays.density",label:"Density",value:o.density,min:0,max:2,step:.01,onChange:n=>t("godRays",{...o,density:n})}),J(I,{path:"sceneConfig.postProcessing.godRays.decay",label:"Decay",value:o.decay,min:0,max:1,step:.01,onChange:n=>t("godRays",{...o,decay:n})}),J(I,{path:"sceneConfig.postProcessing.godRays.weight",label:"Weight",value:o.weight,min:0,max:2,step:.01,onChange:n=>t("godRays",{...o,weight:n})}),J(I,{path:"sceneConfig.postProcessing.godRays.exposure",label:"Exposure",value:o.exposure,min:0,max:2,step:.01,onChange:n=>t("godRays",{...o,exposure:n})}),J(I,{path:"sceneConfig.postProcessing.godRays.clampMax",label:"Clamp max",value:o.clampMax,min:0,max:2,step:.01,onChange:n=>t("godRays",{...o,clampMax:n})}),J(fe,{path:"sceneConfig.postProcessing.godRays.blur",label:"Blur",checked:o.blur,onChange:n=>t("godRays",{...o,blur:n})}),J(bt,{path:"sceneConfig.postProcessing.godRays.kernelSize",label:"Kernel size",value:o.kernelSize,options:ci,onChange:n=>t("godRays",{...o,kernelSize:n})})]})}function hu({pp:e,set:t,open:i,toggle:r}){let{lensflare:o}=e;return yi(re,{title:"Lens flare",tooltip:"Adds camera flare artifacts and glow from a bright light source.",open:i.lensflare,onToggle:()=>r("lensflare"),disabled:!o.enabled,trailing:J(de,{checked:o.enabled,onChange:n=>t("lensflare",{...o,enabled:n}),label:"Toggle lensflare"}),children:[J(kt,{path:"sceneConfig.postProcessing.lensflare.lensPosition",label:"Lens position",value:o.lensPosition,min:-100,max:100,step:.1,onChange:n=>t("lensflare",{...o,lensPosition:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.smoothTime",label:"Smooth time",value:o.smoothTime,min:0,max:1,step:.01,onChange:n=>t("lensflare",{...o,smoothTime:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.glareSize",label:"Glare size",value:o.glareSize,min:0,max:1,step:.01,onChange:n=>t("lensflare",{...o,glareSize:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.flareSize",label:"Flare size",value:o.flareSize,min:0,max:.1,step:.001,onChange:n=>t("lensflare",{...o,flareSize:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.flareSpeed",label:"Flare speed",value:o.flareSpeed,min:0,max:.2,step:.001,onChange:n=>t("lensflare",{...o,flareSpeed:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.flareShape",label:"Flare shape",value:o.flareShape,min:0,max:.2,step:.001,onChange:n=>t("lensflare",{...o,flareShape:n})}),J(fe,{path:"sceneConfig.postProcessing.lensflare.animated",label:"Animated",checked:o.animated,onChange:n=>t("lensflare",{...o,animated:n})}),J(fe,{path:"sceneConfig.postProcessing.lensflare.anamorphic",label:"Anamorphic",checked:o.anamorphic,onChange:n=>t("lensflare",{...o,anamorphic:n})}),J(St,{path:"sceneConfig.postProcessing.lensflare.colorGain",label:"Color gain",value:o.colorGain,onChange:n=>t("lensflare",{...o,colorGain:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.haloScale",label:"Halo scale",value:o.haloScale,min:0,max:2,step:.01,onChange:n=>t("lensflare",{...o,haloScale:n})}),J(fe,{path:"sceneConfig.postProcessing.lensflare.secondaryGhosts",label:"Secondary ghosts",checked:o.secondaryGhosts,onChange:n=>t("lensflare",{...o,secondaryGhosts:n})}),J(fe,{path:"sceneConfig.postProcessing.lensflare.aditionalStreaks",label:"Additional streaks",checked:o.aditionalStreaks,onChange:n=>t("lensflare",{...o,aditionalStreaks:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.ghostScale",label:"Ghost scale",value:o.ghostScale,min:0,max:1,step:.01,onChange:n=>t("lensflare",{...o,ghostScale:n})}),J(I,{path:"sceneConfig.postProcessing.lensflare.opacity",label:"Opacity",value:o.opacity,min:0,max:1,step:.01,onChange:n=>t("lensflare",{...o,opacity:n})}),J(fe,{path:"sceneConfig.postProcessing.lensflare.starBurst",label:"Star burst",checked:o.starBurst,onChange:n=>t("lensflare",{...o,starBurst:n})})]})}function xu({pp:e,set:t,open:i,toggle:r}){let{depthOfField:o}=e;return yi(re,{title:"Depth of field",tooltip:"Blurs areas that sit away from the focal plane for a camera-like look.",open:i.depthOfField,onToggle:()=>r("depthOfField"),disabled:!o.enabled,trailing:J(de,{checked:o.enabled,onChange:n=>t("depthOfField",{...o,enabled:n}),label:"Toggle depth of field"}),children:[J(I,{path:"sceneConfig.postProcessing.depthOfField.focusDistance",label:"Focus distance",value:o.focusDistance,min:0,max:50,step:.1,onChange:n=>t("depthOfField",{...o,focusDistance:n})}),J(I,{path:"sceneConfig.postProcessing.depthOfField.focusRange",label:"Focus range",value:o.focusRange,min:.1,max:50,step:.1,onChange:n=>t("depthOfField",{...o,focusRange:n})}),J(I,{path:"sceneConfig.postProcessing.depthOfField.focalLength",label:"Focal length",value:o.focalLength,min:0,max:1,step:.01,onChange:n=>t("depthOfField",{...o,focalLength:n})}),J(I,{path:"sceneConfig.postProcessing.depthOfField.bokehScale",label:"Bokeh scale",value:o.bokehScale,min:0,max:20,step:.1,onChange:n=>t("depthOfField",{...o,bokehScale:n})})]})}import{jsx as se,jsxs as Vn}from"react/jsx-runtime";function vu({pp:e,set:t,open:i,toggle:r}){let{dotScreen:o}=e;return Vn(re,{title:"Dot screen",tooltip:"Overlays a halftone dot pattern for a printed or retro look.",open:i.dotScreen,onToggle:()=>r("dotScreen"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("dotScreen",{...o,enabled:n}),label:"Toggle dot screen"}),children:[se(I,{path:"sceneConfig.postProcessing.dotScreen.angle",label:"Angle",value:o.angle,min:0,max:Math.PI*2,step:.01,formatValue:n=>`${n.toFixed(2)} rad`,onChange:n=>t("dotScreen",{...o,angle:n})}),se(I,{path:"sceneConfig.postProcessing.dotScreen.scale",label:"Scale",value:o.scale,min:.1,max:10,step:.05,onChange:n=>t("dotScreen",{...o,scale:n})})]})}function yu({pp:e,set:t,open:i,toggle:r}){let{glitch:o}=e;return Vn(re,{title:"Glitch",tooltip:"Introduces digital distortion, tearing, and scan noise.",open:i.glitch,onToggle:()=>r("glitch"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("glitch",{...o,enabled:n}),label:"Toggle glitch"}),children:[se(bt,{path:"sceneConfig.postProcessing.glitch.mode",label:"Mode",value:o.mode,options:md,onChange:n=>t("glitch",{...o,mode:n})}),se(tn,{path:"sceneConfig.postProcessing.glitch.delay",label:"Delay",value:o.delay,min:0,max:10,step:.01,onChange:n=>t("glitch",{...o,delay:n})}),se(tn,{path:"sceneConfig.postProcessing.glitch.duration",label:"Duration",value:o.duration,min:0,max:5,step:.01,onChange:n=>t("glitch",{...o,duration:n})}),se(tn,{path:"sceneConfig.postProcessing.glitch.strength",label:"Strength",value:o.strength,min:0,max:2,step:.01,onChange:n=>t("glitch",{...o,strength:n})}),se(tn,{path:"sceneConfig.postProcessing.glitch.chromaticAberrationOffset",label:"Chromatic aberration offset",value:o.chromaticAberrationOffset,min:0,max:.02,step:1e-4,onChange:n=>t("glitch",{...o,chromaticAberrationOffset:n})}),se(I,{path:"sceneConfig.postProcessing.glitch.columns",label:"Columns",value:o.columns,min:0,max:.5,step:.001,onChange:n=>t("glitch",{...o,columns:n})}),se(I,{path:"sceneConfig.postProcessing.glitch.ratio",label:"Ratio",value:o.ratio,min:0,max:1,step:.01,onChange:n=>t("glitch",{...o,ratio:n})})]})}function wu({pp:e,set:t,open:i,toggle:r}){let{grid:o}=e;return Vn(re,{title:"Grid",tooltip:"Adds a visual grid overlay that feels retro or debug-like.",open:i.grid,onToggle:()=>r("grid"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("grid",{...o,enabled:n}),label:"Toggle grid"}),children:[se(I,{path:"sceneConfig.postProcessing.grid.scale",label:"Scale",value:o.scale,min:.1,max:10,step:.05,onChange:n=>t("grid",{...o,scale:n})}),se(I,{path:"sceneConfig.postProcessing.grid.lineWidth",label:"Line width",value:o.lineWidth,min:0,max:1,step:.01,onChange:n=>t("grid",{...o,lineWidth:n})})]})}function Su({pp:e,set:t,open:i,toggle:r}){let{chromaticAberration:o}=e;return Vn(re,{title:"Chromatic aberration",tooltip:"Separates color channels slightly to mimic lens fringing.",open:i.chromaticAberration,onToggle:()=>r("chromaticAberration"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("chromaticAberration",{...o,enabled:n}),label:"Toggle chromatic aberration"}),children:[se(I,{path:"sceneConfig.postProcessing.chromaticAberration.offsetX",label:"Offset X",value:o.offsetX,min:0,max:.02,step:1e-4,onChange:n=>t("chromaticAberration",{...o,offsetX:n})}),se(I,{path:"sceneConfig.postProcessing.chromaticAberration.offsetY",label:"Offset Y",value:o.offsetY,min:0,max:.02,step:1e-4,onChange:n=>t("chromaticAberration",{...o,offsetY:n})}),se(fe,{path:"sceneConfig.postProcessing.chromaticAberration.radialModulation",label:"Radial modulation",checked:o.radialModulation,onChange:n=>t("chromaticAberration",{...o,radialModulation:n})}),se(I,{path:"sceneConfig.postProcessing.chromaticAberration.modulationOffset",label:"Modulation offset",value:o.modulationOffset,min:0,max:1,step:.01,onChange:n=>t("chromaticAberration",{...o,modulationOffset:n})})]})}function ku({pp:e,set:t,open:i,toggle:r}){let{noise:o}=e;return Vn(re,{title:"Noise",tooltip:"Adds film grain or static noise to the rendered image.",open:i.noise,onToggle:()=>r("noise"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("noise",{...o,enabled:n}),label:"Toggle noise"}),children:[se(I,{path:"sceneConfig.postProcessing.noise.opacity",label:"Amount",value:o.opacity,min:0,max:1,step:.01,onChange:n=>t("noise",{...o,opacity:n})}),se(fe,{path:"sceneConfig.postProcessing.noise.premultiply",label:"Premultiply",checked:o.premultiply,onChange:n=>t("noise",{...o,premultiply:n})})]})}function Cu({pp:e,set:t,open:i,toggle:r}){let{scanline:o}=e;return se(re,{title:"Scan lines",tooltip:"Draws horizontal CRT-style scan lines over the frame.",open:i.scanline,onToggle:()=>r("scanline"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("scanline",{...o,enabled:n}),label:"Toggle scanline"}),children:se(I,{path:"sceneConfig.postProcessing.scanline.density",label:"Density",value:o.density,min:0,max:10,step:.25,onChange:n=>t("scanline",{...o,density:n})})})}function Mu({pp:e,set:t,open:i,toggle:r}){let{pixelation:o}=e;return se(re,{title:"Pixelation",tooltip:"Reduces detail into larger pixels for a blocky stylized effect.",open:i.pixelation,onToggle:()=>r("pixelation"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("pixelation",{...o,enabled:n}),label:"Toggle pixelation"}),children:se(I,{path:"sceneConfig.postProcessing.pixelation.granularity",label:"Granularity",value:o.granularity,min:0,max:20,step:1,onChange:n=>t("pixelation",{...o,granularity:n})})})}function Pu({pp:e,set:t,open:i,toggle:r}){let{ramp:o}=e;return Vn(re,{title:"Color ramp",tooltip:"Adds a screen-space color gradient, or masks effects earlier in the stack.",open:i.ramp,onToggle:()=>r("ramp"),disabled:!o.enabled,trailing:se(de,{checked:o.enabled,onChange:n=>t("ramp",{...o,enabled:n}),label:"Toggle ramp"}),children:[se(bt,{path:"sceneConfig.postProcessing.ramp.rampType",label:"Ramp type",value:o.rampType,options:gd,onChange:n=>t("ramp",{...o,rampType:n})}),se(tn,{path:"sceneConfig.postProcessing.ramp.rampStart",label:"Ramp start",value:o.rampStart,min:0,max:1,step:.01,onChange:n=>t("ramp",{...o,rampStart:n})}),se(tn,{path:"sceneConfig.postProcessing.ramp.rampEnd",label:"Ramp end",value:o.rampEnd,min:0,max:1,step:.01,onChange:n=>t("ramp",{...o,rampEnd:n})}),se(St,{path:"sceneConfig.postProcessing.ramp.startColor",label:"Start color",value:o.startColor,onChange:n=>t("ramp",{...o,startColor:n})}),se(St,{path:"sceneConfig.postProcessing.ramp.endColor",label:"End color",value:o.endColor,onChange:n=>t("ramp",{...o,endColor:n})}),!o.rampMask&&se(I,{path:"sceneConfig.postProcessing.ramp.opacity",label:"Gradient opacity",value:o.opacity??.5,min:0,max:1,step:.01,onChange:n=>t("ramp",{...o,opacity:n})}),se(I,{path:"sceneConfig.postProcessing.ramp.rampBias",label:"Bias",value:o.rampBias,min:0,max:1,step:.01,onChange:n=>t("ramp",{...o,rampBias:n})}),se(I,{path:"sceneConfig.postProcessing.ramp.rampGain",label:"Gain",value:o.rampGain,min:0,max:1,step:.01,onChange:n=>t("ramp",{...o,rampGain:n})}),se(fe,{path:"sceneConfig.postProcessing.ramp.rampMask",label:"Mask earlier effects",checked:o.rampMask,onChange:n=>t("ramp",{...o,rampMask:n})}),se(fe,{path:"sceneConfig.postProcessing.ramp.rampInvert",label:"Invert",checked:o.rampInvert,onChange:n=>t("ramp",{...o,rampInvert:n})})]})}import{jsx as Oe,jsxs as Nu}from"react/jsx-runtime";function Bu({pp:e,set:t,open:i,toggle:r}){let{outline:o}=e;return Nu(re,{title:"Outline",tooltip:"Draws a visible edge around the selected object binding.",open:i.outline,onToggle:()=>r("outline"),disabled:!o.enabled,trailing:Oe(de,{checked:o.enabled,onChange:n=>t("outline",{...o,enabled:n}),label:"Toggle outline"}),children:[Oe("div",{className:"se-placeholder",children:"Outlines the currently selected object binding in the model editor."}),Oe(I,{path:"sceneConfig.postProcessing.outline.selectionLayer",label:"Selection layer",value:o.selectionLayer,min:0,max:20,step:1,onChange:n=>t("outline",{...o,selectionLayer:n})}),Oe(I,{path:"sceneConfig.postProcessing.outline.edgeStrength",label:"Edge strength",value:o.edgeStrength,min:0,max:10,step:.1,onChange:n=>t("outline",{...o,edgeStrength:n})}),Oe(I,{path:"sceneConfig.postProcessing.outline.pulseSpeed",label:"Pulse speed",value:o.pulseSpeed,min:0,max:10,step:.1,onChange:n=>t("outline",{...o,pulseSpeed:n})}),Oe(St,{path:"sceneConfig.postProcessing.outline.visibleEdgeColor",label:"Visible edge color",value:o.visibleEdgeColor,onChange:n=>t("outline",{...o,visibleEdgeColor:n})}),Oe(St,{path:"sceneConfig.postProcessing.outline.hiddenEdgeColor",label:"Hidden edge color",value:o.hiddenEdgeColor,onChange:n=>t("outline",{...o,hiddenEdgeColor:n})}),Oe(bt,{path:"sceneConfig.postProcessing.outline.kernelSize",label:"Kernel size",value:o.kernelSize,options:ci,onChange:n=>t("outline",{...o,kernelSize:n})}),Oe(fe,{path:"sceneConfig.postProcessing.outline.blur",label:"Blur",checked:o.blur,onChange:n=>t("outline",{...o,blur:n})}),Oe(fe,{path:"sceneConfig.postProcessing.outline.xRay",label:"X-Ray",checked:o.xRay,onChange:n=>t("outline",{...o,xRay:n})})]})}function Tu({pp:e,set:t,open:i,toggle:r}){let{selectiveBloom:o}=e;return Nu(re,{title:"Selective bloom",tooltip:"Applies bloom only to objects assigned to the selected layer.",open:i.selectiveBloom,onToggle:()=>r("selectiveBloom"),disabled:!o.enabled,trailing:Oe(de,{checked:o.enabled,onChange:n=>t("selectiveBloom",{...o,enabled:n}),label:"Toggle selective bloom"}),children:[Oe("div",{className:"se-placeholder",children:"Applies bloom to the currently selected object binding."}),Oe(I,{path:"sceneConfig.postProcessing.selectiveBloom.selectionLayer",label:"Selection layer",value:o.selectionLayer,min:0,max:20,step:1,onChange:n=>t("selectiveBloom",{...o,selectionLayer:n})}),Oe(I,{path:"sceneConfig.postProcessing.selectiveBloom.intensity",label:"Intensity",value:o.intensity,min:0,max:5,step:.05,onChange:n=>t("selectiveBloom",{...o,intensity:n})}),Oe(I,{path:"sceneConfig.postProcessing.selectiveBloom.luminanceThreshold",label:"Threshold",value:o.luminanceThreshold,min:0,max:1,step:.01,onChange:n=>t("selectiveBloom",{...o,luminanceThreshold:n})}),Oe(I,{path:"sceneConfig.postProcessing.selectiveBloom.luminanceSmoothing",label:"Smoothing",value:o.luminanceSmoothing,min:0,max:1,step:.01,onChange:n=>t("selectiveBloom",{...o,luminanceSmoothing:n})}),Oe(bt,{path:"sceneConfig.postProcessing.selectiveBloom.kernelSize",label:"Kernel size",value:o.kernelSize,options:ci,onChange:n=>t("selectiveBloom",{...o,kernelSize:n})}),Oe(fe,{path:"sceneConfig.postProcessing.selectiveBloom.mipmapBlur",label:"Mipmap blur",checked:o.mipmapBlur,onChange:n=>t("selectiveBloom",{...o,mipmapBlur:n})}),Oe(fe,{path:"sceneConfig.postProcessing.selectiveBloom.inverted",label:"Inverted",checked:o.inverted,onChange:n=>t("selectiveBloom",{...o,inverted:n})}),Oe(fe,{path:"sceneConfig.postProcessing.selectiveBloom.ignoreBackground",label:"Ignore background",checked:o.ignoreBackground,onChange:n=>t("selectiveBloom",{...o,ignoreBackground:n})})]})}function Ru({pp:e,set:t,open:i,toggle:r}){let{smaa:o}=e;return Oe(re,{title:"Anti-aliasing",tooltip:"Reduces jagged edges with subpixel anti-aliasing.",open:i.smaa,onToggle:()=>r("smaa"),trailing:Oe(de,{checked:o.enabled,onChange:n=>t("smaa",{...o,enabled:n}),label:"Toggle smaa"}),children:Oe("div",{className:"se-placeholder",children:"Subpixel Morphological Anti-Aliasing smooths jagged edges in post-process."})})}import{jsx as to,jsxs as wi}from"react/jsx-runtime";var Au=[{key:"toneMapping",label:"Tone mapping",group:"Color",Section:pu},{key:"brightnessContrast",label:"Brightness and contrast",group:"Color",Section:lu},{key:"hueSaturation",label:"Hue and saturation",group:"Color",Section:du},{key:"colorAverage",label:"Color average",group:"Color",Section:su},{key:"sepia",label:"Sepia",group:"Color",Section:bu},{key:"vignette",label:"Vignette",group:"Color",Section:cu},{key:"bloom",label:"Bloom",group:"Lighting",Section:uu},{key:"ssao",label:"Ambient occlusion",hint:"SSAO",group:"Lighting",feature:"postLighting",Section:mu},{key:"depthOfField",label:"Depth of field",group:"Lighting",feature:"postLighting",Section:xu},{key:"autofocus",label:"Auto focus",group:"Lighting",feature:"postLighting",Section:gu},{key:"godRays",label:"God rays",group:"Lighting",feature:"postLighting",Section:fu},{key:"lensflare",label:"Lens flare",group:"Lighting",feature:"postLighting",Section:hu},{key:"outline",label:"Outline",group:"Selection",feature:"postSelection",Section:Bu},{key:"selectiveBloom",label:"Selective bloom",group:"Selection",feature:"postSelection",Section:Tu},{key:"smaa",label:"Anti-aliasing",hint:"SMAA",group:"Selection",feature:"postSelection",Section:Ru},{key:"chromaticAberration",label:"Chromatic aberration",group:"Stylize",feature:"postSelection",Section:Su},{key:"dotScreen",label:"Dot screen",group:"Stylize",feature:"postSelection",Section:vu},{key:"glitch",label:"Glitch",group:"Stylize",feature:"postSelection",Section:yu},{key:"grid",label:"Grid",group:"Stylize",feature:"postSelection",Section:wu},{key:"noise",label:"Noise",group:"Stylize",feature:"postSelection",Section:ku},{key:"pixelation",label:"Pixelation",group:"Stylize",feature:"postSelection",Section:Mu},{key:"ramp",label:"Color ramp",group:"Stylize",feature:"postSelection",Section:Pu},{key:"scanline",label:"Scan lines",group:"Stylize",feature:"postSelection",Section:Cu}],Wf=["Color","Lighting","Selection","Stylize"],Yf={postLighting:"starter",postSelection:"growth"};function es({config:e,onChange:t}){let[i,r]=Tr({}),[o,n]=Tr(()=>new Set),[c,d]=Tr(!1),[s,g]=Tr(null),p=Kf(null);On([p],()=>d(!1),c),_f(()=>{if(!c)return;let m=N=>{N.key==="Escape"&&d(!1)};return window.addEventListener("keydown",m),()=>window.removeEventListener("keydown",m)},[c]);let x=m=>r(N=>({...N,[m]:!N[m]})),{tier:b}=dt(),h=e.postProcessing,M=(m,N)=>t({...e,postProcessing:{...h,[m]:N}}),S=m=>!m.feature||lt(b,m.feature),B=Au.filter(m=>S(m)&&(h[m.key]?.enabled===!0||o.has(m.key))),y=Au.filter(m=>!B.includes(m)),u={pp:h,set:M,open:i,toggle:x},v=m=>{if(d(!1),!S(m)){g(m);return}g(null),n(N=>new Set(N).add(m.key)),r(N=>({...N,[m.key]:!0})),M(m.key,{...h[m.key],enabled:!0})};return wi("div",{className:"se-generalContent",children:[wi("div",{className:"se-listHeader",ref:p,children:[to("span",{children:"Effects"}),wi("button",{type:"button",className:"bb-button bb-button--ghost bb-button--small","aria-expanded":c,disabled:!y.length,onClick:()=>d(m=>!m),children:[to(qf,{size:13,"aria-hidden":"true"}),"Add effect"]}),c?to("div",{className:"se-addMenu",role:"menu","aria-label":"Add effect",children:Wf.map(m=>{let N=y.filter(A=>A.group===m);return N.length?wi("div",{role:"group","aria-label":m,children:[to("h6",{children:m}),N.map(A=>wi("button",{type:"button",role:"menuitem",onClick:()=>v(A),children:[to("span",{children:A.label}),A.hint?to("small",{children:A.hint}):null,S(A)?null:to(Gf,{size:12,"aria-label":"Needs an upgrade"})]},A.key))]},m):null})}):null]}),s?.feature?to(Ye,{requiredTier:Yf[s.feature],feature:s.label}):null,B.length?null:to("p",{className:"se-listEmpty",children:"Add an effect to shape the final image, starting with tone mapping or bloom."}),B.map(({key:m,Section:N})=>to(N,{...u},m))]})}import{useState as Ou,useSyncExternalStore as Jf}from"react";import{Eye as Xf,EyeOff as Zf,Plus as Qf,Trash2 as eh}from"lucide-react";import{Fragment as ih,jsx as ve,jsxs as yo}from"react/jsx-runtime";var th=["512","1024","2048","4096"],Eu={none:"None",directional:"Directional",point:"Point",spot:"Spot",hemisphere:"Hemisphere"};function oh({index:e,light:t,selected:i,onSelect:r,onToggleVisible:o}){return yo("div",{className:`se-lightRow ${i?"se-lightRow--active":""}`,onClick:r,children:[yo("span",{className:"se-lightRowLabel",children:[e+1,": ",Eu[t.type]]}),ve("button",{type:"button",className:"se-iconButton","aria-label":t.visible?"Hide light":"Show light",onClick:n=>{n.stopPropagation(),o()},children:t.visible?ve(Xf,{size:14}):ve(Zf,{size:14})})]})}function nh(){return{id:crypto.randomUUID(),type:"directional",color:"#ffffff",intensity:1,position:[2.5,5,2.5],attachedToCamera:!1,castShadow:!1,shadowBias:-5e-4,visible:!0}}function ts({config:e,onChange:t}){let[i,r]=Ou({lights:!0,shadows:!1,groundShadows:!1,environment:!1,envShadow:!1}),o=Jf(_d,Kd),[n,c]=Ou(e.lighting.lights[0]?.id??null),d=o??n,s=T=>{c(T),Vd(T)},g=T=>r(D=>({...D,[T]:!D[T]})),{tier:p}=dt(),{lighting:x,shadows:b,groundShadows:h,environment:M}=e,S=T=>t({...e,lighting:T}),B=T=>t({...e,shadows:T}),y=T=>t({...e,groundShadows:T}),u=T=>t({...e,environment:T}),v=(T,D)=>{S({...x,lights:x.lights.map(k=>k.id===T?{...k,...D}:k)})},m=x.lights.find(T=>T.id===d)??null,N=()=>{let T=nh();S({...x,lights:[...x.lights,T]}),s(T.id)},A=()=>{if(!m)return;let T=x.lights.filter(D=>D.id!==m.id);S({...x,lights:T}),s(T[0]?.id??null)},K=Ot(p,"lights",x.lights.length);return yo("div",{className:"se-generalContent",children:[yo(re,{title:"Lights",open:i.lights,onToggle:()=>g("lights"),trailing:yo("span",{className:"se-listHeaderActions",children:[m&&x.lights.length>1?ve("button",{type:"button",className:"se-iconButton",onClick:A,title:"Remove selected light","aria-label":"Remove selected light",children:ve(eh,{size:13})}):null,ve("button",{type:"button",className:"se-iconButton",onClick:N,disabled:!K,title:"Add light","aria-label":"Add light",children:ve(Qf,{size:14})})]}),children:[ve("div",{className:"se-lightList",children:x.lights.map((T,D)=>ve(oh,{index:D,light:T,selected:T.id===d,onSelect:()=>s(T.id),onToggleVisible:()=>v(T.id,{visible:!T.visible})},T.id))}),K?null:ve(Ye,{requiredTier:en("lights",x.lights.length),feature:"More lights"}),m?yo("div",{className:"se-lightProps",children:[yo("div",{className:"se-field se-fieldInline","data-ri-path":"sceneConfig.lighting.lights[\u2026].type",children:[ve("span",{className:"se-fieldLabel",children:"Type"}),ve(et,{className:"se-select",value:m.type,onChange:T=>v(m.id,{type:T.target.value}),children:ud.map(T=>ve("option",{value:T,children:Eu[T]},T))})]}),ve(St,{path:"sceneConfig.lighting.lights[\u2026].color",label:"Color",value:m.color,onChange:T=>v(m.id,{color:T})}),ve(I,{path:"sceneConfig.lighting.lights[\u2026].intensity",label:"Intensity",value:m.intensity,min:0,max:10,step:.1,onChange:T=>v(m.id,{intensity:T})}),m.type!=="hemisphere"&&m.type!=="none"&&ve(kt,{path:"sceneConfig.lighting.lights[\u2026].position",label:"Position",value:m.position,min:-100,max:100,step:.05,onChange:T=>v(m.id,{position:T})}),(m.type==="spot"||m.type==="directional")&&ve(kt,{path:"sceneConfig.lighting.lights[\u2026].target",label:"Target",value:m.target??[0,0,0],min:-100,max:100,step:.05,onChange:T=>v(m.id,{target:T})}),m.type==="spot"&&yo(ih,{children:[ve(I,{path:"sceneConfig.lighting.lights[\u2026].angle",label:"Angle",value:m.angle??Math.PI/6,min:0,max:Math.PI/2,step:.01,formatValue:T=>`${Math.round(T*180/Math.PI)}\xB0`,onChange:T=>v(m.id,{angle:T})}),ve(I,{path:"sceneConfig.lighting.lights[\u2026].penumbra",label:"Penumbra",value:m.penumbra??.2,min:0,max:1,step:.01,onChange:T=>v(m.id,{penumbra:T})}),ve(I,{path:"sceneConfig.lighting.lights[\u2026].distance",label:"Distance",value:m.distance??0,min:0,max:100,step:.5,onChange:T=>v(m.id,{distance:T})}),ve(I,{path:"sceneConfig.lighting.lights[\u2026].decay",label:"Decay",value:m.decay??2,min:0,max:4,step:.1,onChange:T=>v(m.id,{decay:T})})]}),ve(fe,{path:"sceneConfig.lighting.lights[\u2026].attachedToCamera",label:"Attached to camera",checked:m.attachedToCamera,onChange:T=>v(m.id,{attachedToCamera:T})}),ve(fe,{path:"sceneConfig.lighting.lights[\u2026].castShadow",label:"Cast shadows",checked:m.castShadow,onChange:T=>v(m.id,{castShadow:T})}),ve(I,{path:"sceneConfig.lighting.lights[\u2026].shadowBias",label:"Shadow bias",value:m.shadowBias,min:-.01,max:.01,step:1e-4,onChange:T=>v(m.id,{shadowBias:T}),disabled:!m.castShadow||!b.enabled}),!m.castShadow||!b.enabled?ve("span",{className:"bb-note",children:b.enabled?"Turn on Cast shadows for this light to use Shadow bias.":"Turn on Shadows below to use Shadow bias."}):null]}):null]}),yo(re,{title:"Shadows",open:i.shadows,onToggle:()=>g("shadows"),disabled:!b.enabled,trailing:ve(de,{checked:b.enabled,onChange:T=>B({...b,enabled:T}),label:"Toggle shadows"}),children:[ve(bt,{label:"Map size",value:String(b.mapSize),options:th,onChange:T=>B({...b,mapSize:Number(T)})}),ve(I,{path:"sceneConfig.shadows.bias",label:"Bias",value:b.bias,min:-.01,max:.01,step:1e-4,onChange:T=>B({...b,bias:T})}),ve(I,{path:"sceneConfig.shadows.normalBias",label:"Normal bias",value:b.normalBias,min:0,max:.2,step:.01,onChange:T=>B({...b,normalBias:T})}),ve(I,{path:"sceneConfig.shadows.radius",label:"Radius (softness)",value:b.radius,min:0,max:20,step:.5,onChange:T=>B({...b,radius:T})})]})]})}import{lazy as rh,Suspense as ah}from"react";import{jsx as os}from"react/jsx-runtime";function Do(e){let t=rh(e);return function(r){return os(ah,{fallback:os("p",{className:"bb-panelEmpty",children:"Loading\u2026"}),children:os(t,{...r})})}}import{jsx as ln,jsxs as ch}from"react/jsx-runtime";var sh=Do(()=>import("./RulesTab-2U4MFYOZ.mjs")),ju=[{id:"model",label:"Model"},{id:"camera",label:"Camera"},{id:"world",label:"World"},{id:"lighting",label:"Lights"},{id:"postProcessing",label:"Effects"},{id:"rules",label:"Rules"}],lh=[],dh={};function ns({diagnostics:e,onDiagnosticsOpenChange:t,config:i,onChange:r,activeSubTab:o,materialVariantGroups:n=lh,onImageFile:c,objectBindings:d=dh,limitBounds:s}){let{tier:g}=dt();return ch("div",{className:"se-tabContent",children:[o==="model"&&ln(iu,{diagnostics:e,onDiagnosticsOpenChange:t,config:i,onChange:r,materialVariantGroups:n}),o==="camera"&&ln(ru,{config:i,onChange:r,limitBounds:s}),o==="world"&&ln(au,{config:i,onChange:r,onImageFile:c}),o==="lighting"&&ln(ts,{config:i,onChange:r}),o==="postProcessing"&&ln(es,{config:i,onChange:r}),o==="rules"&&(lt(g,"rules")?ln(sh,{config:i,onChange:r,objectBindings:d}):ln(Ye,{requiredTier:"growth",feature:"Rules"}))]})}import{ChevronRight as Lu,Info as Iu}from"lucide-react";import{jsx as oo,jsxs as _n}from"react/jsx-runtime";function Du({title:e,trailing:t,children:i,disabled:r,open:o,onToggle:n,tooltip:c}){return _n("div",{className:"bb-materialPanel","data-ri-section":e,children:[_n("div",{className:"bb-materialPanelHeaderRow",children:[_n("button",{type:"button",className:"bb-materialPanelHeader",onClick:n,"aria-expanded":o,title:c,children:[oo(Lu,{size:13,className:`bb-materialPanelChevron ${o?"bb-materialPanelChevron--open":""}`}),oo("span",{className:"bb-materialPanelTitle",children:e}),c?oo(Iu,{size:11,className:"bb-materialPanelHelp","aria-hidden":"true"}):null]}),t?oo("span",{className:"bb-materialPanelTrailing",children:t}):null]}),o?oo("div",{className:`bb-materialPanelBody ${r?"bb-materialPanelBody--disabled":""}`,children:i}):null]})}function Je({title:e,open:t,onToggle:i,trailing:r,children:o,tooltip:n}){return _n("div",{className:"bb-section","data-ri-section":e,children:[_n("div",{className:"bb-sectionHeaderRow",children:[_n("button",{type:"button",className:"bb-sectionHeaderButton",onClick:i,"aria-expanded":t,title:n,children:[oo(Lu,{size:13,className:`bb-sectionChevron ${t?"bb-sectionChevron--open":""}`}),oo("h2",{className:"bb-sectionTitle",children:e}),n?oo(Iu,{size:11,className:"bb-sectionHelp","aria-hidden":"true"}):null]}),r?oo("span",{className:"bb-sectionHeaderTrailing",children:r}):null]}),t?oo("div",{className:"bb-sectionBody",children:o}):null]})}import{Copy as uh,Plus as ph,Scan as bh,Trash2 as mh}from"lucide-react";import{Fragment as gh,jsx as Ee,jsxs as no}from"react/jsx-runtime";function is(e){let t=e.assets.find(o=>o.url===e.activeUrl),i=t?.placement??{},r=e.assets.length<2?"Use Remove model to clear the last model":e.deleteIsPermanent?"Delete model":"Delete model (undoable)";return no("div",{className:"ri-assets",children:[no(lc,{title:"Models",children:[Ee("button",{type:"button",className:"se-iconButton",title:"Frame all models","aria-label":"Frame all models",onClick:e.onFrameAll,children:Ee(bh,{size:13})}),Ee("button",{type:"button",className:"se-iconButton",title:"Add model","aria-label":"Add model",disabled:e.busy||!!e.addRequiresTier,onClick:e.onAdd,children:Ee(ph,{size:14})})]}),e.addRequiresTier?Ee(Ye,{requiredTier:e.addRequiresTier,feature:"More models in a project"}):null,Ee("ul",{className:"ri-assets-list","aria-label":"Models in this scene",children:e.assets.map(o=>Ee("li",{children:no("button",{type:"button",className:o.url===e.activeUrl?"ri-assets-item is-active":"ri-assets-item","aria-pressed":o.url===e.activeUrl,onClick:()=>e.onSelect(o.url),children:[Ee("span",{className:"ri-assets-itemName",children:o.displayName??o.placement.label??o.name}),Ee("small",{children:o.placement.visible===!1?"Hidden":o.ready?null:"Loading"})]})},o.id))}),t&&no(gh,{children:[no(Fa,{title:"Placement",children:[Ee(pt,{label:"Name",children:Ee("input",{className:"se-textInput","aria-label":"Model name",value:i.label??t.name,maxLength:512,onChange:o=>e.onChange(t.id,{label:o.target.value})})}),Ee(fe,{label:"Visible",checked:i.visible!==!1,onChange:o=>e.onChange(t.id,{visible:o})}),Ee(kt,{min:-1e6,max:1e6,label:"Position",value:i.position??[0,0,0],step:.1,onChange:o=>e.onChange(t.id,{position:o})}),Ee(kt,{min:-1e6,max:1e6,label:"Rotation",value:(i.rotation??[0,0,0]).map(o=>o*180/Math.PI),step:1,onChange:o=>e.onChange(t.id,{rotation:o.map(n=>n*Math.PI/180)})}),Ee(kt,{min:-1e6,max:1e6,label:"Scale",value:i.scale??[1,1,1],step:.1,onChange:o=>{o.every(n=>n!==0)&&e.onChange(t.id,{scale:o})}})]}),no(Fa,{title:"Align",children:[Ee(pt,{label:"Grid spacing",children:Ee("input",{className:"se-numberInput","aria-label":"Grid spacing",type:"number",min:.001,step:.1,value:e.composition.gridSize,onChange:o=>{let n=Number(o.target.value);Number.isFinite(n)&&n>0&&e.onGridSize(n)}})}),no(go,{children:[Ee("button",{type:"button",className:"bb-button",onClick:()=>e.onSnap(t.id),children:"Snap to grid"}),Ee("button",{type:"button",className:"bb-button",disabled:!t.ready,onClick:()=>e.onGround(t.url),children:"Place on ground"})]})]}),no(go,{children:[no("button",{type:"button",className:"bb-button",disabled:e.busy||!t.ready,onClick:()=>e.onDuplicate(t.url),children:[Ee(uh,{size:13,"aria-hidden":"true"}),"Duplicate"]}),no("button",{type:"button",className:"bb-button",disabled:e.busy||e.assets.length<2,title:r,onClick:()=>e.onDelete(t.url),children:[Ee(mh,{size:13,"aria-hidden":"true"}),"Delete"]})]}),Ee("p",{className:"rui-footnote",title:"Instance ID",children:Ee("code",{children:t.id})})]})]})}import{useEffect as fh,useId as hh,useRef as zu,useState as xh}from"react";import{ChevronDown as vh,Download as yh,FileArchive as wh,FileCode2 as Sh,FileJson as Fu,Upload as kh}from"lucide-react";import{jsx as jt,jsxs as Rr}from"react/jsx-runtime";function Hu({action:e,groups:t,busy:i}){let[r,o]=xh(!1),n=zu(null),c=zu(null),d=hh(),s=i||t.every(g=>g.options.every(p=>p.disabled));return fh(()=>{if(!r)return;let g=p=>{n.current?.contains(p.target)||o(!1)};return window.addEventListener("pointerdown",g),()=>window.removeEventListener("pointerdown",g)},[r]),Rr("div",{className:"bb-exportMenuWrapper",ref:n,onKeyDown:g=>{g.key!=="Escape"||!r||(g.preventDefault(),g.stopPropagation(),o(!1),c.current?.focus())},children:[Rr("button",{ref:c,type:"button",className:e==="Export"?"bb-button bb-button--primary":"bb-barButton",disabled:s,"aria-busy":i||void 0,onClick:()=>o(g=>!g),title:`${e} files`,"aria-label":`${e} files`,"aria-expanded":r,"aria-controls":r?d:void 0,children:[e==="Import"?jt(kh,{size:14,"aria-hidden":"true"}):jt(yh,{size:14,"aria-hidden":"true"}),e,jt(vh,{size:12})]}),r&&jt("div",{className:"bb-exportMenu",id:d,role:"group","aria-label":`${e} options`,children:t.map((g,p)=>Rr("div",{className:"bb-fileMenuScope",children:[jt("div",{className:"bb-exportMenuTitle",children:g.title}),jt("p",{className:"bb-exportMenuDescription",id:`${d}-${p}`,children:g.description}),g.options.map(x=>Rr("button",{type:"button",className:"bb-exportMenuItem",disabled:x.disabled||i,"aria-label":`${e} ${x.label}`,"aria-describedby":`${d}-${p}`,onClick:()=>{o(!1),x.run()},children:[x.icon,x.label]},x.label))]},g.title))})]})}function $u(e,t,i){return[...i?[{title:"Complete scene",description:"Every model, placement, texture, binding, and scene setting. Remote assets keep their URLs.",options:[{label:"Complete scene ZIP",icon:jt(wh,{size:14}),disabled:e==="Import"?i.importDisabled:i.exportDisabled,run:e==="Import"?i.onImport:i.onExport}]}]:[],...t.map(r=>({title:r.title,description:r.description,options:e==="Import"?[{label:`${r.title} JSON`,icon:jt(Fu,{size:14}),disabled:r.importDisabled,run:r.onImport}]:[{label:`${r.title} JSON`,icon:jt(Fu,{size:14}),disabled:r.exportDisabled,run:r.onExportJson},{label:`${r.title} TypeScript`,icon:jt(Sh,{size:14}),disabled:r.exportDisabled,run:r.onExportTs}]}))]}function Uu({scopes:e,sceneBundle:t,busy:i}){return jt(Hu,{action:"Export",groups:$u("Export",e,t),busy:i})}function Vu({scopes:e,sceneBundle:t,busy:i}){return jt(Hu,{action:"Import",groups:$u("Import",e,t),busy:i})}import{Box as Ch,ChevronDown as Mh,CodeXml as Ph,Maximize2 as Bh,MousePointer2 as Th,Move3d as Rh,Redo2 as Nh,Rotate3d as Ah,Search as Oh,SquareSplitHorizontal as Eh,Undo2 as jh}from"lucide-react";import{jsx as Se,jsxs as Kn}from"react/jsx-runtime";var Nr=[{id:"select",label:"Select",shortcut:"V",icon:Se(Th,{size:15})},{id:"move",label:"Move",shortcut:"G",icon:Se(Rh,{size:15})},{id:"rotate",label:"Rotate",shortcut:"R",icon:Se(Ah,{size:15})},{id:"scale",label:"Scale",shortcut:"T",icon:Se(Bh,{size:15})}],Lh=typeof navigator<"u"&&/Mac|iPhone|iPad/.test(navigator.platform)?"\u2318K":"Ctrl K";function _u({modelName:e,modelMenu:t,canUndo:i,canRedo:r,undoTarget:o,onUndo:n,onRedo:c,tool:d,onToolChange:s,space:g,onSpaceChange:p,hasModel:x,compareOpen:b,onToggleCompare:h,codeOpen:M,onToggleCode:S,onOpenCommands:B,start:y,xrToolsSlot:u,fileActions:v}){return Kn("header",{className:"bb-topBar",children:[Se("span",{className:"bb-topBarLogo",role:"img","aria-label":"Binding Builder",children:Se(Ch,{size:14,"aria-hidden":"true"})}),t?Se(Hn,{label:e,title:"Model actions",children:t}):Se("span",{className:"bb-topBarModel",children:e}),y,Se("span",{className:"bb-topBarDivider"}),Se("button",{type:"button",className:"bb-toolButton",disabled:!i,onClick:n,title:`Undo ${o} change (Cmd/Ctrl+Z)`,"aria-label":`Undo ${o} change`,children:Se(jh,{size:15})}),Se("button",{type:"button",className:"bb-toolButton",disabled:!r,onClick:c,title:`Redo ${o} change (Cmd/Ctrl+Shift+Z)`,"aria-label":`Redo ${o} change`,children:Se(Nh,{size:15})}),Se("span",{className:"bb-topBarDivider"}),Se("div",{className:"bb-toolGroup",role:"radiogroup","aria-label":"Transform tool",children:Nr.map(m=>Se("button",{type:"button",role:"radio","aria-checked":d===m.id,"aria-label":`${m.label} tool`,disabled:!x,className:`bb-toolButton ${d===m.id?"bb-toolButton--active":""}`,onClick:()=>s(m.id),title:`${m.label} (${m.shortcut})`,children:m.icon},m.id))}),Kn("label",{className:"bb-topBarSelect",title:"Transform axes",children:[Se("span",{className:"bb-visuallyHidden",children:"Transform axes"}),Kn(et,{value:g,onChange:m=>p(m.target.value),children:[Se("option",{value:"world",children:"World"}),Se("option",{value:"local",children:"Local"})]}),Se(Mh,{size:12,"aria-hidden":"true"})]}),Se("span",{className:"bb-topBarSpacer"}),Kn("button",{type:"button",className:"bb-commandButton",onClick:B,"aria-keyshortcuts":"Meta+K Control+K",children:[Se(Oh,{size:13,"aria-hidden":"true"}),Se("span",{children:"Search settings"}),Se("kbd",{children:Lh})]}),Se("span",{className:"bb-topBarSpacer"}),Se("span",{ref:u,className:"bb-topBarXR"}),x?Kn("button",{type:"button",className:`bb-barButton ${b?"bb-barButton--active":""}`,onClick:h,"aria-pressed":b,title:"Drag a divider across the preview to see it before and after your changes",children:[Se(Eh,{size:14,"aria-hidden":"true"}),"Compare"]}):null,Kn("button",{type:"button",className:`bb-barButton ${M?"bb-barButton--active":""}`,onClick:S,"aria-pressed":M,title:"Show the code this editor produces",children:[Se(Ph,{size:14,"aria-hidden":"true"}),"Code"]}),v]})}import{Line as Ku}from"@react-three/drei";import{jsx as Ar,jsxs as qu}from"react/jsx-runtime";var rs="#35c0dc",Gu=.01;function Wu({outline:e,visible:t}){let i=Br(),r=i.active?i.points:t?e?.points??[]:[];if(r.length===0)return null;let o=(i.active?i.floor:e?.floor??0)+Gu,n=Math.max(...r.map(([s])=>s))-Math.min(...r.map(([s])=>s))+Math.max(...r.map(([,s])=>s))-Math.min(...r.map(([,s])=>s)),c=Math.max(.03,n*.006),d=s=>[...r,...i.active?[]:[r[0]]].map(([g,p])=>[g,s,p]);return qu("group",{ref:s=>{s&&ld(s)},children:[r.length>1?Ar(Ku,{points:d(o),color:rs,lineWidth:2,depthTest:!1,renderOrder:999}):null,!i.active&&e?Ar(Ku,{points:d(e.ceiling-Gu),color:rs,lineWidth:1,dashed:!0,dashSize:c*4,gapSize:c*3,depthTest:!1,renderOrder:999}):null,i.active?r.map(([s,g],p)=>qu("mesh",{position:[s,o,g],renderOrder:999,children:[Ar("sphereGeometry",{args:[p===0?c*1.8:c,12,8]}),Ar("meshBasicMaterial",{color:rs,depthTest:!1,transparent:!0,opacity:.9})]},p)):null]})}import{jsx as Ih}from"react/jsx-runtime";function Si({orientation:e,label:t,onPointerDown:i,onKeyDown:r}){return Ih("div",{className:`bb-resizer bb-resizer--${e}`,role:"separator","aria-orientation":e,"aria-label":t,tabIndex:0,onPointerDown:i,onKeyDown:r})}import{useCallback as as,useEffect as Dh,useRef as zh,useState as Fh}from"react";var Ju="react-immersive:editor-panels";function Yu(){try{return JSON.parse(localStorage.getItem(Ju)??"{}")}catch{return{}}}function Or(e,{size:t,min:i,max:r,edge:o,open:n=!0}){let[c,d]=Fh(()=>{let b=Yu()[e];return{size:b&&Number.isFinite(b.size)?Math.min(r,Math.max(i,b.size)):t,open:b?.open??n}}),s=zh(c);s.current=c,Dh(()=>{try{localStorage.setItem(Ju,JSON.stringify({...Yu(),[e]:c}))}catch{}},[e,c]);let g=as(b=>d(h=>({...h,open:b})),[]),p=as(b=>{if(b.button!==0)return;b.preventDefault();let h=b.currentTarget;h.setPointerCapture(b.pointerId);let M=o==="top"?b.clientY:b.clientX,S=s.current.size,B=o==="right"?1:-1,y=v=>{let m=o==="top"?v.clientY:v.clientX,N=Math.min(r,Math.max(i,S+(m-M)*B));d(A=>({...A,size:N}))},u=()=>{h.removeEventListener("pointermove",y),h.removeEventListener("pointerup",u),h.removeEventListener("pointercancel",u)};h.addEventListener("pointermove",y),h.addEventListener("pointerup",u),h.addEventListener("pointercancel",u)},[o,i,r]),x=as(b=>{let h=o==="top"?"ArrowUp":o==="right"?"ArrowRight":"ArrowLeft",M=o==="top"?"ArrowDown":o==="right"?"ArrowLeft":"ArrowRight";if(b.key!==h&&b.key!==M)return;b.preventDefault(),b.stopPropagation();let S=(b.key===h?1:-1)*16;d(B=>({...B,size:Math.min(r,Math.max(i,B.size+S))}))},[o,i,r]);return{size:c.size,open:c.open,setOpen:g,startResize:p,onResizeKey:x}}import{useEffect as Hh}from"react";import{X as $h}from"lucide-react";import{jsx as ss,jsxs as Uh}from"react/jsx-runtime";function Xu({toast:e,onDismiss:t}){return Hh(()=>{if(!e||e.tone!=="success")return;let i=window.setTimeout(t,3e3);return()=>window.clearTimeout(i)},[e,t]),e?Uh("div",{className:`bb-toast bb-toast--${e.tone}`,role:e.tone==="error"?"alert":"status",children:[ss("span",{children:e.text}),ss("button",{type:"button","aria-label":"Dismiss message",onClick:t,children:ss($h,{size:13})})]}):null}import{memo as Vh,useMemo as _h,useState as Qu}from"react";import{Check as Kh,Copy as Gh,X as qh}from"lucide-react";function ki(e){return JSON.stringify(e,null,2)}function Er(e){return['import { defineObjectBindings } from "@liveroom-tech/react-immersive/utils";',"",`export const objectBindings = defineObjectBindings(${JSON.stringify(e,null,2)});`,""].join(`
2
+ `)}function jr(e){return JSON.stringify(e,null,2)}function Lr(e){return['import type { SceneConfig } from "@liveroom-tech/react-immersive/utils";',"",`export const sceneConfig: SceneConfig = ${JSON.stringify(e,null,2)};`,""].join(`
3
+ `)}function Zu(e,t,i){An(new Blob([t],{type:i}),e)}function ls(e){return JSON.stringify(e??{},null,2)}function ds(e){return`[${e[0].toFixed(3)}, ${e[1].toFixed(3)}, ${e[2].toFixed(3)}]`}import{jsx as Gt,jsxs as ep}from"react/jsx-runtime";var Wh={model:["model","wireframe"],camera:["camera"],world:["environment","background","groundShadows"],lighting:["lighting","shadows"],postProcessing:["postProcessing"],rules:["styleRules"],product:["product"]};function Yh(e){return!e||typeof e!="object"?e:Object.fromEntries(Object.entries(e).filter(([,t])=>t?.enabled))}var tp=Vh(function({scope:t,selectedKey:i,selectedBinding:r,sceneConfig:o,sceneTab:n,onClose:c}){let[d,s]=Qu("ts"),[g,p]=Qu(!1),{preview:x,full:b,caption:h}=_h(()=>{if(t==="object"){if(!i||!r)return{preview:"",full:"",caption:"Select an object to see its binding."};let B={[i]:r};return{preview:ki(B),full:d==="ts"?Er(B):ki(B),caption:"objectBindings"}}let M=Wh[n]??[],S=Object.fromEntries(M.map(B=>[B,B==="postProcessing"?Yh(o[B]):o[B]]));return{preview:JSON.stringify(S,null,2),full:d==="ts"?Lr(o):jr(o),caption:"sceneConfig"}},[t,i,r,o,n,d]);return ep("section",{className:"bb-codePanel","aria-label":"Code",children:[ep("header",{children:[Gt("strong",{children:"Code"}),Gt("code",{children:h}),Gt("span",{className:"bb-topBarSpacer"}),Gt("div",{className:"bb-codeFormat",role:"radiogroup","aria-label":"Code format",children:["ts","json"].map(M=>Gt("button",{type:"button",role:"radio","aria-checked":d===M,className:d===M?"is-active":"",onClick:()=>s(M),children:M==="ts"?"TS":"JSON"},M))}),Gt("button",{type:"button",className:"bb-toolButton bb-toolButton--small",disabled:!b,title:t==="scene"?"Copy the whole scene config":"Copy this binding","aria-label":t==="scene"?"Copy the whole scene config":"Copy this binding",onClick:async()=>{await $n(b),p(!0),window.setTimeout(()=>p(!1),1500)},children:g?Gt(Kh,{size:13}):Gt(Gh,{size:13})}),Gt("button",{type:"button",className:"bb-toolButton bb-toolButton--small","aria-label":"Close code panel",onClick:c,children:Gt(qh,{size:13})})]}),Gt("pre",{tabIndex:0,children:x})]})});import{useEffect as cs,useMemo as Jh,useRef as np,useState as op}from"react";import{Search as Xh}from"lucide-react";import{jsx as qt,jsxs as dn}from"react/jsx-runtime";function Zh(e,t){let i=e.label.toLowerCase(),r=`${i} ${e.hint} ${e.keywords??""}`.toLowerCase(),o=0;for(let n of t){if(!r.includes(n))return-1;o+=i.startsWith(n)?3:i.includes(n)?2:1}return o}function ip({commands:e,onClose:t}){let[i,r]=op(""),[o,n]=op(0),c=np(null),d=Jh(()=>{let g=i.toLowerCase().split(/\s+/).filter(Boolean);return g.length?e.map(p=>({command:p,value:Zh(p,g)})).filter(p=>p.value>=0).sort((p,x)=>x.value-p.value).slice(0,40).map(p=>p.command):e.slice(0,40)},[e,i]);cs(()=>n(0),[i]),cs(()=>{c.current?.children[o]?.scrollIntoView({block:"nearest"})},[o]);let s=g=>{g&&(t(),g.run())};return qt("div",{className:"bb-paletteBackdrop",onMouseDown:g=>{g.target===g.currentTarget&&t()},children:dn("div",{className:"bb-palette",role:"dialog","aria-modal":"true","aria-label":"Search settings",children:[dn("label",{className:"bb-paletteSearch",children:[qt(Xh,{size:14,"aria-hidden":"true"}),qt("input",{autoFocus:!0,role:"combobox","aria-expanded":"true","aria-controls":"bb-paletteList","aria-activedescendant":d[o]?`bb-palette-${d[o].id}`:void 0,"aria-label":"Search settings and commands",placeholder:"Search settings and commands",value:i,onChange:g=>r(g.target.value),onKeyDown:g=>{g.key==="ArrowDown"&&(g.preventDefault(),n(p=>Math.min(d.length-1,p+1))),g.key==="ArrowUp"&&(g.preventDefault(),n(p=>Math.max(0,p-1))),g.key==="Enter"&&(g.preventDefault(),s(d[o])),g.key==="Escape"&&(g.preventDefault(),g.stopPropagation(),t())}})]}),dn("div",{className:"bb-paletteList",id:"bb-paletteList",role:"listbox",ref:c,children:[d.map((g,p)=>dn("button",{id:`bb-palette-${g.id}`,type:"button",role:"option","aria-selected":p===o,tabIndex:-1,className:p===o?"is-active":"",onMouseMove:()=>n(p),onClick:()=>s(g),children:[qt("span",{children:g.label}),g.shortcut?qt("kbd",{children:g.shortcut}):null,qt("small",{children:g.hint})]},g.id)),d.length?null:dn("p",{children:["Nothing matches \u201C",i,"\u201D."]})]})]})})}function rp({onClose:e}){let t=np(null);return cs(()=>t.current?.focus(),[]),qt("div",{className:"bb-paletteBackdrop",onMouseDown:r=>{r.target===r.currentTarget&&e()},children:qt("div",{ref:t,tabIndex:-1,className:"bb-shortcuts",role:"dialog","aria-modal":"true","aria-label":"Keyboard shortcuts",onKeyDown:r=>{(r.key==="Escape"||r.key==="?")&&(r.preventDefault(),r.stopPropagation(),e())},children:[["Tools",[["V","Select"],["G","Move"],["R","Rotate"],["T","Scale"],["F","Frame selection"]]],["Editor",[["\u2318K","Search settings"],["\u2318Z","Undo"],["\u21E7\u2318Z","Redo"],["?","Shortcuts"],["Esc","Clear selection"]]],["Camera",[["W A S D","Move"],["Space / C","Up and down"],["Arrows","Orbit"],["\u21E7 Up / Down","Zoom"]]],["Selecting",[["Click","Select"],["\u2318 Click","Add or remove"],["\u21E7 Click","Add in the viewport, range in the Outliner"],["\u2318A","All shown in the Outliner"]]]].map(([r,o])=>dn("section",{children:[qt("h4",{children:r}),o.map(([n,c])=>dn("div",{children:[qt("span",{children:c}),qt("kbd",{children:n})]},c))]},r))})})}var ze=(e,t)=>({panel:"object",tab:e,section:t}),he=(e,t)=>({panel:"scene",tab:e,section:t}),ap=[{label:"Object ID",hint:"Object \u203A General",keywords:"identity id modelObjectId",where:ze("general","Identity")},{label:"Label, type, status, group, tags",hint:"Object \u203A General",keywords:"basics selectable hoverable visible",where:ze("general","Basics")},{label:"Position, rotation, scale",hint:"Object \u203A General",keywords:"transform move pivot",where:ze("general","Transform")},{label:"Saved view",hint:"Object \u203A General",keywords:"camera position cameraState",where:ze("general","Saved view")},{label:"Material presets",hint:"Object \u203A Material",keywords:"wood metal glass plastic",where:ze("material")},{label:"Base color",hint:"Object \u203A Material",keywords:"pbr albedo texture metalness baseColor",where:ze("material","Surface")},{label:"Roughness",hint:"Object \u203A Material",keywords:"glossiness matte shiny",where:ze("material","Roughness")},{label:"Opacity",hint:"Object \u203A Material",keywords:"alpha transparency blending",where:ze("material","Opacity")},{label:"Emission",hint:"Object \u203A Material",keywords:"emissive glow",where:ze("material","Emission")},{label:"Normal and bump maps",hint:"Object \u203A Material",keywords:"normalMap bumpMap",where:ze("material","Normal and bump")},{label:"Displacement",hint:"Object \u203A Material",keywords:"height map",where:ze("material","Displacement")},{label:"Ambient occlusion map",hint:"Object \u203A Material",keywords:"aoMap",where:ze("material","Ambient occlusion")},{label:"Clearcoat",hint:"Object \u203A Material",keywords:"lacquer gloss layer",where:ze("material","Clearcoat")},{label:"Sheen",hint:"Object \u203A Material",keywords:"fabric velvet",where:ze("material","Sheen")},{label:"Anisotropy",hint:"Object \u203A Material",keywords:"brushed metal",where:ze("material","Anisotropy")},{label:"Transmission and volume",hint:"Object \u203A Material",keywords:"glass thickness attenuation",where:ze("material","Transmission and volume")},{label:"Faces",hint:"Object \u203A Material",keywords:"side double backface",where:ze("material","Faces")},{label:"Decals",hint:"Object \u203A Decals",keywords:"logo text image print",where:ze("decals")},{label:"Actions",hint:"Object \u203A Actions",keywords:"onAction button command",where:ze("actions")},{label:"Metrics",hint:"Object \u203A Data",keywords:"json",where:ze("data","Metrics")},{label:"Metadata",hint:"Object \u203A Data",keywords:"json",where:ze("data","Metadata")},{label:"Model rotation",hint:"Scene \u203A Model",keywords:"straighten orient",where:he("model","Display")},{label:"Renderer and shading",hint:"Scene \u203A Model",keywords:"pbr matcap uv checker lit unlit normals",where:he("model","Display")},{label:"Material variants",hint:"Scene \u203A Model",keywords:"KHR_materials_variants",where:he("model","Display")},{label:"Auto rotate",hint:"Scene \u203A Model",keywords:"turntable spin",where:he("model","Auto rotate")},{label:"Wireframe",hint:"Scene \u203A Model",where:he("model","Wireframe")},{label:"Diagnostics",hint:"Scene \u203A Model",keywords:"asset statistics triangles textures",where:he("model","Diagnostics")},{label:"Field of view",hint:"Scene \u203A Camera",keywords:"fov lens",where:he("camera","Lens")},{label:"Environment",hint:"Scene \u203A World",keywords:"hdri preset intensity rotation ibl",where:he("world","Environment")},{label:"Environment shadow",hint:"Scene \u203A World",keywords:"shadowLight",where:he("world","Environment shadow")},{label:"Background",hint:"Scene \u203A World",keywords:"color image environment",where:he("world","Background")},{label:"Ground shadows",hint:"Scene \u203A World",keywords:"contact catcher",where:he("world","Ground shadows")},{label:"Lights",hint:"Scene \u203A Lights",keywords:"directional point spot hemisphere",where:he("lighting","Lights")},{label:"Shadows",hint:"Scene \u203A Lights",keywords:"map size bias softness",where:he("lighting","Shadows")},{label:"Effects",hint:"Scene \u203A Effects",keywords:"post processing bloom ssao tone mapping vignette depth of field",where:he("postProcessing")},{label:"Tone mapping",hint:"Scene \u203A Effects",keywords:"post processing effect aces filmic exposure",where:he("postProcessing","Tone mapping")},{label:"Brightness and contrast",hint:"Scene \u203A Effects",keywords:"post processing effect ",where:he("postProcessing","Brightness and contrast")},{label:"Hue and saturation",hint:"Scene \u203A Effects",keywords:"post processing effect ",where:he("postProcessing","Hue and saturation")},{label:"Vignette",hint:"Scene \u203A Effects",keywords:"post processing effect ",where:he("postProcessing","Vignette")},{label:"Bloom",hint:"Scene \u203A Effects",keywords:"post processing effect glow threshold",where:he("postProcessing","Bloom")},{label:"Ambient occlusion (SSAO)",hint:"Scene \u203A Effects",keywords:"post processing effect ssao",where:he("postProcessing","Ambient occlusion")},{label:"Depth of field",hint:"Scene \u203A Effects",keywords:"post processing effect bokeh blur focus",where:he("postProcessing","Depth of field")},{label:"God rays",hint:"Scene \u203A Effects",keywords:"post processing effect sun",where:he("postProcessing","God rays")},{label:"Lens flare",hint:"Scene \u203A Effects",keywords:"post processing effect ",where:he("postProcessing","Lens flare")},{label:"Outline",hint:"Scene \u203A Effects",keywords:"post processing effect edge",where:he("postProcessing","Outline")},{label:"Anti-aliasing (SMAA)",hint:"Scene \u203A Effects",keywords:"post processing effect smaa",where:he("postProcessing","Anti-aliasing")},{label:"Chromatic aberration",hint:"Scene \u203A Effects",keywords:"post processing effect ",where:he("postProcessing","Chromatic aberration")},{label:"Glitch",hint:"Scene \u203A Effects",keywords:"post processing effect ",where:he("postProcessing","Glitch")},{label:"Noise",hint:"Scene \u203A Effects",keywords:"post processing effect grain",where:he("postProcessing","Noise")},{label:"Pixelation",hint:"Scene \u203A Effects",keywords:"post processing effect ",where:he("postProcessing","Pixelation")},{label:"Section cut",hint:"Scene \u203A Model",keywords:"clip plane box slice",where:he("model","Section cut")},{label:"Configure: customer choices",hint:"Configure",keywords:"product configurator options swatch variant customise customize choices shop e-commerce",where:{panel:"configure",tab:"configure"}},{label:"Configure: prices and buying",hint:"Configure",keywords:"price sku checkout buy link cart currency commerce",where:{panel:"configure",tab:"configure",section:"Prices and buying"}},{label:"Configure: restrictions",hint:"Configure",keywords:"compatibility rules requires excludes combinations",where:{panel:"configure",tab:"configure",section:"Restrictions"}},{label:"Configure: publish and embed",hint:"Configure",keywords:"embed publish share website shopify wordpress",where:{panel:"configure",tab:"configure",section:"Publish"}},{label:"Rules",hint:"Scene \u203A Rules",keywords:"style rules styleRules metric status color scale pulse",where:he("rules")},{label:"Assets",hint:"Left panel",keywords:"models placements grid composition",where:{panel:"left",tab:"assets"}},{label:"Annotations",hint:"Left panel",keywords:"hotspots markers notes",where:{panel:"left",tab:"annotations"}},{label:"Measurements",hint:"Left panel",keywords:"distance area calibrate units",where:{panel:"left",tab:"measure"}},{label:"Sequences",hint:"Timeline",keywords:"keyframes tracks timeline",where:{panel:"dock",tab:"sequences"}},{label:"Clips",hint:"Timeline",keywords:"animations autoplay loop speed",where:{panel:"dock",tab:"clips"}},{label:"Cinematic",hint:"Timeline",keywords:"waypoints camera path",where:{panel:"dock",tab:"cinematic"}}];function sp(e){requestAnimationFrame(()=>{let t=document.querySelector(`.bb-root [data-ri-section="${CSS.escape(e)}"]`);if(!t)return;let i=t.querySelector('button[aria-expanded="false"]');i?.closest("[data-ri-section]")===t&&i.click(),t.scrollIntoView({block:"nearest"}),t.classList.add("bb-flash"),window.setTimeout(()=>t.classList.remove("bb-flash"),900)})}import{useEffect as nx,useRef as ix,useState as Ir}from"react";import{Lock as rx,Plus as ax,Trash2 as sx}from"lucide-react";import{RotateCcw as Qh}from"lucide-react";import{jsx as Ci}from"react/jsx-runtime";function Ct({panelKey:e,title:t,tooltip:i,toggleLabel:r,controls:o,children:n,requiredTier:c,core:d=!1}){let{openMaterialPanels:s,materialPanelEnabled:g,onToggleMaterialPanel:p,onSetMaterialPanelState:x}=o,b=c?.locked??!1;return o.visibleLayers.has(e)?Ci(Du,{title:t,tooltip:i,disabled:b||!d&&!g[e],open:s[e],onToggle:()=>p(e),trailing:d?Ci("button",{type:"button",className:"se-iconButton",title:`Clear ${t.toLowerCase()} overrides`,"aria-label":`Clear ${t.toLowerCase()} overrides`,onClick:()=>x(e,!1),children:Ci(Qh,{size:12})}):Ci(de,{checked:!b&&g[e],onChange:b?()=>{}:h=>x(e,h),label:r??`Toggle ${t}`}),children:b&&c?Ci(Ye,{requiredTier:c.tier,feature:t}):n}):null}import{createContext as dp,useContext as lp,useRef as ex}from"react";import{FileUp as tx}from"lucide-react";import{jsx as Fe,jsxs as zo}from"react/jsx-runtime";var us=dp(null),ps=dp(null);function Ue({label:e,value:t,placeholder:i,onChange:r,path:o}){let n=ex(null),c=lp(us),d=lp(ps);return zo("div",{className:"bb-field bb-field--row","data-ri-path":o,children:[Fe("label",{className:"bb-label",title:e,children:e}),zo("div",{className:"bb-fileField",title:c??void 0,children:[Fe("input",{className:"bb-input bb-fileField-input",placeholder:i,value:t,disabled:!!c&&!t,onChange:s=>{let g=s.target.value;!g&&t&&di(t),r(g)}}),Fe("button",{type:"button",className:"bb-fileFieldButton",disabled:!!c,onClick:()=>n.current?.click(),"aria-label":`Select file for ${e}`,title:`Select file for ${e}`,children:Fe(tx,{size:13})}),Fe("input",{ref:n,type:"file",accept:"image/png,image/jpeg,image/webp,image/avif",className:"bb-hiddenInput",onChange:s=>{let g=s.target.files?.[0];if(!g)return;let p=Rn(g);t&&t!==p&&di(t),_t(p,URL.createObjectURL(g)),d?.(p,g),r(p),s.target.value=""}})]})]})}function Fo({label:e,value:t,fallback:i="#ffffff",onChange:r,path:o}){return zo("div",{className:"bb-field bb-field--row","data-ri-path":o,children:[Fe("span",{className:"bb-label",children:e}),Fe(uc,{label:e,value:t||i,onChange:r})]})}function Mi({label:e,checked:t,onChange:i,path:r}){return zo("label",{className:"bb-field bb-field--row","data-ri-path":r,children:[Fe("span",{className:"bb-label",title:e,children:e}),Fe("span",{className:"rui-checkCell",children:Fe("input",{type:"checkbox",checked:t,onChange:o=>i(o.target.checked)})})]})}function cp({label:e,value:t,min:i,max:r,step:o,placeholder:n,disabled:c,onChange:d,path:s}){return zo("div",{className:"bb-field bb-field--row","data-ri-path":s,children:[Fe("label",{className:"bb-label",title:e,children:e}),Fe("input",{className:"bb-input",type:"number",min:i,max:r,step:o,placeholder:n,disabled:c,value:t??"",onChange:g=>d(g.target.value===""?void 0:Number(g.target.value))})]})}function ox(e,t){let i=t<1?Math.ceil(-Math.log10(t)):0,r=10**Math.max(i,0);return Math.round(e*r)/r}function bs({label:e,value:t,min:i,max:r,step:o=.01,disabled:n,onChange:c,path:d}){let s=t??0,g=x=>{let b=x;return i!==void 0&&(b=Math.max(i,b)),r!==void 0&&(b=Math.min(r,b)),b},p=dc({value:s,step:o,min:i,max:r,disabled:n,onChange:x=>c(ox(x,o))});return zo("div",{className:"bb-field bb-field--row","data-ri-path":d,children:[Fe("label",{className:"bb-label bb-label--scrub",title:"Drag to change",...p,children:e}),Fe("input",{className:"bb-input",type:"number",min:i,max:r,step:o,disabled:n,value:s,onChange:x=>{x.target.value!==""&&c(g(Number(x.target.value)))}})]})}function Gn({label:e,value:t,options:i,onChange:r,path:o}){return zo("div",{className:"bb-field bb-field--row","data-ri-path":o,children:[Fe("label",{className:"bb-label",title:e,children:e}),i.length<=3?Fe("div",{className:"se-segmentedControl",children:i.map(n=>Fe("button",{type:"button",className:`se-segmentedOption ${n===t?"se-segmentedOption--active":""}`,onClick:()=>r(n),children:n.charAt(0).toUpperCase()+n.slice(1)},n))}):Fe(et,{className:"bb-select",value:t,onChange:n=>r(n.target.value),children:i.map(n=>Fe("option",{value:n,children:n.charAt(0).toUpperCase()+n.slice(1)},n))})]})}function ke({label:e,value:t,min:i,max:r,step:o,onChange:n,path:c}){return zo("div",{className:"bb-field bb-field--row","data-ri-path":c,children:[Fe("span",{className:"bb-label",children:e}),Fe(cc,{label:e,value:t??i,unset:t===void 0,min:i,max:r,step:o,onChange:n})]})}import{Fragment as bp,jsx as $,jsxs as Ie}from"react/jsx-runtime";var up="This object has no texture coordinates (UVs), so image maps can't be placed on it. Colors and the other settings work, and Decals can put an image on it.",pp=[{key:"pbr",label:"Surface",core:!0},{key:"roughness",label:"Roughness",core:!0},{key:"opacity",label:"Opacity",core:!0},{key:"normalBump",label:"Normal and bump"},{key:"emission",label:"Emission"},{key:"ao",label:"Ambient occlusion"},{key:"faces",label:"Faces"},{key:"displacement",label:"Displacement",advanced:!0},{key:"clearcoat",label:"Clearcoat",advanced:!0},{key:"sheen",label:"Sheen",advanced:!0},{key:"anisotropy",label:"Anisotropy",advanced:!0},{key:"transmission",label:"Transmission and volume",advanced:!0}];function mp({selectedItem:e,selectedMaterial:t,pbrWorkflow:i,onPbrWorkflowChange:r,openMaterialPanels:o,materialPanelEnabled:n,onToggleMaterialPanel:c,onSetMaterialPanelState:d,updateSelectedMaterial:s,setSelectedTexturePath:g,isTexturePositioningEnabled:p,onConfirmTexturePosition:x,takesImage:b=!0}){let{tier:h}=dt(),M={tier:"starter",locked:!lt(h,"advancedMaterials")},[S,B]=Ir(()=>new Set),[y,u]=Ir(!1),v=ix(null);On([v],()=>u(!1),y),nx(()=>B(new Set),[e]);let m=new Set(pp.filter(P=>P.core||n[P.key]||S.has(P.key)).map(P=>P.key)),N=pp.filter(P=>!m.has(P.key)),A=P=>{u(!1),B(L=>new Set(L).add(P)),d(P,!0),o[P]||c(P)},K={openMaterialPanels:o,materialPanelEnabled:n,onToggleMaterialPanel:c,onSetMaterialPanelState:d,visibleLayers:m},[T,D]=Ir("roughness"),[k,Q]=Ir("factor"),G=(P,L)=>{s(e,Me=>{if(!Me?.texture?.path)return Me??{};let Xe=Me.texture.offset??[0,0],Z=[Xe[0],Xe[1]];return Z[P]=L,{...Me,texture:{...Me.texture,offset:Z}}})},ee=P=>{s(e,L=>{if(!L?.texture?.path)return L??{};let Me=(P%360+360)%360;return{...L,texture:{...L.texture,rotation:Me*Math.PI/180}}})},le=()=>{g(e,"texture","")};return Ie(us.Provider,{value:b?null:up,children:[b?null:$("p",{className:"bb-note bb-materialNotice",children:up}),$(Ct,{panelKey:"pbr",core:!0,title:"Surface",tooltip:"Controls the base color and workflow used for physically based shading.",controls:K,children:Ie("div",{className:"bb-grid",children:[$(Gn,{label:"Workflow",value:i,options:["metalness","specular"],onChange:r}),$(Ue,{path:"objectBindings[\u2026].style.material.texture.path",label:i==="specular"?"Albedo map":"Base map",placeholder:"materials/oak-wood.jpg",value:t?.texture?.path??"",onChange:P=>g(e,"texture",P)}),t?.texture?.path?Ie("div",{className:"rui-group",children:[Ie("div",{className:"rui-groupHeader",children:[$("span",{children:"Texture position"}),$("button",{type:"button",className:"se-iconButton",onClick:le,title:"Remove the texture and its position","aria-label":"Remove the texture and its position",children:$(sx,{size:13})})]}),Ie("div",{className:"bb-grid",children:[$(bs,{path:"objectBindings[\u2026].style.material.texture.offset",label:"Offset X",value:t?.texture?.offset?.[0]??0,step:.01,onChange:P=>G(0,P)}),$(bs,{path:"objectBindings[\u2026].style.material.texture.offset",label:"Offset Y",value:t?.texture?.offset?.[1]??0,step:.01,onChange:P=>G(1,P)})]}),$(ke,{label:"Rotation",value:((t?.texture?.rotation??0)*180/Math.PI%360+360)%360,min:0,max:360,step:1,onChange:P=>ee(P??0)}),p?$("button",{type:"button",className:"bb-button rui-inlineButton",onClick:x,title:"Confirm this texture position and exit positioning mode",children:"Done positioning"}):$("p",{className:"bb-note",style:{margin:"6px 0 0"},children:"Double-click the object in the preview to drag its texture directly (scroll to zoom), or edit its offset numerically once positioning."})]}):null,$(Fo,{path:"objectBindings[\u2026].style.material.baseColor",label:i==="specular"?"Albedo color":"Base color",value:t?.baseColor??"#ffffff",onChange:P=>s(e,L=>({...L,baseColor:P}))}),i==="metalness"?Ie(bp,{children:[$(ke,{path:"objectBindings[\u2026].style.material.metalness",label:"Metalness",value:t?.metalness,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,metalness:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.metalnessMap.path",label:"Metalness map",placeholder:"materials/body-metalness.jpg",value:t?.metalnessMap?.path??"",onChange:P=>g(e,"metalnessMap",P)})]}):Ie(bp,{children:[$(ke,{path:"objectBindings[\u2026].style.material.specularIntensity",label:"Specular intensity",value:t?.specularIntensity,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,specularIntensity:P}))}),$(Fo,{path:"objectBindings[\u2026].style.material.specularColor",label:"Specular color",value:t?.specularColor??"#ffffff",onChange:P=>s(e,L=>({...L,specularColor:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.specularIntensityMap.path",label:"Intensity map",placeholder:"materials/body-specular-intensity.jpg",value:t?.specularIntensityMap?.path??"",onChange:P=>g(e,"specularIntensityMap",P)}),$(Ue,{path:"objectBindings[\u2026].style.material.specularColorMap.path",label:"Color map",placeholder:"materials/body-specular-color.jpg",value:t?.specularColorMap?.path??"",onChange:P=>g(e,"specularColorMap",P)})]}),$(ke,{path:"objectBindings[\u2026].style.material.reflectivity",label:"Reflectivity",value:t?.reflectivity,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,reflectivity:P}))})]})}),$(Ct,{panelKey:"roughness",core:!0,title:"Roughness",tooltip:"Adjusts how matte or shiny the surface appears.",toggleLabel:"Toggle Roughness and Glossiness",controls:K,children:Ie("div",{className:"bb-grid",children:[$(Gn,{label:"Mode",value:T,options:["roughness","glossiness"],onChange:D}),$("div",{className:"bb-field bb-field--full",children:$("p",{className:"bb-note",children:T==="roughness"?"Roughness: 0 is glossy, 1 is matte.":"Glossiness is the inverse of roughness (glossiness = 1 \u2212 roughness)"})}),T==="roughness"?$(ke,{path:"objectBindings[\u2026].style.material.roughness",label:"Roughness",value:t?.roughness,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,roughness:P}))}):$(ke,{path:"objectBindings[\u2026].style.material.roughness",label:"Glossiness",value:t?.roughness===void 0?void 0:1-t.roughness,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,roughness:P===void 0?void 0:1-P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.roughnessMap.path",label:T==="glossiness"?"Glossiness map":"Roughness map",placeholder:"materials/body-roughness.jpg",value:t?.roughnessMap?.path??"",onChange:P=>g(e,"roughnessMap",P)})]})}),$(Ct,{panelKey:"emission",title:"Emission",tooltip:"Makes the material self-illuminated with emissive color and intensity.",controls:K,children:Ie("div",{className:"bb-grid",children:[$(Fo,{path:"objectBindings[\u2026].style.material.emissive",label:"Color",value:t?.emissive??"#000000",fallback:"#000000",onChange:P=>s(e,L=>({...L,emissive:P}))}),$(ke,{path:"objectBindings[\u2026].style.material.emissiveIntensity",label:"Intensity",value:t?.emissiveIntensity,min:0,max:10,step:.1,onChange:P=>s(e,L=>({...L,emissiveIntensity:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.emissiveMap.path",label:"Map",placeholder:"materials/body-emissive.jpg",value:t?.emissiveMap?.path??"",onChange:P=>g(e,"emissiveMap",P)})]})}),$(Ct,{panelKey:"opacity",core:!0,title:"Opacity",tooltip:"Controls transparency, alpha testing, and blending behavior.",controls:K,children:Ie("div",{className:"bb-grid",children:[$(ke,{path:"objectBindings[\u2026].style.material.opacity",label:"Opacity",value:t?.opacity,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,opacity:P}))}),$(ke,{path:"objectBindings[\u2026].style.material.alphaTest",label:"Alpha test",value:t?.alphaTest,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,alphaTest:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.alphaMap.path",label:"Alpha map",placeholder:"materials/body-alpha.png",value:t?.alphaMap?.path??"",onChange:P=>g(e,"alphaMap",P)}),$(Gn,{path:"objectBindings[\u2026].style.material.blendingMode",label:"Blending mode",value:t?.blendingMode??"normal",options:nc,onChange:P=>s(e,L=>({...L,blendingMode:P}))}),$(Mi,{path:"objectBindings[\u2026].style.material.alphaHash",label:"Alpha hash",checked:t?.alphaHash??!1,onChange:P=>s(e,L=>({...L,alphaHash:P}))}),$(Mi,{path:"objectBindings[\u2026].style.material.dithering",label:"Dithering",checked:t?.dithering??!1,onChange:P=>s(e,L=>({...L,dithering:P}))})]})}),Ie(Ct,{panelKey:"normalBump",title:"Normal and bump",tooltip:"Adds surface detail without changing the actual mesh shape.",toggleLabel:"Toggle Normal and Bump",controls:K,children:[Ie("div",{className:"bb-grid",children:[$(Ue,{path:"objectBindings[\u2026].style.material.normalMap.path",label:"Normal map",placeholder:"materials/body-normal.jpg",value:t?.normalMap?.path??"",onChange:P=>g(e,"normalMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.normalScale",label:"Normal scale",value:t?.normalScale,min:0,max:5,step:.01,onChange:P=>s(e,L=>({...L,normalScale:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.bumpMap.path",label:"Bump map",placeholder:"materials/body-bump.jpg",value:t?.bumpMap?.path??"",onChange:P=>g(e,"bumpMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.bumpScale",label:"Bump scale",value:t?.bumpScale,min:0,max:5,step:.01,onChange:P=>s(e,L=>({...L,bumpScale:P}))})]}),$(Mi,{path:"objectBindings[\u2026].style.material.flipNormalY",label:"Flip normal Y",checked:t?.flipNormalY??!1,onChange:P=>s(e,L=>({...L,flipNormalY:P}))})]}),$(Ct,{panelKey:"displacement",requiredTier:M,title:"Displacement",tooltip:"Offsets geometry using a texture to create real surface height.",controls:K,children:Ie("div",{className:"bb-grid",children:[$(Ue,{path:"objectBindings[\u2026].style.material.displacementMap.path",label:"Map",placeholder:"materials/body-displacement.jpg",value:t?.displacementMap?.path??"",onChange:P=>g(e,"displacementMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.displacementScale",label:"Scale",value:t?.displacementScale,min:-5,max:5,step:.01,onChange:P=>s(e,L=>({...L,displacementScale:P}))}),$(ke,{path:"objectBindings[\u2026].style.material.displacementBias",label:"Bias",value:t?.displacementBias,min:-5,max:5,step:.01,onChange:P=>s(e,L=>({...L,displacementBias:P}))})]})}),$(Ct,{panelKey:"ao",title:"Ambient occlusion",tooltip:"Darkens creases and contact areas to add depth.",controls:K,children:Ie("div",{className:"bb-grid",children:[$(Ue,{path:"objectBindings[\u2026].style.material.aoMap.path",label:"Map",placeholder:"materials/body-ao.jpg",value:t?.aoMap?.path??"",onChange:P=>g(e,"aoMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.aoMapIntensity",label:"Intensity",value:t?.aoMapIntensity,min:0,max:5,step:.01,onChange:P=>s(e,L=>({...L,aoMapIntensity:P}))})]})}),Ie(Ct,{panelKey:"clearcoat",requiredTier:M,title:"Clearcoat",tooltip:"Adds a glossy protective layer on top of the base material.",controls:K,children:[Ie("div",{className:"bb-grid",children:[$(Ue,{path:"objectBindings[\u2026].style.material.clearcoatMap.path",label:"Coat map",placeholder:"materials/body-clearcoat.jpg",value:t?.clearcoatMap?.path??"",onChange:P=>g(e,"clearcoatMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.clearcoat",label:"Clearcoat",value:t?.clearcoat,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,clearcoat:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.clearcoatRoughnessMap.path",label:"Roughness map",placeholder:"materials/body-clearcoat-roughness.jpg",value:t?.clearcoatRoughnessMap?.path??"",onChange:P=>g(e,"clearcoatRoughnessMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.clearcoatRoughness",label:"Roughness",value:t?.clearcoatRoughness,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,clearcoatRoughness:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.clearcoatNormalMap.path",label:"Normal map",placeholder:"materials/body-clearcoat-normal.jpg",value:t?.clearcoatNormalMap?.path??"",onChange:P=>g(e,"clearcoatNormalMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.clearcoatNormalScale",label:"Normal scale",value:t?.clearcoatNormalScale,min:0,max:5,step:.01,onChange:P=>s(e,L=>({...L,clearcoatNormalScale:P}))})]}),$(Mi,{path:"objectBindings[\u2026].style.material.flipClearcoatNormalY",label:"Flip normal Y",checked:t?.flipClearcoatNormalY??!1,onChange:P=>s(e,L=>({...L,flipClearcoatNormalY:P}))})]}),$(Ct,{panelKey:"sheen",requiredTier:M,title:"Sheen",tooltip:"Adds a soft fabric-like sheen on grazing angles.",controls:K,children:Ie("div",{className:"bb-grid",children:[$(ke,{path:"objectBindings[\u2026].style.material.sheen",label:"Sheen",value:t?.sheen,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,sheen:P}))}),$(Fo,{path:"objectBindings[\u2026].style.material.sheenColor",label:"Color",value:t?.sheenColor??"#ffffff",onChange:P=>s(e,L=>({...L,sheenColor:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.sheenColorMap.path",label:"Color map",placeholder:"materials/body-sheen-color.jpg",value:t?.sheenColorMap?.path??"",onChange:P=>g(e,"sheenColorMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.sheenRoughness",label:"Roughness",value:t?.sheenRoughness,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,sheenRoughness:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.sheenRoughnessMap.path",label:"Roughness map",placeholder:"materials/body-sheen-roughness.jpg",value:t?.sheenRoughnessMap?.path??"",onChange:P=>g(e,"sheenRoughnessMap",P)})]})}),$(Ct,{panelKey:"anisotropy",requiredTier:M,title:"Anisotropy",tooltip:"Stretches reflections in one direction for brushed or fiber-like surfaces.",controls:K,children:Ie("div",{className:"bb-grid",children:[$(ke,{path:"objectBindings[\u2026].style.material.anisotropy",label:"Intensity",value:t?.anisotropy,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,anisotropy:P}))}),$(Gn,{label:"Direction",value:k,options:["factor","texture"],onChange:Q}),k==="factor"?$(ke,{path:"objectBindings[\u2026].style.material.anisotropyRotation",label:"Rotation",value:t?.anisotropyRotation,min:0,max:6.28,step:.01,onChange:P=>s(e,L=>({...L,anisotropyRotation:P}))}):$(Ue,{path:"objectBindings[\u2026].style.material.anisotropyMap.path",label:"Map",placeholder:"materials/body-anisotropy.jpg",value:t?.anisotropyMap?.path??"",onChange:P=>g(e,"anisotropyMap",P)})]})}),$(Ct,{panelKey:"transmission",requiredTier:M,title:"Transmission and volume",tooltip:"Controls glass-like transmission and how light travels through volume.",toggleLabel:"Toggle Transmission and Volume",controls:K,children:Ie("div",{className:"bb-grid",children:[$(ke,{path:"objectBindings[\u2026].style.material.transmission",label:"Transmission",value:t?.transmission,min:0,max:1,step:.01,onChange:P=>s(e,L=>({...L,transmission:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.transmissionMap.path",label:"Map",placeholder:"materials/body-transmission.jpg",value:t?.transmissionMap?.path??"",onChange:P=>g(e,"transmissionMap",P)}),$(ke,{path:"objectBindings[\u2026].style.material.thickness",label:"Thickness",value:t?.thickness,min:0,max:5,step:.01,onChange:P=>s(e,L=>({...L,thickness:P}))}),$(Ue,{path:"objectBindings[\u2026].style.material.thicknessMap.path",label:"Thickness map",placeholder:"materials/body-thickness.jpg",value:t?.thicknessMap?.path??"",onChange:P=>g(e,"thicknessMap",P)}),$(Fo,{path:"objectBindings[\u2026].style.material.attenuationColor",label:"Volume tint",value:t?.attenuationColor??"#ffffff",onChange:P=>s(e,L=>({...L,attenuationColor:P}))}),$(cp,{path:"objectBindings[\u2026].style.material.attenuationDistance",label:"Attenuation",value:t?.attenuationDistance,min:0,step:.01,placeholder:"Infinity when unset",onChange:P=>s(e,L=>({...L,attenuationDistance:P}))})]})}),$(Ct,{panelKey:"faces",title:"Faces",tooltip:"Chooses which side of the mesh renders and how backfaces are handled.",controls:K,children:$("div",{className:"bb-grid",children:$(Gn,{path:"objectBindings[\u2026].style.material.side",label:"Side",value:t?.side??"front",options:oc,onChange:P=>s(e,L=>({...L,side:P}))})})}),N.length?Ie("div",{className:"se-listHeader se-listHeader--footer",ref:v,children:[Ie("button",{type:"button",className:"bb-button bb-button--ghost bb-button--small","aria-expanded":y,onClick:()=>u(P=>!P),children:[$(ax,{size:13,"aria-hidden":"true"}),"Add layer"]}),y?$("div",{className:"se-addMenu se-addMenu--up",role:"menu","aria-label":"Add layer",children:N.map(P=>Ie("button",{type:"button",role:"menuitem",onClick:()=>A(P.key),children:[$("span",{children:P.label}),P.advanced&&M.locked?$(rx,{size:12,"aria-label":"Needs an upgrade"}):null]},P.key))}):null]}):null]})}import{useRef as cx,useState as ux}from"react";import{Ban as px,ChevronDown as bx}from"lucide-react";var Dr="default",ms=[{id:Dr,label:"Default",swatch:"transparent",material:{}},{id:"wood",label:"Wood",swatch:"#8b5a2b",material:{baseColor:"#8b5a2b",metalness:0,roughness:.75,reflectivity:.04}},{id:"brushed-metal",label:"Brushed Metal",swatch:"linear-gradient(135deg, #cfcfcf, #8a8a8a)",material:{baseColor:"#c8c8c8",metalness:1,roughness:.35}},{id:"chrome",label:"Polished Chrome",swatch:"linear-gradient(135deg, #ffffff, #9aa0a6)",material:{baseColor:"#e8e8e8",metalness:1,roughness:.05}},{id:"gold",label:"Gold",swatch:"linear-gradient(135deg, #ffe9a8, #c89b2c)",material:{baseColor:"#e6b325",metalness:1,roughness:.2}},{id:"copper",label:"Copper",swatch:"linear-gradient(135deg, #e3a576, #8a4a26)",material:{baseColor:"#b87333",metalness:1,roughness:.3}},{id:"glass",label:"Glass",swatch:"linear-gradient(135deg, rgba(255,255,255,0.9), rgba(180,210,230,0.4))",material:{baseColor:"#ffffff",metalness:0,roughness:.02,reflectivity:.5,opacity:1,transmission:1,thickness:.5,attenuationColor:"#ffffff",attenuationDistance:1}},{id:"frosted-glass",label:"Frosted Glass",swatch:"linear-gradient(135deg, rgba(255,255,255,0.85), rgba(210,225,235,0.6))",material:{baseColor:"#ffffff",metalness:0,roughness:.4,reflectivity:.3,opacity:1,transmission:.9,thickness:.5}},{id:"plastic-glossy",label:"Glossy Plastic",swatch:"#dadada",material:{baseColor:"#dadada",metalness:0,roughness:.25,reflectivity:.5,clearcoat:.3,clearcoatRoughness:.1}},{id:"plastic-matte",label:"Matte Plastic",swatch:"#9a9a9a",material:{baseColor:"#9a9a9a",metalness:0,roughness:.85,reflectivity:.04}},{id:"rubber",label:"Rubber",swatch:"#1a1a1a",material:{baseColor:"#1a1a1a",metalness:0,roughness:.9,reflectivity:.02}},{id:"fabric",label:"Fabric",swatch:"#9c8a6b",material:{baseColor:"#9c8a6b",metalness:0,roughness:.95,sheen:.4,sheenColor:"#ffffff",sheenRoughness:.6}},{id:"ceramic",label:"Ceramic",swatch:"#f5f5f0",material:{baseColor:"#f5f5f0",metalness:0,roughness:.15,clearcoat:.6,clearcoatRoughness:.1}},{id:"concrete",label:"Concrete",swatch:"#9b9b93",material:{baseColor:"#9b9b93",metalness:0,roughness:.95,reflectivity:.03}}],lx=Array.from(new Set(ms.flatMap(e=>Object.keys(e.material)))),dx=Object.fromEntries(lx.map(e=>[e,void 0]));function gp(e){return e.id===Dr?dx:e.material}import{jsx as cn,jsxs as gs}from"react/jsx-runtime";function fp({disabled:e,onApply:t}){let[i,r]=ux(!1),o=cx(null);return On([o],()=>r(!1),i),gs("div",{className:"se-field se-fieldInline bb-presetRow",ref:o,children:[cn("span",{className:"se-fieldLabel",children:"Preset"}),gs("button",{type:"button",className:"bb-presetButton",disabled:e,"aria-expanded":i,onClick:()=>r(n=>!n),children:[cn("span",{children:"Apply a preset"}),cn(bx,{size:12,"aria-hidden":"true"})]}),i?cn("div",{className:"se-addMenu bb-presetMenu",role:"menu","aria-label":"Material presets",children:ms.map(n=>gs("button",{type:"button",role:"menuitem",onClick:()=>{r(!1),t(gp(n))},children:[cn("span",{className:"bb-presetSwatch",style:{background:n.swatch},children:n.id===Dr?cn(px,{size:10,"aria-hidden":"true"}):null}),cn("span",{className:"bb-presetLabel",children:n.label})]},n.id))}):null]})}import{useId as mx}from"react";import{jsx as qn,jsxs as fs}from"react/jsx-runtime";function hp({selectedItem:e,selectedBinding:t,open:i,onToggle:r,updateBinding:o,idError:n}){let c=mx();return qn(Je,{title:"Identity",open:i,onToggle:r,children:fs("div",{className:"bb-grid",children:[fs("div",{className:"bb-field bb-field--row","data-ri-path":"objectBindings[\u2026].modelObjectId",children:[qn("label",{htmlFor:`${c}-model-object-id`,className:"bb-label",title:"The object's exact name in the model file. It can't be changed.",children:"Model object ID"}),qn("input",{id:`${c}-model-object-id`,className:"bb-input bb-readonly",value:t.modelObjectId,readOnly:!0})]}),fs("div",{className:"bb-field bb-field--row","data-ri-path":"objectBindings[\u2026].id",children:[qn("label",{htmlFor:`${c}-id`,className:"bb-label",children:"ID"}),qn("input",{id:`${c}-id`,className:`bb-input ${n?"bb-input--error":""}`,"aria-invalid":n?!0:void 0,"aria-describedby":n?`${c}-id-error`:void 0,value:t.id,onChange:d=>o(e,s=>({...s,id:d.target.value}))}),n?qn("span",{id:`${c}-id-error`,role:"alert",className:"bb-status bb-status--error bb-fieldFull",children:n}):null]})]})})}import{useEffect as gx,useId as fx,useState as xp}from"react";import{jsx as nt,jsxs as Wt}from"react/jsx-runtime";function vp({selectedItem:e,selectedBinding:t,open:i,onToggle:r,updateBinding:o}){let n=fx(),[c,d]=xp(t.group??""),[s,g]=xp(t.tags?.join(", ")??"");gx(()=>{d(t.group??""),g(t.tags?.join(", ")??"")},[e,t.group,t.tags]);let p=()=>{o(e,b=>({...b,group:c.trim()||void 0}))},x=()=>{let b=[...new Set(s.split(",").map(h=>h.trim()).filter(Boolean))];o(e,h=>({...h,tags:b.length>0?b:void 0}))};return Wt(Je,{title:"Basics",open:i,onToggle:r,children:[Wt("div",{className:"bb-grid",children:[Wt("div",{className:"bb-field",children:[nt("label",{htmlFor:`${n}-label`,className:"bb-label",children:"Label"}),nt("input",{id:`${n}-label`,className:"bb-input",value:t.label??"",onChange:b=>o(e,h=>({...h,label:b.target.value}))})]}),Wt("div",{className:"bb-field",children:[nt("label",{htmlFor:`${n}-type`,className:"bb-label",children:"Type"}),nt("input",{id:`${n}-type`,className:"bb-input",list:`${n}-type-suggestions`,value:t.type??"other",onChange:b=>o(e,h=>({...h,type:b.target.value}))}),nt("datalist",{id:`${n}-type-suggestions`,children:pc.map(b=>nt("option",{value:b},b))})]}),Wt("div",{className:"bb-field",children:[nt("label",{htmlFor:`${n}-status`,className:"bb-label",children:"Status"}),nt(et,{id:`${n}-status`,className:"bb-select",value:t.status??"normal",onChange:b=>o(e,h=>({...h,status:b.target.value})),children:bc.map(b=>nt("option",{value:b,children:b},b))})]}),Wt("div",{className:"bb-field",children:[nt("label",{htmlFor:`${n}-group`,className:"bb-label",children:"Group"}),nt("input",{id:`${n}-group`,className:"bb-input",placeholder:"paint",value:c,onChange:b=>d(b.target.value),onBlur:p,onKeyDown:b=>{b.key==="Enter"&&b.currentTarget.blur()}})]}),Wt("div",{className:"bb-field",children:[nt("label",{htmlFor:`${n}-tags`,className:"bb-label",children:"Tags"}),nt("input",{id:`${n}-tags`,className:"bb-input",placeholder:"exterior, configurable",value:s,onChange:b=>g(b.target.value),onBlur:x,onKeyDown:b=>{b.key==="Enter"&&b.currentTarget.blur()}})]})]}),Wt("div",{className:"bb-checkboxRow",children:[Wt("label",{className:"bb-checkbox",children:[nt("input",{type:"checkbox",checked:t.selectable!==!1,onChange:b=>o(e,h=>({...h,selectable:b.target.checked}))}),"Selectable"]}),Wt("label",{className:"bb-checkbox",children:[nt("input",{type:"checkbox",checked:t.hoverable!==!1,onChange:b=>o(e,h=>({...h,hoverable:b.target.checked}))}),"Hoverable"]}),Wt("label",{className:"bb-checkbox",children:[nt("input",{type:"checkbox",checked:t.visible!==!1,onChange:b=>o(e,h=>({...h,visible:b.target.checked}))}),"Visible"]})]})]})}import{useEffect as hx,useState as xx}from"react";import{Plus as vx,Trash2 as yx}from"lucide-react";import{Fragment as Sx,jsx as Ve,jsxs as Mt}from"react/jsx-runtime";var yp=Ea.filter(e=>e.handling==="viewer"),wx=Ea.filter(e=>e.handling==="host");function wp({selectedItem:e,selectedBinding:t,open:i,onToggle:r,updateBinding:o,takesImage:n=!0}){let[c,d]=xx(new Set);hx(()=>{d(new Set)},[e]);let s=t.actions??[],g=(b,h)=>o(e,M=>({...M,actions:(M.actions??[]).map((S,B)=>B===b?h(S):S)})),p=b=>{o(e,h=>({...h,actions:(h.actions??[]).filter((M,S)=>S!==b)})),d(h=>{let M=new Set;return h.forEach(S=>{S<b?M.add(S):S>b&&M.add(S-1)}),M})},x=(b,h)=>d(M=>{let S=new Set(M);return h?S.add(b):S.delete(b),S});return Mt(Je,{title:"Actions",open:i,onToggle:r,children:[Ve("div",{className:"bb-actionList",children:s.map((b,h)=>{let M=gr(b.id),S=c.has(h)||!M,B=b.id.trim(),y=M?null:Nd(b.id),u=B.length>0&&s.some((v,m)=>m!==h&&v.id.trim()===B);return Mt("div",{className:"bb-actionCard",children:[Mt("div",{className:"rui-groupHeader",children:[Mt("span",{children:["Action ",h+1]}),Ve("button",{type:"button",className:"se-iconButton",title:"Remove action","aria-label":`Remove action ${h+1}`,onClick:()=>p(h),children:Ve(yx,{size:13})})]}),Mt("div",{className:"bb-actionGrid",children:[Mt("div",{className:"bb-field bb-field--row","data-ri-path":"objectBindings[\u2026].actions[\u2026].id",children:[Ve("label",{className:"bb-label",children:"ID"}),Mt(et,{className:"bb-select",value:S?mr:b.id,onChange:v=>{let m=v.target.value;if(m===mr){x(h,!0);return}x(h,!1);let N=gr(m);g(h,A=>({...A,id:m,label:N&&ja(A.label)?N.label:A.label}))},children:[Ve("optgroup",{label:"Handled by the viewer",children:yp.map(v=>Ve("option",{value:v.id,children:v.id},v.id))}),Ve("optgroup",{label:"Handled by your app",children:wx.map(v=>Ve("option",{value:v.id,children:v.id},v.id))}),Ve("option",{value:mr,children:"Custom\u2026"})]})]}),S?Mt("div",{className:"bb-field bb-field--row",children:[Ve("label",{className:"bb-label",children:"Custom ID"}),Ve("input",{className:"bb-input",value:b.id,placeholder:"open-datasheet",onChange:v=>{x(h,!0),g(h,m=>({...m,id:v.target.value}))}})]}):null,Mt("div",{className:"bb-field bb-field--row","data-ri-path":"objectBindings[\u2026].actions[\u2026].label",children:[Ve("label",{className:"bb-label",children:"Label"}),Ve("input",{className:"bb-input",value:b.label,onChange:v=>g(h,m=>({...m,label:v.target.value}))})]}),M?.id==="change-material"&&!n?Ve("span",{className:"bb-note bb-note--warning",children:"This object has no texture coordinates, so an image picked here can't be placed on it, and the viewer says so. Change Color and Add Image work."}):M?Ve("span",{className:"bb-note",children:M.description}):B.length===0?Ve("span",{className:"bb-note bb-note--error",children:"An action ID is required, the button renders but can never be identified in onAction."}):Mt("span",{className:"bb-note bb-note--warning",children:["Unrecognised ID, the viewer has no built-in behavior for it. Add declarative effects and execute them with useViewerActions, or handle it in onAction.",y?Mt(Sx,{children:[" Did you mean ",Ve("button",{type:"button",className:"bb-linkButton",onClick:()=>{x(h,!1);let v=gr(y);g(h,m=>({...m,id:y,label:v&&ja(m.label)?v.label:m.label}))},children:y}),"?"]}):null]}),b.effects?.length?Mt("span",{className:"bb-note",children:[b.effects.length," declarative effect",b.effects.length===1?"":"s",", execute with useViewerActions."]}):null,u?Ve("span",{className:"bb-note bb-note--warning",children:"Another action on this binding uses the same ID, they will render as two identical buttons."}):null]})]},h)})}),Ve(go,{children:Mt("button",{type:"button",className:"bb-button",onClick:()=>{let b=yp.find(h=>!s.some(M=>M.id===h.id));o(e,h=>({...h,actions:[...h.actions??[],{id:b?.id??"",label:b?.label??"New action",type:"command"}]})),b||x(s.length,!0)},children:[Ve(vx,{size:13,"aria-hidden":"true"}),"Add action"]})})]})}import{useRef as kx}from"react";import{Image as Cx,ImagePlus as Mx,Trash2 as Px,Type as Sp}from"lucide-react";import{Fragment as Cp,jsx as Ge,jsxs as Pt}from"react/jsx-runtime";var kp=()=>`decal-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;function Mp({selectedItem:e,selectedBinding:t,open:i,onToggle:r,updateBinding:o,placement:n,onPlacementChange:c,defaultSize:d,onImageFile:s,onNudge:g}){let{tier:p}=dt(),x=kx(null),b=t.decals??[],h=n?.nodeKey===e?n:null,M=y=>o(e,u=>({...u,decals:y.length>0?y:void 0})),S=(y,u)=>M(b.map(v=>v.id===y?{...v,...u}:v)),B=y=>{y.image&&di(y.image),h?.decal.id===y.id&&c(null),M(b.filter(u=>u.id!==y.id))};return Pt(Je,{title:"Decals",open:i,onToggle:r,tooltip:"Print a logo, image, or text on the selected object's surface.",children:[Ot(p,"decalsPerObject",b.length)?null:Ge(Ye,{requiredTier:en("decalsPerObject",b.length),feature:"More decals on this object"}),Pt(Cp,{children:[Pt("div",{className:"rui-actions",children:[Pt("button",{type:"button",className:"bb-button",disabled:!Ot(p,"decalsPerObject",b.length),onClick:()=>x.current?.click(),children:[Ge(Mx,{size:13,"aria-hidden":"true"})," Add image"]}),Pt("button",{type:"button",className:"bb-button",disabled:!Ot(p,"decalsPerObject",b.length),onClick:()=>c({nodeKey:e,decal:{id:kp(),text:"Your text",color:"#ffffff",size:d}}),children:[Ge(Sp,{size:13,"aria-hidden":"true"})," Add text"]}),Ge("input",{ref:x,type:"file",accept:"image/png,image/jpeg,image/webp,image/avif,image/svg+xml",className:"bb-hiddenInput",onChange:y=>{let u=y.target.files?.[0];if(y.target.value="",!u)return;let v=Rn(u);_t(v,URL.createObjectURL(u)),s?.(v,u),c({nodeKey:e,decal:{id:kp(),image:v,size:d}})}})]}),b.length===0&&!h?Ge("p",{className:"se-listEmpty",children:"No decals on this object yet."}):null,b.map(y=>Pt("div",{className:"bb-decalCard",children:[Pt("div",{className:"rui-groupHeader",children:[Pt("span",{className:"rui-groupTitle",title:y.image??y.text,children:[y.image?Ge(Cx,{size:13,"aria-hidden":"true"}):Ge(Sp,{size:13,"aria-hidden":"true"}),y.image??y.text]}),Ge("button",{type:"button",className:"se-iconButton",title:"Delete decal","aria-label":"Delete decal",onClick:()=>B(y),children:Ge(Px,{size:13})})]}),Ge(Ad,{onNudge:u=>g(y.id,u)}),Pt("div",{className:"bb-grid",children:[y.image?null:Pt(Cp,{children:[Pt("div",{className:"bb-field bb-field--row",children:[Ge("label",{className:"bb-label",children:"Text"}),Ge("input",{className:"bb-input",value:y.text??"",onChange:u=>S(y.id,{text:u.target.value})})]}),Ge(Fo,{label:"Color",variant:"input",value:y.color??"#ffffff",onChange:u=>S(y.id,{color:u})}),Pt("div",{className:"bb-field bb-field--row",children:[Ge("label",{className:"bb-label",children:"Weight"}),Pt(et,{className:"bb-select",value:y.fontWeight??"bold",onChange:u=>S(y.id,{fontWeight:u.target.value}),children:[Ge("option",{value:"bold",children:"Bold"}),Ge("option",{value:"normal",children:"Regular"})]})]})]}),Ge(ke,{label:"Size",value:Number(y.size.toFixed(4)),min:Number((d/20).toPrecision(2)),max:Number((d*6).toPrecision(2)),step:Number((d/50).toPrecision(1)),onChange:u=>u!==void 0&&u>0&&S(y.id,{size:u})}),Ge(ke,{label:"Rotation",value:Math.round((y.rotation??0)*180/Math.PI),min:-180,max:180,step:1,onChange:u=>S(y.id,{rotation:(u??0)*Math.PI/180})}),Ge(ke,{label:"Opacity",value:y.opacity??1,min:0,max:1,step:.05,onChange:u=>S(y.id,{opacity:u??1})})]})]},y.id))]})]})}import{MapPin as Bx,Trash2 as Tx}from"lucide-react";import{jsx as Bt,jsxs as Pi}from"react/jsx-runtime";var Rx=e=>e.map(t=>t.toFixed(2)).join(", ");function Pp({open:e,onToggle:t,cameraState:i,formattedCameraState:r,savedCameraPosition:o,onSaveCameraPosition:n,onGoToSavedCamera:c,onClearSavedCamera:d,onResetView:s,onFitScene:g}){let p=o?.position&&o?.target?o:null;return Pi(Je,{title:"Saved view",open:e,onToggle:t,tooltip:"Stores the current camera for this object, so selecting it flies there.",children:[Bt(pt,{label:"Camera",children:Bt("code",{className:"rui-readout",children:i?r?.position:"Move the camera"})}),Bt(pt,{label:"Looking at",children:Bt("code",{className:"rui-readout",children:i?r?.target:"\u2013"})}),p?Pi("div",{className:"rui-listRow rui-listRow--saved",children:[Pi("span",{className:"rui-listRowMain",children:[Bt("span",{className:"rui-listRowTitle",children:"Saved view"}),Bt("code",{className:"rui-listRowMeta",children:Rx(p.position)})]}),Pi("span",{className:"rui-listRowActions rui-listRowActions--visible",children:[Bt("button",{type:"button",className:"se-iconButton",onClick:c,title:"Fly to the saved view","aria-label":"Fly to the saved view",children:Bt(Bx,{size:13})}),Bt("button",{type:"button",className:"se-iconButton",onClick:d,title:"Delete saved view","aria-label":"Delete saved view",children:Bt(Tx,{size:13})})]})]}):null,Pi(go,{children:[Bt("button",{type:"button",className:"bb-button",onClick:n,disabled:!i,children:p?"Update view":"Save view"}),Bt("button",{type:"button",className:"bb-button",onClick:s,children:"Reset camera"}),Bt("button",{type:"button",className:"bb-button",onClick:g,children:"Fit scene"})]})]})}import{useLayoutEffect as Nx,useRef as Ax,useState as Ox}from"react";import{RotateCcw as Ex}from"lucide-react";import{jsx as it,jsxs as un}from"react/jsx-runtime";var Tp=["X","Y","Z"],jx=.1,Lx=.1,Bp=.01;function Rp(e){let t=e%360;return t<0?t+360:t}function Ix(e){return Rp(e*180/Math.PI)}function Dx(e){return e*Math.PI/180}function hs({value:e,min:t=-1/0,max:i=1/0,step:r=.1,disabled:o=!1,onChange:n,formatValue:c=g=>Number(g.toFixed(3)),ariaLabel:d,className:s}){let g=c(e),[p,x]=Ox(String(g)),b=Ax(!1);return Nx(()=>{b.current||x(String(g))},[g]),it("input",{type:"number",className:s,step:r,min:t===-1/0?void 0:t,max:i===1/0?void 0:i,value:p,disabled:o,"aria-label":d,onFocus:()=>{b.current=!0},onChange:h=>{let M=h.target.value;if(x(M),M===""||M==="-")return;let S=Number(M);if(Number.isFinite(S)){let B=Math.max(t,Math.min(i,S));n(B)}},onBlur:()=>{b.current=!1,x(String(c(e)))}})}function zx({value:e,min:t=-1/0,max:i=1/0,step:r=.1,disabled:o=!1,onChange:n,formatValue:c=s=>Number(s.toFixed(3)),label:d}){return it("div",{className:"bb-transformAxesGrid",children:Tp.map((s,g)=>un("div",{className:"bb-transformAxis",children:[it("span",{className:"se-axisStepperLabel bb-transformAxisLabel",children:s}),it("div",{className:"bb-transformAxisControl",children:it(hs,{className:"se-numberInput bb-transformNumberInput",step:r,min:t,max:i,value:e[g],disabled:o,formatValue:c,ariaLabel:`${s} ${d?.toLowerCase()||""}`,onChange:p=>{let x=[...e];x[g]=p,n(x,g)}})})]},s))})}function Np({selectedItem:e,selectedBinding:t,open:i,onToggle:r,updateBinding:o,originalTransform:n,originalTransforms:c}){let d=t.transform?.rotation??n?.rotation??[0,0,0],s=t.transform?.position??n?.position??[0,0,0],g=n?.scale??[1,1,1],p=La(t.transform?.scale??g,g),x=(y=e??"")=>c?.[y]??(y===e?n:null),b=(y,u)=>y.transform?.pivot??Ld(u?.pivotLocal??[0,0,0],y.transform?.rotation??u?.rotation??[0,0,0],y.transform?.scale??u?.scale??[1,1,1],u?.rotationOrder??"XYZ",y.transform?.shear),h=(y,u)=>{e&&o(e,(v,m)=>{let N=x(m),K=[...v.transform?.rotation??N?.rotation??[0,0,0]];return K[y]=Dx(Rp(u)),{...v,transform:{...v.transform,rotation:K,pivot:b(v,N)}}})},M=(y,u)=>{e&&o(e,(v,m)=>{let N=x(m),K=[...v.transform?.position??N?.position??[0,0,0]];return K[y]=u,{...v,transform:{...v.transform,position:K}}})},S=y=>{if(!e)return;let u=Math.max(Bp,y);o(e,(v,m)=>{let N=x(m),A=N?.scale??[1,1,1],K=v.transform?.scale??A,T=La(K,A),D=T>0?K:A,k=u/(T||1);return{...v,transform:{...v.transform,scale:D.map(Q=>Q*k),pivot:b(v,N)}}})},B=()=>{!e||!n||o(e,y=>{let u={...y.transform};return delete u.position,delete u.rotation,delete u.scale,delete u.pivot,delete u.shear,{...y,transform:Object.keys(u).length>0?u:void 0}})};return un(Je,{title:"Transform",open:i,onToggle:r,tooltip:"Rotation and scale keep the object's visible center fixed. Scale preserves its proportions.",children:[un("div",{className:"se-field se-fieldInline","data-ri-path":"objectBindings[\u2026].transform.rotation",children:[it("span",{className:"se-fieldLabel",children:"Rotation"}),it("div",{className:"bb-transformAxesGrid",children:Tp.map((y,u)=>{let v=Math.round(Ix(d[u]));return un("div",{className:"bb-transformAxis",children:[it("span",{className:"se-axisStepperLabel bb-transformAxisLabel",children:y}),it("div",{className:"bb-transformAxisControl",children:it(hs,{className:"se-numberInput bb-transformNumberInput",step:1,min:0,max:359,value:v,disabled:!e,formatValue:m=>Math.round(m),ariaLabel:`${y} rotation in degrees`,onChange:m=>h(u,m)})})]},y)})})]}),un("div",{className:"se-field se-fieldInline","data-ri-path":"objectBindings[\u2026].transform.position",children:[it("span",{className:"se-fieldLabel",children:"Position"}),it(zx,{value:s,min:-1/0,max:1/0,step:jx,disabled:!e,label:"position",onChange:(y,u)=>M(u,y[u])})]}),un("div",{className:"se-field se-fieldInline","data-ri-path":"objectBindings[\u2026].transform.scale",children:[it("span",{className:"se-fieldLabel",children:"Scale"}),it(hs,{className:"se-numberInput bb-transformNumberInput",step:Lx,min:Bp,value:p,disabled:!e,formatValue:y=>Number(y.toFixed(2)),ariaLabel:"Uniform scale factor",onChange:S})]}),it(go,{children:un("button",{type:"button",className:"bb-button",disabled:!e||!n,onClick:B,title:"Restore this object's position, rotation, and scale to what they were in the original model",children:[it(Ex,{size:13,"aria-hidden":"true"}),"Restore original"]})})]})}function Ap(e,t,i){let r=e.key?t.has(e.key)?[...t]:[e.key]:e.keys;return[...new Set(r)].filter(o=>i[o]&&!i[o].removed)}function Op(e,t,i){let r=e[t],o=i.trim();return!r||r.removed||!o||r.label===o?e:{...e,[t]:{...r,label:o}}}function Ep(e,t,i){let r=t.filter(n=>e[n]&&!e[n].removed&&e[n].visible!==i);if(!r.length)return e;let o={...e};for(let n of r)o[n]={...e[n],visible:i};return o}import{memo as bv}from"react";import{useCallback as Wx,useEffect as ws,useId as Yx,useLayoutEffect as Ss,useMemo as Wn,useRef as Bi,useState as pn}from"react";import{Box as Jx,ChevronDown as Xx,ChevronRight as Zx,ChevronsDownUp as Qx,ChevronsUpDown as ev,EyeOff as tv,Focus as ov,Folder as nv,Lightbulb as iv,ListChecks as rv,Trash2 as av}from"lucide-react";import{useLayoutEffect as jp,useRef as Fx,useState as xs}from"react";import{ChevronDown as Hx,ChevronRight as $x,Copy as Ux,Eye as Vx,EyeOff as _x,Focus as Lp,ListChecks as Kx,Pencil as Gx,Trash2 as qx}from"lucide-react";import{Fragment as Ip,jsx as ot,jsxs as wo}from"react/jsx-runtime";function Dp({x:e,y:t,name:i,objectKey:r,objectId:o,keys:n,hidden:c,isolated:d,expanded:s,onRename:g,onSetVisible:p,onDelete:x,onFocus:b,onIsolate:h,onSelectContents:M,onToggle:S,onClose:B}){let y=Fx(null),[u,v]=xs(!1),[m,N]=xs(i),[A,K]=xs(!1);jp(()=>{let k=y.current,Q=document.activeElement,G=()=>B();return window.addEventListener("resize",G),window.addEventListener("blur",G),()=>{window.removeEventListener("resize",G),window.removeEventListener("blur",G),(!document.activeElement||document.activeElement===document.body||k?.contains(document.activeElement))&&Q?.isConnected&&Q.focus({preventScroll:!0})}},[B]),jp(()=>{let k=y.current;if(!k)return;let Q=k.getBoundingClientRect();k.style.left=`${Math.max(8,Math.min(e,window.innerWidth-Q.width-8))}px`,k.style.top=`${Math.max(8,Math.min(t,window.innerHeight-Q.height-8))}px`,u?k.querySelector("input")?.select():k.querySelector("button")?.focus()},[e,t,u,A]);let T=(k,Q,G,ee=!1)=>wo("button",{type:"button",role:"menuitem",className:ee?"bb-treeMenuDanger":void 0,onClick:()=>{B(),G()},children:[Q,k]}),D=n.length>1;return ot("div",{className:"bb-pathMenuScrim",onPointerDown:k=>{k.stopPropagation(),B()},onContextMenu:k=>{k.preventDefault(),k.stopPropagation(),B()},children:ot("div",{ref:y,className:"bb-pathMenu bb-treeMenu",style:{left:e,top:t},role:u?"dialog":"menu","aria-modal":u||void 0,"aria-label":u?`Rename ${i}`:`Actions for ${i}`,onPointerDown:k=>k.stopPropagation(),onContextMenu:k=>{k.preventDefault(),k.stopPropagation()},onKeyDown:k=>{if(k.stopPropagation(),k.key==="Escape"){k.preventDefault(),B();return}if(k.key==="Tab"){if(k.preventDefault(),!u){B();return}let le=Array.from(y.current.querySelectorAll("input, button:not(:disabled)")),P=le.indexOf(document.activeElement);le[(P+(k.shiftKey?-1:1)+le.length)%le.length]?.focus();return}if(u||!["ArrowDown","ArrowUp","Home","End"].includes(k.key))return;k.preventDefault();let Q=Array.from(y.current.querySelectorAll("[role=menuitem]")),G=Q.indexOf(document.activeElement),ee=k.key==="Home"?0:k.key==="End"?Q.length-1:(G+(k.key==="ArrowDown"?1:-1)+Q.length)%Q.length;Q[ee]?.focus()},children:u?wo("form",{onSubmit:k=>{k.preventDefault(),!(!m.trim()||!r)&&(g?.(r,m.trim()),B())},children:[wo("label",{children:["Display name",ot("input",{className:"bb-input","aria-label":"Object display name",value:m,maxLength:200,onChange:k=>N(k.target.value)})]}),wo("div",{className:"bb-treeMenuRenameActions",children:[ot("button",{type:"button",onClick:B,children:"Cancel"}),ot("button",{type:"submit",disabled:!m.trim(),children:"Save"})]})]}):wo(Ip,{children:[ot("div",{className:"bb-treeMenuTitle",children:D&&r?`${n.length} selected objects`:i}),r&&b&&T("Focus object",ot(Lp,{size:13}),()=>b(r)),r&&h&&T(d?"Show all objects":"Isolate object",ot(Lp,{size:13}),()=>h(d?null:r)),p&&T(`${c?"Show":"Hide"}${D?` ${n.length} objects`:""}`,c?ot(Vx,{size:13}):ot(_x,{size:13}),()=>p(n,c)),r&&g&&wo("button",{type:"button",role:"menuitem",onClick:()=>v(!0),children:[ot(Gx,{size:13}),"Rename\u2026"]}),!r&&M&&T(`Select contents (${n.length})`,ot(Kx,{size:13}),()=>M(n)),s!==void 0&&T(s?"Collapse branch":"Expand branch",s?ot($x,{size:13}):ot(Hx,{size:13}),S),o&&wo("button",{type:"button",role:"menuitem",onClick:async()=>{await $n(o)?B():K(!0)},children:[ot(Ux,{size:13}),"Copy object ID"]}),A&&wo("p",{role:"status",className:"bb-treeMenuError",children:["Couldn\u2019t copy. Object ID: ",o]}),x&&wo(Ip,{children:[ot("hr",{}),T(D?`Delete ${n.length} objects\u2026`:"Delete\u2026",ot(qx,{size:13}),()=>x(n),!0)]})]})})})}function zp(e,t){let i=new Map(Object.entries(t).filter(([,c])=>!c.removed).map(([c,d])=>[d.modelObjectId??c,c])),r=new Set,o=new Map;for(let c of e){let d=c.objectId?i.get(c.objectId):void 0;d&&r.add(d),o.set(c.id,{id:c.id,name:c.name,key:d,children:[],keys:[]})}let n=[];for(let c of e){let d=o.get(c.id);((c.parentId?o.get(c.parentId):void 0)?.children??n).push(d)}for(let[c,d]of Object.entries(t))!d.removed&&!r.has(c)&&n.push({id:`binding:${c}`,name:d.modelObjectId??c,key:c,children:[],keys:[c]});for(let c=e.length-1;c>=0;c--){let d=o.get(e[c].id);d.children=d.children.filter(s=>s.keys.length),d.keys=[...d.key?[d.key]:[],...d.children.flatMap(s=>s.keys)]}return n.filter(c=>c.keys.length)}function Fp(e,t,i){let r=i.trim().toLowerCase();if(!r)return e;let o=n=>{let c=n.key?t[n.key]:void 0;if([n.name,n.key,c?.label,c?.type,c?.group,...c?.tags??[]].join(" ").toLowerCase().includes(r))return n;let s=n.children.map(o).filter(g=>!!g);return s.length?{...n,key:void 0,children:s,keys:s.flatMap(g=>g.keys)}:null};return e.map(o).filter(n=>!!n)}function vs(e,t,i=!1){let r=[],o=e.slice().reverse().map(n=>({node:n,depth:0,parentId:null}));for(;o.length;){let n=o.pop();if(r.push(n),i||!t.has(n.node.id))for(let c=n.node.children.length-1;c>=0;c--)o.push({node:n.node.children[c],depth:n.depth+1,parentId:n.node.id})}return r}function ys(e,t){for(let i of e){if(i.key===t)return[];let r=ys(i.children,t);if(r)return[i.id,...r]}return null}function Hp(e,t,i,r,o){if(o.range){let n=i?r.indexOf(i):-1,c=r.indexOf(t);if(n>=0&&c>=0){let d=r.slice(Math.min(n,c),Math.max(n,c)+1);return[...new Set(o.additive?[...e,...d]:d)]}}return o.toggle||o.additive?e.includes(t)?e.filter(n=>n!==t):[...e,t]:[t]}import{Fragment as pv,jsx as me,jsxs as ht}from"react/jsx-runtime";var sv=[],lv=[],dv=[],So=24;function cv({count:e,total:t,name:i,onChange:r}){let o=Bi(null);return Ss(()=>{o.current&&(o.current.indeterminate=e>0&&e<t)},[e,t]),me("input",{ref:o,className:"bb-treeCheckbox",type:"checkbox","aria-label":`Select ${i}`,"aria-checked":e>0&&e<t?"mixed":e===t,checked:e===t&&t>0,onChange:r})}function zr({bindings:e,hierarchy:t=lv,selectedItem:i,onSelect:r,onHover:o,fill:n,isolatedItem:c,onIsolate:d,multiSelectEnabled:s=!1,multiSelectedKeys:g=sv,onSetMultiSelected:p,selectionSets:x=dv,onSelectionSetsChange:b,onToggleMultiSelect:h,onRename:M,onSetVisible:S,onDelete:B,onFocus:y}){let[u,v]=pn(""),[m,N]=pn(()=>new Set),[A,K]=pn(""),T=Bi(null),D=Wn(()=>zp(t,e),[t,e]),k=Wn(()=>Fp(D,e,u),[D,e,u]),Q=Wn(()=>vs(k,m,!!u.trim()),[k,m,u]),G=Wn(()=>Q.flatMap(({node:z})=>z.key?[z.key]:[]),[Q]),ee=Wn(()=>k.flatMap(z=>z.keys),[k]),le=Bi(null);ws(()=>{if(le.current===i)return;let z=i?ys(D,i):null;i&&!z||(le.current=i,z?.length&&N(U=>{if(!z.some(be=>U.has(be)))return U;let xe=new Set(U);return z.forEach(be=>xe.delete(be)),xe}))},[i,D]);let P=Wn(()=>new Set(s||g.length>0?g:i?[i]:[]),[s,g,i]),L=ee.length>0&&ee.every(z=>P.has(z)),Me=z=>{let U=z.every(be=>P.has(be)),xe=new Set(z);p?.(U?[...P].filter(be=>!xe.has(be)):[...new Set([...P,...z])])},Xe=z=>N(U=>{let xe=new Set(U);return xe.has(z)?xe.delete(z):xe.add(z),xe}),Z=(z,U)=>{let xe=z.node.key;if(!xe){Xe(z.node.id);return}p&&(s||U.shiftKey||U.ctrlKey||U.metaKey)?p(Hp([...P],xe,T.current??i,G,{range:U.shiftKey,additive:U.ctrlKey||U.metaKey,toggle:s&&!U.shiftKey})):r(xe),U.shiftKey||(T.current=xe)},Le=z=>{let U=new Set(z.objectIds);return Object.keys(e).filter(xe=>!e[xe].removed&&U.has(e[xe].modelObjectId??xe))},Ze=Ot(dt().tier,"selectionSets",x.length),O=()=>{let z=[...P].filter(U=>e[U]&&!e[U].removed);!z.length||!A.trim()||x.length>=128||!Ze||(b?.([...x,{id:crypto.randomUUID(),name:A.trim(),objectIds:z.map(U=>e[U].modelObjectId??U)}]),K(""))};return ht("section",{className:`bb-nodeList ${n?"bb-nodeList--fill":""}`,children:[ht("div",{className:"bb-outlinerHead",children:[me("div",{className:"bb-search",children:me("input",{className:"bb-input","aria-label":"Filter objects",placeholder:"Filter objects",value:u,onChange:z=>v(z.target.value)})}),h&&me("button",{type:"button",className:`bb-treeIcon ${s?"bb-treeIcon--active":""}`,"aria-pressed":s,"aria-label":"Toggle multi-select",title:s?"Multi-select on: edits apply to every selected object":"Select multiple objects",onClick:h,children:me(rv,{size:14})}),me("button",{type:"button",className:"bb-treeIcon","aria-label":"Expand all",title:"Expand all",onClick:()=>N(new Set),children:me(ev,{size:14})}),me("button",{type:"button",className:"bb-treeIcon","aria-label":"Collapse all",title:"Collapse all",onClick:()=>N(new Set(vs(D,new Set,!0).filter(({node:z})=>z.children.length).map(({node:z})=>z.id))),children:me(Qx,{size:14})})]}),p&&u.trim()&&ee.length>0&&ht("div",{className:"bb-selectionModeBar bb-selectionModeBar--matches",children:[ht("span",{children:[ee.length," ",ee.length===1?"match":"matches"]}),me("button",{type:"button",className:"bb-button bb-button--small",onClick:()=>Me(ee),children:L?"Clear":"Select all"})]}),me(uv,{rows:Q,revealKey:i,bindings:e,selected:P,multiSelect:s,collapsed:m,searching:!!u.trim(),search:u,onSelect:Z,onToggle:Xe,onToggleKeys:p?Me:void 0,onSelectAll:p?()=>p(ee):void 0,onHover:o,isolatedItem:c,onIsolate:d,onRename:M,onSetVisible:S,onDelete:B,onFocus:y,onSetMultiSelected:p}),b&&ht("details",{className:"bb-selectionSets",children:[ht("summary",{children:["Saved selections",x.length?` (${x.length})`:""]}),ht("div",{className:"bb-selectionSetCreate",children:[me("input",{className:"bb-input","aria-label":"Selection name",placeholder:"Name this selection",maxLength:200,value:A,onChange:z=>K(z.target.value),onKeyDown:z=>{z.key==="Enter"&&(z.preventDefault(),O())}}),me("button",{type:"button",className:"bb-button bb-button--ghost",disabled:!P.size||!A.trim()||x.length>=128||!Ze,title:Ze?void 0:"Saving more selections requires the Starter plan or higher.",onClick:O,children:"Save"})]}),!x.length&&me("p",{children:"Select objects, then save the selection to reuse it."}),x.map(z=>{let U=Le(z);return ht("div",{className:"bb-selectionSetRow",children:[ht("button",{type:"button",className:"bb-button bb-button--ghost",disabled:!U.length,title:U.length<z.objectIds.length?`${z.objectIds.length-U.length} objects unavailable`:void 0,onClick:()=>{v(""),N(new Set),p?.(U),T.current=U[0]??null},children:[z.name,ht("small",{children:[U.length," / ",z.objectIds.length]})]}),me("button",{type:"button",className:"bb-treeIcon","aria-label":`Delete selection ${z.name}`,onClick:()=>b(x.filter(xe=>xe.id!==z.id)),children:me(av,{size:14})})]},z.id)})]})]})}function uv({rows:e,revealKey:t,bindings:i,selected:r,multiSelect:o,collapsed:n,searching:c,search:d,onSelect:s,onToggle:g,onToggleKeys:p,onSelectAll:x,onHover:b,isolatedItem:h,onIsolate:M,onRename:S,onSetVisible:B,onDelete:y,onFocus:u,onSetMultiSelected:v}){let[m,N]=pn(null),A=Wx(()=>N(null),[]),K=Bi(null),T=(O,z,U)=>{let xe=Ap(O.node,r,i);xe.length&&(K.current?.focus({preventScroll:!0}),O.node.key&&!r.has(O.node.key)&&v?.([O.node.key]),b?.(null),N({row:O,x:z,y:U,keys:xe}))};ws(()=>{A()},[d,i,A]);let[D,k]=pn(400),[Q,G]=pn(0),[ee,le]=pn(0),P=Yx();Ss(()=>{let O=K.current;if(!O)return;let z=new ResizeObserver(()=>k(O.clientHeight));return z.observe(O),()=>z.disconnect()},[]),ws(()=>{K.current&&(K.current.scrollTop=0),G(0),le(0)},[d]);let L=O=>{O=Math.max(0,Math.min(e.length-1,O)),le(O);let z=K.current;z&&(O*So<z.scrollTop?z.scrollTop=O*So:(O+1)*So>z.scrollTop+z.clientHeight&&(z.scrollTop=(O+1)*So-z.clientHeight))},Me=Bi(null);Ss(()=>{if(Me.current===t)return;if(!t){Me.current=null;return}let O=e.findIndex(({node:z})=>z.key===t);O<0||(Me.current=t,L(O))});let Xe=O=>{let z=e[Math.min(ee,e.length-1)];if(z){if(O.key==="ContextMenu"||O.shiftKey&&O.key==="F10"){O.preventDefault(),O.stopPropagation();let U=document.getElementById(`${P}-${Math.min(ee,e.length-1)}`)?.getBoundingClientRect();U&&T(z,U.left+24,U.bottom);return}if((O.ctrlKey||O.metaKey)&&O.key.toLowerCase()==="a"){O.preventDefault(),O.stopPropagation(),x?.();return}if(["ArrowDown","ArrowUp","ArrowLeft","ArrowRight","Home","End","Enter"," "].includes(O.key)){if(O.preventDefault(),O.stopPropagation(),O.key==="ArrowDown"&&L(ee+1),O.key==="ArrowUp"&&L(ee-1),O.key==="Home"&&L(0),O.key==="End"&&L(e.length-1),O.key==="ArrowRight"&&z.node.children.length&&(n.has(z.node.id)?g(z.node.id):L(ee+1)),O.key==="ArrowLeft")if(z.node.children.length&&!n.has(z.node.id))g(z.node.id);else{let U=e.findIndex(xe=>xe.node.id===z.parentId);U>=0&&L(U)}(O.key==="Enter"||O.key===" ")&&(O.key===" "&&o&&!z.node.key?p?.(z.node.keys):s(z,O))}}},Z=Math.max(0,Math.min(e.length-1,Math.floor(Q/So))-5),Le=Math.min(e.length,Z+Math.ceil(D/So)+12),Ze=Math.min(ee,e.length-1);return ht(pv,{children:[ht("div",{ref:K,className:"bb-sceneTree",role:"tree","aria-label":"Scene hierarchy","aria-multiselectable":!!x,tabIndex:0,"aria-activedescendant":Ze>=Z&&Ze<Le?`${P}-${Ze}`:void 0,onKeyDown:Xe,onScroll:O=>{G(O.currentTarget.scrollTop),A()},children:[!e.length&&me("p",{className:"bb-treeEmpty",children:"No matching objects."}),me("div",{style:{height:e.length*So,position:"relative"},children:e.slice(Z,Le).map((O,z)=>{let{node:U,depth:xe}=O,be=Z+z,xt=U.key?i[U.key]:void 0,Te=U.keys.reduce((Jt,ji)=>Jt+Number(r.has(ji)),0),ro=U.children.length?c||!n.has(U.id):void 0,Jn=U.key?r.has(U.key):Te===U.keys.length;return ht("div",{id:`${P}-${be}`,role:"treeitem","aria-level":xe+1,"aria-expanded":ro,"aria-selected":Jn,className:`bb-treeRow${Jn?" bb-treeRow--selected":""}${U.key?" bb-treeRow--object":""}${xt?.visible===!1?" bb-treeRow--hidden":""}`,style:{top:be*So,height:So,paddingLeft:4+Math.min(xe,10)*12},onContextMenu:Jt=>{Jt.preventDefault(),Jt.stopPropagation(),le(be),T(O,Jt.clientX,Jt.clientY)},onFocus:()=>le(be),onMouseEnter:()=>b?.(U.key??null),onMouseLeave:()=>b?.(null),children:[U.children.length?me("button",{type:"button",tabIndex:-1,className:"bb-treeIcon","aria-label":`${ro?"Collapse":"Expand"} ${U.name}`,onClick:()=>g(U.id),children:ro?me(Xx,{size:13}):me(Zx,{size:13})}):me("span",{className:"bb-treeSpacer"}),o&&p&&me(cv,{count:Te,total:U.keys.length,name:U.name,onChange:()=>p(U.keys)}),ht("button",{type:"button",tabIndex:-1,className:"bb-treeNode",onClick:Jt=>{le(be),K.current?.focus({preventScroll:!0}),s(O,Jt)},children:[xt?xt.type==="light"?me(iv,{size:13,"aria-hidden":"true"}):me(Jx,{size:13,"aria-hidden":"true"}):me(nv,{size:13,"aria-hidden":"true"}),me("span",{title:xt?`${xt.type??"other"} \xB7 ${xt.modelObjectId}`:void 0,children:xt?.label||U.name}),xt?null:me("small",{children:U.keys.length})]}),xt?.visible===!1&&me(tv,{size:12,className:"bb-treeHiddenIcon","aria-label":"Hidden"}),U.key&&M&&me("button",{type:"button",tabIndex:-1,className:"bb-treeIcon bb-treeIsolate","aria-label":`${h===U.key?"Show all":"Isolate"} ${U.name}`,"aria-pressed":h===U.key,onClick:()=>M(h===U.key?null:U.key),children:me(ov,{size:13})})]},U.id)})})]}),m&&me(Dp,{x:m.x,y:m.y,name:m.row.node.key&&i[m.row.node.key]?.label||m.row.node.name,objectKey:m.row.node.key,objectId:m.row.node.key?i[m.row.node.key]?.modelObjectId??m.row.node.key:void 0,keys:m.keys,hidden:m.keys.every(O=>i[O]?.visible===!1),isolated:h===m.row.node.key,expanded:!c&&m.row.node.children.length?!n.has(m.row.node.id):void 0,onRename:S,onSetVisible:B,onDelete:y,onFocus:u,onIsolate:M,onSelectContents:v,onToggle:()=>g(m.row.node.id),onClose:A})]})}import{Fragment as fv,jsx as bn,jsxs as ks}from"react/jsx-runtime";var Cs=[],$p=bv(mv);function Ms(e){let t=0;for(let i of Object.values(e))i.removed||(t+=1);return t}function mv({bindings:e,selectedItem:t,onSelect:i,onHover:r,modelGroups:o,onSelectModel:n,isolatedItem:c=null,onIsolate:d,multiSelectEnabled:s=!1,onToggleMultiSelect:g,onExitMultiSelect:p,multiSelectedKeys:x=Cs,onSetMultiSelected:b,hierarchy:h,selectionSets:M,onSelectionSetsChange:S,onRename:B,onSetVisible:y,onDelete:u,onFocus:v}){let m=o&&o.length>=2?o:null,N=m?m.reduce((A,K)=>A+Ms(K.bindings),0):Ms(e);return ks(fv,{children:[s&&ks("div",{className:"bb-selectionModeBar",children:[ks("span",{children:[x.length," of ",N," selected"]}),bn("button",{type:"button",className:"bb-button bb-button--small","aria-label":"Exit multi-select",onClick:p??g,children:"Done"})]}),m?bn(gv,{groups:m,selectedItem:t,onSelect:i,onHover:r,onSelectModel:n,isolatedItem:c,onIsolate:d,multiSelectEnabled:s,multiSelectedKeys:x,onSetMultiSelected:b,onToggleMultiSelect:g,hierarchy:h,selectionSets:M,onSelectionSetsChange:S,onRename:B,onSetVisible:y,onDelete:u,onFocus:v}):bn(zr,{bindings:e,selectedItem:t,onSelect:i,onHover:r,isolatedItem:c,onIsolate:d,multiSelectEnabled:s,multiSelectedKeys:x,onSetMultiSelected:b,onToggleMultiSelect:g,hierarchy:h,selectionSets:M,onSelectionSetsChange:S,onRename:B,onSetVisible:y,onDelete:u,onFocus:v})]})}function gv({groups:e,selectedItem:t,onSelect:i,onHover:r,onSelectModel:o,isolatedItem:n=null,onIsolate:c,multiSelectEnabled:d=!1,multiSelectedKeys:s=Cs,onSetMultiSelected:g,onToggleMultiSelect:p,hierarchy:x,selectionSets:b,onSelectionSetsChange:h,onRename:M,onSetVisible:S,onDelete:B,onFocus:y}){return bn("section",{className:"bb-nodeList bb-nodeList--grouped",children:e.map(u=>{let v=u.isActive,m=Ms(u.bindings),N=`${u.label} (${m})${u.isActive?" \xB7 Active":""}`,A=v;return bn("div",{className:`bb-groupItem ${A?"bb-groupItem--fill":""}`,children:bn(Je,{title:N,open:v,onToggle:()=>{o?.(u.url)},children:bn(zr,{bindings:u.bindings,hierarchy:u.isActive?x:void 0,selectionSets:u.isActive?b:void 0,onSelectionSetsChange:u.isActive?h:void 0,selectedItem:t,onSelect:K=>{o?.(u.url),i(K)},onHover:r,fill:A,isolatedItem:u.isActive?n:null,onIsolate:u.isActive?c:void 0,multiSelectEnabled:u.isActive&&d,multiSelectedKeys:u.isActive?s:Cs,onSetMultiSelected:u.isActive?g:void 0,onToggleMultiSelect:u.isActive?p:void 0,onRename:u.isActive?M:void 0,onSetVisible:u.isActive?S:void 0,onDelete:u.isActive?B:void 0,onFocus:u.isActive?y:void 0})})},u.url)})})}import{jsx as Ps,jsxs as hv}from"react/jsx-runtime";function Bs({title:e,label:t,open:i,onToggle:r,draft:o,error:n,example:c,onDraftChange:d,onCommit:s}){return Ps(Je,{title:e,open:i,onToggle:r,children:hv("div",{className:"rui-stack",children:[Ps("textarea",{className:"bb-textarea","aria-label":t,placeholder:c,value:o,onChange:g=>d(g.target.value),onBlur:s}),n?Ps("span",{className:"bb-note bb-note--error",children:n}):null]})})}import{useCallback as Lt}from"react";import{PropertyBinding as _p}from"three";import{PropertyBinding as Ts}from"three";function Up(e){let t=new Map;return e.map(i=>{let r=(t.get(i)??0)+1;return t.set(i,r),r===1?i:`${i} (${r})`})}function mn(e,t,i=[],r={},o=new Set(Object.keys(lr(e).nodesById))){let n=new Map(Object.entries(t).filter(([,b])=>b.removed===!0).map(([b,h])=>[h.modelObjectId??b,h])),c=new Set(Object.entries(r).map(([b,h])=>h.modelObjectId??b)),d=i.filter(b=>b.loadState==="loading").map(b=>Ts.sanitizeNodeName(`${io(b.namePrefix)}_`)),s=Object.fromEntries(Object.entries(t).filter(([b,h])=>{let M=h.modelObjectId??b;return!c.has(M)&&(h.removed===!0||o.has(M)||d.some(S=>M.startsWith(S)))})),g=Object.fromEntries(Object.entries(r).map(([b,h])=>[b,n.get(h.modelObjectId??b)??h])),p={...s,...g},x=Object.keys(p);return x.length===Object.keys(t).length&&x.every(b=>p[b]===t[b])?t:p}function io(e){return e.replace(/\.[^./\\]+$/,"")}function Rs(e,t,i={}){let r=Ts.sanitizeNodeName(io(e)).replace(/_/g,"-")||"Model",o=t.map(d=>Ts.sanitizeNodeName(io(d.namePrefix))),n=Object.entries(i).map(([d,s])=>s.modelObjectId??d),c=r;for(let d=2;;d++){let s=`${c}_`;if(!o.some(g=>g===c||g.startsWith(s))&&!n.some(g=>g.startsWith(s)))return c;c=`${r}-${d}`}}function Yn(e){e.resolved.cleanup()}function Ti(e){e.resolved?.cleanup(),e.mergedModelSources.forEach(Yn)}function Ri(e,t){let i=Ud(e),r=ui(i,hr(e));if(t){let n=new Map(Object.values(t).map(c=>[c.modelObjectId,c]));for(let c of i){let d=n.get(c);d&&(r[c]=d)}}e.updateMatrixWorld(!0);let o={};for(let n of i){let c=li(e,n);if(!c){o[n]={position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],pivotLocal:[0,0,0],rotationOrder:"XYZ"};continue}let d=jd(c);o[n]={position:[c.position.x,c.position.y,c.position.z],rotation:[c.rotation.x,c.rotation.y,c.rotation.z],scale:[c.scale.x,c.scale.y,c.scale.z],pivotLocal:[d.x,d.y,d.z],rotationOrder:c.rotation.order}}return{bindings:r,originalTransforms:o,nodeNames:i}}function xv(e,t){let i=e;for(;i;){if(i===t)return!0;i=i.parent}return!1}function Ns(e,t){let i=e.parent??e,r=Ri(i,t),o=r.nodeNames.filter(n=>{let c=li(i,n);return c?xv(c,e):!1});return{bindings:Object.fromEntries(o.map(n=>[n,r.bindings[n]])),originalTransforms:Object.fromEntries(o.map(n=>[n,r.originalTransforms[n]])),nodeNames:o}}function Fr(e,t=[]){let i={bindings:e,mergeSources:t};return{past:[],present:i,future:[],baseline:i,edits:0}}function Kp(e,t){let i=t(e.present),r=e.past.map(t),o=e.future.map(t),n=t(e.baseline);return i===e.present&&n===e.baseline&&r.every((c,d)=>c===e.past[d])&&o.every((c,d)=>c===e.future[d])?e:{...e,present:i,past:r,future:o,baseline:n}}function Gp(e,t,i,r={}){return Kp(e,o=>{if(!o.mergeSources.some(d=>d.url===t))return o;let n=new Map(Object.entries(o.bindings).map(([d,s])=>[s.modelObjectId??d,s])),c={...o.bindings};for(let[d,s]of Object.entries(r))c[d]=n.get(s.modelObjectId??d)??s;return{bindings:c,mergeSources:o.mergeSources.map(d=>d.url===t?{...d,...i}:d)}})}function As(e,t){let i=e.mergeSources.find(n=>n.url===t);if(!i)return e;let r=new Set(i.nodeNames),o=_p.sanitizeNodeName(`${io(i.namePrefix)}_`);return{mergeSources:e.mergeSources.filter(n=>n.url!==t),bindings:Object.fromEntries(Object.entries(e.bindings).filter(([n,c])=>{let d=c.modelObjectId??n;return!r.has(d)&&!r.has(n)&&!d.startsWith(o)}))}}function Os(e,t){let i=xo(e.bindingHistory??Fr(e.bindings,e.mergedModelSources),{type:"set",updater:t,track:!0,coalesce:!1});return{...e,bindings:i.present.bindings,mergedModelSources:i.present.mergeSources,bindingHistory:i}}function Es(e,t,i,r){let o=Gp(e.bindingHistory??Fr(e.bindings,e.mergedModelSources),t,i,r);return{...e,bindings:o.present.bindings,mergedModelSources:o.present.mergeSources,bindingHistory:o}}function qp(e,t){let i=e.bindingHistory??Fr(e.bindings,e.mergedModelSources),o=[i.present,...i.past,...i.future].flatMap(d=>d.mergeSources).map(d=>_p.sanitizeNodeName(`${io(d.namePrefix)}_`)),n=Object.fromEntries(Object.entries(t).filter(([d,s])=>!o.some(g=>(s.modelObjectId??d).startsWith(g)))),c=Kp(i,d=>({...d,bindings:{...n,...d.bindings}}));return{...e,bindings:c.present.bindings,bindingHistory:c}}function Vp(e,t){let i=new Set(t.mergeSources.map(r=>r.url));return{...e,present:{...e.present,mergeSources:e.present.mergeSources.map(r=>i.has(r.url)?r:{...r,loadState:"loading"})}}}function Wp(e,t=[]){let i=fi({bindings:e,mergeSources:t}),{setValue:r,setValueAsStep:o,updateHistory:n,restoreSnapshot:c}=i,d=Lt(v=>r(m=>{let N=typeof v=="function"?v(m.bindings):v;return N===m.bindings?m:{...m,bindings:N}}),[r]),s=Lt(v=>o(m=>{let N=typeof v=="function"?v(m.bindings):v;return N===m.bindings?m:{...m,bindings:N}}),[o]),g=Lt(v=>n(m=>{let N=typeof v=="function"?v(m.present.bindings):v;if(N===m.present.bindings)return m;let A={...m.present,bindings:N};return{...m,present:A,baseline:m.edits===0?A:m.baseline}}),[n]),p=Lt(v=>n(m=>{let N=typeof v=="function"?v(m.present.mergeSources):v,A={...m.present,mergeSources:N};return{...m,present:A,baseline:m.edits===0?A:m.baseline}}),[n]),x=Lt(v=>o(m=>({...m,mergeSources:[...m.mergeSources,typeof v=="function"?v(m):v]})),[o]),b=Lt(v=>o(m=>As(m,v)),[o]),h=Lt((v,m,N)=>{n(A=>Gp(A,v,m,N))},[n]),M=Lt(()=>c(v=>{let m=xo(v,{type:"undo"});return m===v?v:Vp(m,v.present)}),[c]),S=Lt(()=>c(v=>{let m=xo(v,{type:"redo"});return m===v?v:Vp(m,v.present)}),[c]),B=Lt((v,m)=>c(N=>xo(N,{type:"reset",value:{bindings:v,mergeSources:N.present.mergeSources},track:m?.asEdit??!1})),[c]),y=Lt(()=>c(v=>xo(v,{type:"reset",value:v.present,track:!1})),[c]),u=Lt(v=>c({...v.bindingHistory??Fr(v.bindings,v.mergedModelSources),present:{bindings:v.bindings,mergeSources:v.mergedModelSources}}),[c]);return{value:i.value.bindings,baseline:i.baseline.bindings,mergeSources:i.value.mergeSources,snapshot:i.snapshot,edits:i.edits,canUndo:i.canUndo,canRedo:i.canRedo,setValue:d,setValueAsStep:s,setValueUntracked:g,setMergeSourcesUntracked:p,addMerge:x,removeMerge:b,hydrateMerge:h,undo:M,redo:S,reset:B,clearHistory:y,restoreModel:u}}import{useEffect as Yp,useRef as vv}from"react";function Jp(e,t,{modelUrl:i,modelSourceRef:r,uploadedFilesRef:o}={}){let n=vv(new Map);Yp(()=>{let c=new Map,d=p=>{for(let x of[p.present,...p.past,...p.future])x.mergeSources.forEach(b=>c.set(b.url,b))};d(e);for(let p of t)p.bindingHistory&&d(p.bindingHistory),p.mergedModelSources.forEach(x=>c.set(x.url,x));for(let[p,x]of n.current)c.has(p)||x.resolved.cleanup();n.current=c;let s=new Set,g=p=>{p?.kind==="file"&&s.add(p.key)};i&&g(r?.current?.model),t.forEach(p=>g(p.sessionModel)),c.forEach(p=>g(p.sessionModel));for(let p of o?.current.keys()??[])s.has(p)||o?.current.delete(p)},[e,t,i,r,o]),Yp(()=>()=>{n.current.forEach(c=>c.resolved.cleanup()),n.current.clear(),o?.current.clear()},[o])}import{useCallback as yv,useEffect as js,useRef as wv}from"react";var Sv=500;function Xp({composition:e,autosaveEnabled:t,hasEdits:i,modelUrl:r,bindings:o,sceneConfig:n,parkedModels:c,mergedModelSources:d,modelOrder:s,onTextureUpload:g,modelSourceRef:p,pendingLoadRef:x,storedModelKeysRef:b,uploadedFilesRef:h,pendingAutosaveRef:M,autosaveFailureShownRef:S,setStatusMessage:B,setStatusTone:y}){let u=wv(0),v=yv(async(m,N)=>{if(g)return g(m,N);let A=URL.createObjectURL(m);if(t)try{await Dn(A,m)}catch(K){console.warn("[BindingBuilder] Could not store texture file for autosave:",K)}return A},[g,t]);return js(()=>{if(!t||!i){M.current=null;return}let m=p.current;if(r&&!m){M.current=null;return}let N=r,A=()=>{if(M.current!==A||x.current)return;M.current=null;let T=++u.current,D=Z=>{console.warn("[BindingBuilder] Autosave failed:",Z),!S.current&&(S.current=!0,B("Couldn't autosave this session \u2014 the browser refused to store it, possibly for lack of space. Export your work to keep it."),y("error"))};if(!N||!m)return;let{model:k}=m,Q=[],G=new Set,ee=Z=>{if(!Z||Z.kind!=="file"||(G.add(Z.key),b.current.has(Z.key)))return;let Le=h.current.get(Z.key);Le&&Q.push({key:Z.key,file:Le})};ee(k),c.forEach(Z=>{ee(Z.sessionModel),Z.mergedModelSources.forEach(Le=>ee(Le.sessionModel))}),d.forEach(Z=>ee(Z.sessionModel)),b.current=new Set([...b.current].filter(Z=>G.has(Z)));let le=Z=>({model:Z.sessionModel,namePrefix:Z.namePrefix}),P=c.filter(Z=>!!Z.sessionModel).map(Z=>({model:Z.sessionModel,bindings:Z.bindings,originalTransforms:Z.originalTransforms,modelSettings:Z.modelSettings,mergeModels:Z.mergedModelSources.map(le)})),L=d.map(le),Me=new Map;Me.set(N,k),c.forEach(Z=>{Z.sessionModel&&Me.set(Z.url,Z.sessionModel)});let Xe=s.map(Z=>{let Le=Me.get(Z);return Le?eo(Le):null}).filter(Z=>Z!==null);Sc({model:k,composition:e,bindings:o,sceneConfig:n,parkedModels:P,mergeModels:L,modelOrder:Xe},Q).then(()=>{T===u.current&&(b.current=G,S.current=!1)}).catch(D)};if(M.current=A,!N){A();return}let K=window.setTimeout(A,Sv);return()=>window.clearTimeout(K)},[e,t,i,r,o,n,c,d,s]),js(()=>{if(!t)return;let m=()=>M.current?.(),N=()=>{document.visibilityState==="hidden"&&m()};return window.addEventListener("pagehide",m),document.addEventListener("visibilitychange",N),()=>{window.removeEventListener("pagehide",m),document.removeEventListener("visibilitychange",N),m()}},[t]),js(()=>{if(!t||!r||!i)return;let m=N=>{M.current?.(),N.preventDefault(),N.returnValue=""};return window.addEventListener("beforeunload",m),()=>window.removeEventListener("beforeunload",m)},[t,r,i]),{handleTextureUpload:v}}import{useCallback as Ls,useEffect as kv,useRef as gn}from"react";var Is=640,Ds=360,Cv=.82,Mv=4e3,Pv=2*6e4,Zp=1e3,Bv=6e4;function Tv({now:e,lastActivityAt:t,lastCaptureAt:i,ready:r,loadingTiles:o}){if(!r)return Zp;let n=e-t;return o&&n<Bv?Zp:Math.max(Mv-n,Pv-(e-i),0)}async function Rv(e){let t=new Image;t.src=e,await t.decode();let i=document.createElement("canvas");i.width=Is,i.height=Ds;let r=Math.max(Is/t.naturalWidth,Ds/t.naturalHeight),o=t.naturalWidth*r,n=t.naturalHeight*r,c=i.getContext("2d");if(!c)throw new Error("No 2D canvas to draw the thumbnail on.");return c.imageSmoothingQuality="high",c.drawImage(t,(Is-o)/2,(Ds-n)/2,o,n),new Promise((d,s)=>{i.toBlob(g=>g?d(g):s(new Error("Could not encode the thumbnail.")),"image/jpeg",Cv)})}function Qp({onCapture:e,hasThumbnail:t,viewerRef:i,isModelLoading:r}){let o=gn(e);o.current=e;let n=gn(r);n.current=r;let c=gn(!1),d=gn(!1),s=gn(null),g=gn(0),p=gn(Number.NEGATIVE_INFINITY),x=Ls(()=>{if(!o.current||!c.current||d.current||s.current!==null)return;let S=i.current,B=Date.now(),y=Tv({now:B,lastActivityAt:g.current,lastCaptureAt:p.current,ready:!!S&&!n.current()&&document.visibilityState==="visible",loadingTiles:S?.isLoadingTiles()??!1});if(y>0){s.current=window.setTimeout(()=>{s.current=null,x()},y);return}d.current=!0,c.current=!1,p.current=B,S.captureImage({type:"image/jpeg",quality:.92}).then(Rv).then(u=>o.current?.(u)).catch(u=>{c.current=!0,console.warn("[react-immersive] Could not update the project thumbnail.",u)}).finally(()=>{d.current=!1,x()})},[i]),b=Ls(()=>{g.current=Date.now()},[]),h=Ls(()=>{b(),c.current=!0,x()},[b,x]),M=!!e;return kv(()=>{if(!M)return;g.current=Date.now(),t||(c.current=!0),x();let S=["pointermove","pointerdown","keydown","wheel"];for(let B of S)window.addEventListener(B,b,{passive:!0,capture:!0});return()=>{for(let B of S)window.removeEventListener(B,b,{capture:!0});s.current!==null&&window.clearTimeout(s.current),s.current=null}},[M,t,b,x]),{markThumbnailOutdated:h,noteThumbnailActivity:b}}import{useLayoutEffect as Nv}from"react";function eb({bindings:e,multiSelectMode:t,selectedItem:i,multiSelectedKeys:r,setSelectedItem:o,setMultiSelectedKeys:n}){Nv(()=>{let c=s=>!!(e[s]&&!e[s].removed),d=r.filter(c);d.length!==r.length&&n(d),i&&(!c(i)||t&&!d.includes(i))&&o(t?d[d.length-1]??null:null)},[e,t,i,r,o,n])}import{useCallback as Ho,useReducer as Av}from"react";var Fs={selectedItem:null,keys:[],checkboxMode:!1},zs=(e,t)=>typeof e=="function"?e(t):e;function Ov(e,t){if(t.type==="primary"){let s=zs(t.value,e.selectedItem);return s===e.selectedItem?e:{...e,selectedItem:s}}if(t.type==="keys"){let s=zs(t.value,e.keys);return s===e.keys?e:{...e,keys:s}}if(t.type==="mode"){let s=zs(t.value,e.checkboxMode);return s===e.checkboxMode?e:{...e,checkboxMode:s}}if(t.type==="clear")return Fs;if(t.type==="exitMode"||t.type==="toggleMode"&&e.checkboxMode)return{...e,checkboxMode:!1,keys:[]};if(t.type==="toggleMode")return{...e,checkboxMode:!0,keys:e.keys.length?e.keys:e.selectedItem?[e.selectedItem]:[]};if(t.type==="selection"){let s=[...new Set(t.keys)];return{...e,keys:s,selectedItem:e.selectedItem&&s.includes(e.selectedItem)?e.selectedItem:s[s.length-1]??null}}if(t.type!=="select")return e;let{key:i,modifiers:r}=t;if(!i)return e.checkboxMode?e:Fs;if(!e.checkboxMode&&!r.shiftKey&&!r.ctrlKey&&!r.metaKey)return{...e,selectedItem:i,keys:[]};let o=e.keys.length?e.keys:e.selectedItem?[e.selectedItem]:[],n=r.shiftKey&&!r.ctrlKey&&!r.metaKey,c=o.includes(i)&&!n,d=c?o.filter(s=>s!==i):[...new Set([...o,i])];return{...e,keys:d,selectedItem:c?e.selectedItem&&d.includes(e.selectedItem)?e.selectedItem:d[d.length-1]??null:i}}function tb(){let[e,t]=Av(Ov,Fs),i=Ho(p=>t({type:"primary",value:p}),[]),r=Ho(p=>t({type:"keys",value:p}),[]),o=Ho(p=>t({type:"mode",value:p}),[]),n=Ho(p=>t({type:"selection",keys:p}),[]),c=Ho((p,x={})=>t({type:"select",key:p,modifiers:x}),[]),d=Ho(()=>t({type:"toggleMode"}),[]),s=Ho(()=>t({type:"exitMode"}),[]),g=Ho(()=>t({type:"clear"}),[]);return{selectedItem:e.selectedItem,multiSelectedKeys:e.keys,multiSelectMode:e.checkboxMode,groupSelectionActive:e.checkboxMode||e.keys.length>1,setSelectedItem:i,setMultiSelectedKeys:r,setMultiSelectMode:o,setSelection:n,selectObject:c,toggleMultiSelect:d,exitMultiSelect:s,clearSelection:g}}import{useCallback as ob,useEffect as Ev,useState as jv}from"react";function nb(e,t){let[i,r]=jv(!1),o=e>0||t>0,n=ob(()=>r(!0),[]),c=ob(()=>r(!1),[]);return Ev(()=>{o&&n()},[o,n]),{hasEdits:i||o,markSessionEdited:n,resetSessionEdits:c}}import{useEffect as ib,useReducer as Lv,useRef as rb}from"react";function ab({enabled:e=!0,modelUrl:t,bindings:i,mergeSources:r,parkedModels:o,scenesRef:n,sceneRevision:c,setBindings:d,setParkedModels:s}){let[g,p]=Lv(h=>h+1,0),x=rb(new WeakMap),b=rb(new WeakMap);ib(()=>{if(!e)return;let h=[t,...o.map(B=>B.url)],M=new Set(h.flatMap(B=>{let y=B?n.current.get(B):void 0;return y?[y]:[]})),S=B=>{B.target&&x.current.delete(B.target),p()};for(let B of M)B.addEventListener("childadded",S),B.addEventListener("childremoved",S);return()=>{for(let B of M)B.removeEventListener("childadded",S),B.removeEventListener("childremoved",S)}},[e,t,o,n,c]),ib(()=>{if(!e)return;let h=B=>{let y=x.current.get(B);return y||(y=new Set(Object.keys(lr(B).nodesById)),x.current.set(B,y)),y},M=(B,y)=>{let u=h(B),v=b.current.get(B)??new Set;b.current.set(B,v);for(let[m,N]of Object.entries(y))N.removed&&v.add(N.modelObjectId??m);for(let m of v)u.has(m)&&v.delete(m);return v.size?new Set([...u,...v]):u},S=t?n.current.get(t):void 0;if(S){let B=M(S,i);d(y=>mn(S,y,r,{},B))}s(B=>{let y=!1,u=B.map(v=>{let m=n.current.get(v.url);if(!m)return v;let N=mn(m,v.bindings,v.mergedModelSources,{},M(m,v.bindings));return N===v.bindings?v:(y=!0,{...v,bindings:N})});return y?u:B})},[e,t,i,r,o,n,c,g,d,s])}import{useEffect as Iv,useMemo as Dv,useReducer as zv}from"react";function sb({modelUrl:e,scenesRef:t,sceneRevision:i,streaming:r=!1}){let o=e?t.current.get(e):void 0,[n,c]=zv(d=>d+1,0);return Iv(()=>{if(!o||r)return;let d=()=>c();return o.addEventListener("childadded",d),o.addEventListener("childremoved",d),()=>{o.removeEventListener("childadded",d),o.removeEventListener("childremoved",d)}},[o,r]),Dv(()=>({materialVariantGroups:o?kd(o):[],objectsWithoutUvs:o&&!r?hr(o):new Set,hierarchy:o&&!r?ic(o):[]}),[o,i,n,r])}import{AlertTriangle as Fv,Box as Hv,History as $v,Trash2 as Uv,Upload as Vv}from"lucide-react";import{useId as lb,useState as _v}from"react";import{Fragment as Ni,jsx as ge,jsxs as _e}from"react/jsx-runtime";function Kv(e){let t=new Date(e);return t.toDateString()===new Date().toDateString()?`today at ${t.toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})}`:t.toLocaleString([],{dateStyle:"medium",timeStyle:"short"})}var Hs=ge(Fv,{size:15,"aria-hidden":"true"});function Yt({variant:e,...t}){return ge("button",{type:"button",className:`bb-dialogButton ${e?`bb-dialogButton--${e}`:""}`,...t})}function db({target:e,onCancel:t,onConfirm:i}){return _e(En,{title:`Reset ${e==="bindings"?"object changes":e==="assets"?"asset placements":"scene settings"}?`,icon:Hs,onCancel:t,footer:_e(Ni,{children:[ge(Yt,{onClick:t,children:"Cancel"}),ge(Yt,{variant:"danger",onClick:i,autoFocus:!0,children:"Reset"})]}),children:[ge("p",{children:e==="bindings"?"This removes your changes to object properties, groups, tags, transforms, materials, actions, saved views, metrics, and metadata.":e==="assets"?"This resets every asset's position, rotation, and scale, and the grid spacing. Which assets are in the scene, their names, visibility, and object edits stay.":"This restores camera, lighting, environment, background, animations, annotations, and every other scene setting to their defaults."}),ge("p",{children:e==="assets"?"You can undo this.":"You can't undo this."})]})}function cb({models:e,savedAt:t,onCancel:i,onConfirm:r}){return _e(En,{title:"Restore last session",icon:ge($v,{size:15,className:"bb-dialogIconNeutral","aria-hidden":"true"}),onCancel:i,footer:_e(Ni,{children:[ge(Yt,{onClick:i,children:"Cancel"}),ge(Yt,{variant:"primary",onClick:r,autoFocus:!0,children:"Restore"})]}),children:[_e("p",{children:["Saved ",Kv(t),", with your bindings and scene settings."]}),ge("ul",{className:"bb-modelList","aria-label":"Saved models",children:e.map((o,n)=>_e("li",{className:"bb-modelRow",children:[ge(Hv,{size:14,className:"bb-modelRowIcon","aria-hidden":"true"}),_e("span",{className:"bb-modelRowText",children:[ge("span",{className:"bb-modelRowName",title:o.name,children:o.name}),o.mergedCount>0?_e("small",{children:[o.mergedCount," merged ",o.mergedCount===1?"model":"models"]}):null]})]},n))})]})}function ub({nodeLabel:e,count:t=1,onCancel:i,onConfirm:r}){let o=t>1;return _e(En,{title:o?`Delete ${e}?`:"Delete this object?",icon:Hs,onCancel:i,footer:_e(Ni,{children:[ge(Yt,{onClick:i,children:"Cancel"}),ge(Yt,{variant:"danger",onClick:r,autoFocus:!0,children:"Delete"})]}),children:[o?null:ge("p",{children:ge("strong",{children:e})}),_e("p",{children:[o?"They leave":"It leaves"," the Outliner and the 3D view for every viewer, rather than being hidden as the Visible checkbox does. You can undo this."]})]})}function pb({destinations:e,onCancel:t,onChoose:i}){let[r,o]=_v(e.find(d=>d.isActive)?.url??e[0]?.url??""),n=e.find(d=>d.url===r),c=lb();return _e(En,{title:"Add model",icon:ge(Vv,{size:15,"aria-hidden":"true"}),onCancel:t,footer:_e(Ni,{children:[ge(Yt,{onClick:t,children:"Cancel"}),ge(Yt,{onClick:()=>i({mode:"separate"}),children:"Add as separate model"}),ge(Yt,{variant:"primary",disabled:!n,title:n?`Merge into ${n.name}`:void 0,onClick:()=>n&&i({mode:"merge",targetUrl:r}),children:"Merge into model"})]}),children:[ge("p",{children:"A separate model stays independent and has its own group in the Outliner. Merging adds its objects to the model you choose."}),ge("label",{htmlFor:c,children:"Merge into"}),ge(et,{id:c,value:r,onChange:d=>o(d.target.value),children:e.map(d=>_e("option",{value:d.url,children:[d.label,": ",d.name,d.isActive?" (active)":""]},d.url))})]})}function bb({options:e,onCancel:t,onRemoveModel:i,onRemoveMerge:r,onRemoveAll:o,permanent:n=!1}){let c=lb();return _e(En,{title:"Remove model",icon:Hs,onCancel:t,footer:_e(Ni,{children:[ge(Yt,{onClick:t,children:"Cancel"}),o?ge(Yt,{variant:"danger","aria-describedby":c,onClick:o,children:"Remove all models"}):null]}),children:[ge("p",{children:"Its bindings, transforms and anything merged into it go with it. The other models stay."}),ge("ul",{className:"bb-modelList","aria-label":"Models",children:e.map(d=>_e("li",{className:"bb-modelRow",children:[_e("span",{className:"bb-modelRowText",children:[ge("span",{className:"bb-modelRowName",title:d.label,children:d.label}),d.kind!=="model"?_e("small",{children:["Merged into ",d.ownerLabel]}):d.name!==d.label?ge("small",{title:d.name,children:d.name}):null]}),d.kind==="model"&&d.isActive?ge("span",{className:"bb-modelRowBadge",children:"Active"}):null,_e("button",{type:"button",className:"bb-removeRowButton","aria-label":`Remove ${d.label}`,onClick:()=>d.kind==="model"?i(d.url):r(d.url),children:[ge(Uv,{size:13,"aria-hidden":"true"}),"Remove"]})]},d.url))}),ge("p",{id:c,children:n?"Removing a model removes it for everyone in this project and deletes its stored file unless another project uses it. You can't undo this.":"Removing all models also clears the session saved in this browser. You can't undo this, so export anything you want to keep first."})]})}import{strToU8 as Gv}from"fflate";function qv(e){return(e.decals??[]).map(t=>t.image).filter(t=>!!t?.trim())}function Wv(e){let t=e.style?.material;return t?Object.values(t).filter(i=>!!i&&typeof i=="object"&&typeof i.path=="string"&&i.path.trim().length>0).map(i=>i.path):[]}async function mb(e){let t=new Set;for(let i of Object.values(e)){for(let r of Wv(i))t.add(r);for(let r of qv(i))t.add(r)}return fb(t)}async function gb(e){let t=new Set,i=e.background?.imageUrl?.trim();return i&&t.add(i),fb(t)}async function fb(e){let t=[],i=[];return await Promise.all(Array.from(e).map(async r=>{let o=Qt(r);if(o)try{let n=await fetch(o);if(!n.ok)throw new Error(String(n.status));t.push({path:r,blob:await n.blob()});return}catch{i.push(r);return}try{let n=await fo(r);n&&t.push({path:r,blob:n})}catch{}})),{assets:t,failedPaths:i}}async function Ai(e,t,i,r,o){if(o.length===0){Zu(e,t,i);return}let n={[e]:Gv(t)};for(let d of o)n[d.path]=new Uint8Array(await d.blob.arrayBuffer());let c=await fr(n);An(new Blob([c],{type:"application/zip"}),r)}async function Hr(e){let t=e.background?.imageUrl?.trim();if(t)try{let i=await fo(t);i&&_t(t,URL.createObjectURL(i))}catch(i){console.warn("[BindingBuilder] Could not rehydrate the background image:",i)}}async function fn(e){return await Promise.all(Object.entries(e).map(async([t,i])=>{for(let o of i.decals??[])if(o.image)try{let n=await fo(o.image);n&&_t(o.image,URL.createObjectURL(n))}catch(n){console.warn(`[BindingBuilder] Could not rehydrate a decal image on "${t}":`,n)}let r=i.style?.material;if(r)for(let o of Md){let c=r[o]?.path;if(c)try{let d=await fo(c);if(!d){console.warn(`[BindingBuilder] No stored texture found for "${t}"'s ${o} ("${c}"). If this is meant to be an uploaded file rather than a hosted URL, it was uploaded before texture autosave existed (or this browser's storage was cleared) \u2014 re-upload it once so it's stored for future restores.`);continue}let s=URL.createObjectURL(d);_t(c,s)}catch(d){console.warn(`[BindingBuilder] Could not rehydrate "${t}"'s ${o}:`,d)}}})),e}async function Oi(e){if(!e)return;let t={};for(let i of e.definition.groups)for(let r of i.options)for(let[o,n]of(r.appearance??[]).entries())if(n.material){let c=JSON.stringify([i.id,r.id,o]);t[c]={id:c,modelObjectId:c,style:{material:n.material}}}await fn(t)}async function hb(e){let t=new Set,i=new WeakSet;function r(o,n=0){if(!(!o||typeof o!="object"||i.has(o)||n>64)){i.add(o);for(let[c,d]of Object.entries(o))c!=="metadata"&&(c==="path"&&typeof d=="string"&&d?t.add(d):r(d,n+1))}}return r(e),await Promise.all([...t].map(async o=>{let n=await fo(o);n&&_t(o,URL.createObjectURL(n))})),e}function xb({bindings:e,setBindings:t,sceneConfig:i,setSceneConfig:r,nodeKeys:o,sceneConfigInputRef:n,setIsExporting:c,setStatusMessage:d,setStatusTone:s}){let g=y=>x("bindings",()=>mb(e),u=>y==="json"?Ai("objectBindings.json",ki(e),"application/json","objectBindings.zip",u):Ai("objectBindings.ts",Er(e),"text/typescript","objectBindings-ts.zip",u)),p=y=>x("scene config",()=>gb(i),u=>y==="json"?Ai("sceneConfig.json",jr(i),"application/json","sceneConfig.zip",u):Ai("sceneConfig.ts",Lr(i),"text/typescript","sceneConfig-ts.zip",u)),x=async(y,u,v)=>{c(!0);try{let{assets:m,failedPaths:N}=await u();await v(m),N.length>0?(d(`Exported, but ${N.length} uploaded image${N.length===1?"":"s"} couldn't be bundled: ${N.join(", ")}.`),s("error")):m.length>0&&(d(`Exported with ${m.length} uploaded image${m.length===1?"":"s"} bundled into the zip.`),s("success"))}catch(m){let N=m instanceof Error?m.message:"Unknown export error.";d(`Failed to export ${y}: ${N}`),s("error")}finally{c(!1)}},b=async y=>{if(!o.length){d("Load a model before importing bindings."),s("error");return}let u;try{u=JSON.parse(await y.text())}catch{d(`${y.name} is not valid JSON.`),s("error");return}if(u===null||typeof u!="object"||Array.isArray(u)){d("Expected a JSON object mapping object IDs to bindings."),s("error");return}let v=new Map;for(let D of Object.values(u))if(D!==null&&typeof D=="object"&&typeof D.id=="string"&&typeof D.type=="string"&&typeof D.modelObjectId=="string"){let k=D;v.set(k.modelObjectId,k)}if(v.size===0){d(`${y.name} doesn't look like an exported bindings file.`),s("error");return}let m={...e},N={},A=0;for(let D of Object.keys(m)){let k=v.get(D);k&&(m[D]=k,N[D]=k,A++)}if(A===0){d(`None of the object IDs in ${y.name} match this model \u2014 nothing imported.`),s("error");return}let K=await fn(N);Object.assign(m,K),t(m);let T=v.size-A;d(T>0?`Imported ${A} binding${A===1?"":"s"} from ${y.name} (${T} skipped \u2014 not in this model).`:`Imported ${A} binding${A===1?"":"s"} from ${y.name}.`),s("success")},h=async y=>{let u=y.target.files?.[0];u&&(await b(u),y.target.value="")},M=()=>{n.current?.click()},S=async y=>{let u;try{u=JSON.parse(await y.text())}catch{d(`${y.name} is not valid JSON.`),s("error");return}if(u===null||typeof u!="object"||Array.isArray(u)){d("Expected a JSON object with scene config sections."),s("error");return}let v=["model","camera","lighting","wireframe","shadows","environment","background","groundShadows","postProcessing","animations","annotations","cinematic","styleRules","section","measurements","selectionSets","product"],m=u;if(m.product!==void 0)try{m.product=pr(m.product)}catch(A){d(A instanceof Error?A.message:String(A)),s("error");return}if(m.section!==void 0)try{m.section=cr(i.section,m.section)}catch(A){d(A instanceof Error?A.message:String(A)),s("error");return}if(m.selectionSets!==void 0)try{m.selectionSets=Nn(m.selectionSets)}catch(A){d(A instanceof Error?A.message:String(A)),s("error");return}if(m.measurements!==void 0)try{m.measurements=ur(m.measurements)}catch(A){d(A instanceof Error?A.message:String(A)),s("error");return}let N=v.filter(A=>m[A]!==void 0);if(N.length===0){d(`${y.name} doesn't look like an exported scene config file.`),s("error");return}await Oi(m.product),N.includes("background")&&m.background&&await Hr({background:m.background}),r(A=>{let K={...A};for(let T of N)K[T]=T==="measurements"||T==="section"||T==="product"?m[T]:gi(A[T],m[T]);return K}),d(`Imported ${N.length} section${N.length===1?"":"s"} from ${y.name}.`),s("success")};return{handleExportBindings:g,handleExportSceneConfig:p,importBindingsFile:b,handleImportBindingsChange:h,openSceneConfigImportPicker:M,importSceneConfigFile:S,handleImportSceneConfigChange:async y=>{let u=y.target.files?.[0];u&&(await S(u),y.target.value="")}}}var $s={pbr:["texture","baseColor","metalness","metalnessMap","specularIntensity","specularIntensityMap","specularColor","specularColorMap","reflectivity"],roughness:["roughness","roughnessMap"],emission:["emissive","emissiveIntensity","emissiveMap"],opacity:["opacity","alphaMap","alphaTest","alphaHash","dithering","blendingMode"],normalBump:["normalMap","normalScale","flipNormalY","bumpMap","bumpScale"],displacement:["displacementMap","displacementScale","displacementBias"],ao:["aoMap","aoMapIntensity"],clearcoat:["clearcoat","clearcoatMap","clearcoatRoughness","clearcoatRoughnessMap","clearcoatNormalMap","clearcoatNormalScale","flipClearcoatNormalY"],sheen:["sheen","sheenColor","sheenColorMap","sheenRoughness","sheenRoughnessMap"],anisotropy:["anisotropy","anisotropyRotation","anisotropyMap"],transmission:["transmission","transmissionMap","thickness","thicknessMap","attenuationColor","attenuationDistance"],faces:["side"]},vb=Object.keys($s);function yb(e){if(e==null)return!1;if(typeof e=="string")return e.trim().length>0;if(typeof e=="number")return Number.isFinite(e);if(typeof e=="boolean")return e;if(typeof e=="object"&&"path"in e){let t=e.path;return typeof t=="string"&&t.trim().length>0}return!1}function Us(e){if(e)return Object.values(e).some(yb)?e:void 0}function It(e,t){return e?$s[t].some(i=>yb(e[i])):!1}function Vs(e){return{pbr:It(e,"pbr"),roughness:It(e,"roughness"),emission:It(e,"emission"),opacity:It(e,"opacity"),normalBump:It(e,"normalBump"),displacement:It(e,"displacement"),ao:It(e,"ao"),clearcoat:It(e,"clearcoat"),sheen:It(e,"sheen"),anisotropy:It(e,"anisotropy"),transmission:It(e,"transmission"),faces:It(e,"faces")}}function _s(e,t){if(t)return{...e,style:{...e.style,material:t}};if(!e.style)return e;let{material:i,...r}=e.style;return{...e,style:Object.keys(r).length>0?r:void 0}}function wb(e,t){if(!e)return;let i={...e};for(let r of $s[t])delete i[r];return i}import{ChevronDown as Yv,ChevronUp as Jv}from"lucide-react";import{jsx as hn,jsxs as Sb}from"react/jsx-runtime";function kb({panel:e,tabs:t,tab:i,onTabChange:r,hasModel:o,onPointerDownCapture:n,children:c}){let d=e.open&&o;return Sb("div",{className:`bb-dock ${d?"bb-dock--open":""}`,onPointerDownCapture:n,children:[d?hn(Si,{orientation:"horizontal",label:"Resize timeline",onPointerDown:e.startResize,onKeyDown:e.onResizeKey}):null,Sb("div",{className:"bb-tabs bb-dockBar",role:"tablist","aria-label":"Animation",children:[t.map(({id:s,label:g})=>hn("button",{type:"button",role:"tab",disabled:!o,"aria-selected":e.open&&i===s,className:`bb-tab ${e.open&&i===s?"bb-tab--active":""}`,onClick:()=>{e.open&&i===s?e.setOpen(!1):(r(s),e.setOpen(!0))},children:g},s)),hn("span",{className:"bb-topBarSpacer"}),hn("button",{type:"button",className:"bb-toolButton bb-toolButton--small",disabled:!o,"aria-label":e.open?"Collapse timeline":"Expand timeline",onClick:()=>e.setOpen(!e.open),children:e.open?hn(Yv,{size:14}):hn(Jv,{size:14})})]}),d?hn("div",{className:"bb-dockBody",style:{height:e.size},children:c}):null]})}import{Fragment as rt,jsx as R,jsxs as ce}from"react/jsx-runtime";var by=Do(()=>import("./AnnotationsTab-NEJIXCOM.mjs")),my=Do(()=>import("./AnimationsTab-IKAAKT3P.mjs")),gy=Do(()=>import("./SequencesTab-LTMJTB76.mjs")),fy=Do(()=>import("./CinematicTab-TIQXCPFE.mjs")),hy=Do(()=>import("./ConfigureTab-NYRMOFW4.mjs")),Cb="/room.glb";function Gs(){return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function qs(e){return`Couldn't reload ${e} from your last session. It's still saved in this browser.`}function xy({label:e,values:t,onChange:i}){let r=t.length>0&&t.every(Boolean),o=!r&&t.some(Boolean);return ce("label",{className:"bb-groupFlag",children:[R("input",{type:"checkbox",ref:n=>{n&&(n.indeterminate=o)},checked:r,onChange:n=>i(n.target.checked)}),e]})}var vy=[{id:"outliner",label:"Outliner"},{id:"assets",label:"Assets"},{id:"annotations",label:"Annotations"},{id:"measure",label:"Measure"}],yy=[{id:"sequences",label:"Sequences"},{id:"clips",label:"Clips"},{id:"cinematic",label:"Cinematic"}],Mb=[{id:"general",label:"General",group:!0},{id:"material",label:"Material",group:!0},{id:"decals",label:"Decals",group:!1},{id:"actions",label:"Actions",group:!1},{id:"data",label:"Data",group:!0}],Ws=new Zv,wy=new Xv(new Ei(0,1,0),0),Sy=new Ei,Pb=new WeakMap;function ky(e){let t=Pb.get(e);return t===void 0&&(t=Td(e),Pb.set(e,t)),t}function Cy(e){for(let t=e;t;t=t.parent)if(!t.visible)return!1;return!0}var Bb=[{value:"pbr",label:"PBR"},{value:"matcap",label:"Matcap"},{value:"uv-checker",label:"UV checker"}],Tb={bindings:"object",scene:"scene",assets:"asset"},My=ce(rt,{children:[R("kbd",{children:"G"})," Move ",R("kbd",{children:"R"})," Rotate ",R("kbd",{children:"T"})," Scale ",R("kbd",{children:"F"})," Frame"," ",R("kbd",{children:"?"})," Shortcuts"]});function Rb(e,t=!1){let i=e;return i?.tagName?i.isContentEditable||i.tagName==="TEXTAREA"||t&&(i.tagName==="SELECT"||i.closest(".ri-select"))?!0:i.tagName!=="INPUT"?!1:!["range","checkbox","radio","button","file","color"].includes(i.type):!1}function Py({topBarStart:e,configurePublish:t,licenseKey:i,licenseValidationUrl:r,onLicenseStatusChange:o,arHandoff:n=!0,mobileHandoffUrl:c,dracoDecoderPath:d,ktx2TranscoderPath:s,meshopt:g,project:p,onProjectChange:x,projectChangeDebounceMs:b=350,onModelUpload:h,onTextureUpload:M,onThumbnailCapture:S,hasThumbnail:B=!1,onEditLeaseChange:y,allowModelChange:u=!0,hideLicenseCheckingOverlay:v=!1}){let m=ie(null),N=ie(null),A=ie(null),K=ie(null),T=ie(null),[D]=_(()=>p?_a(p):null),[k,Q]=_(D?.url??null),[G,ee]=_(()=>p?p.models.filter(a=>a!==D).map(Ga):[]),[le,P]=_(()=>p?p.models.map(a=>a.url):[]),[L,Me]=_(D?.name??""),[Xe,Z]=_(D),Le=He(()=>p&&le.length>1&&Xe?.tilesetUrl?{...Xe,tilesetUrl:null}:Xe,[p,le.length,Xe]),Ze=ie(p?qa(p):new Map),{selectedItem:O,setSelectedItem:z,multiSelectMode:U,setMultiSelectMode:xe,multiSelectedKeys:be,setMultiSelectedKeys:xt,groupSelectionActive:Te,selectObject:ro,setSelection:Jn,toggleMultiSelect:Jt,exitMultiSelect:ji,clearSelection:Ys}=tb(),Js=ie({mode:!1,keys:[]}),Li=ie({shiftKey:!1,ctrlKey:!1,metaKey:!1}),[Xn,Nb]=_(null);Js.current={mode:Te,keys:be};let te=Wp(D?.objectBindings??{}),q=te.value,$o=te.setValue,Ii=ie("free");eb({bindings:q,multiSelectMode:Te,selectedItem:O,multiSelectedKeys:be,setSelectedItem:z,setMultiSelectedKeys:xt});let De=te.mergeSources,ko=te.setMergeSourcesUntracked;je(()=>{D?.mergeModels?.length&&ko(zn(D))},[D,ko]);let[Re,ao]=_(!1),[Di,Zn]=_(null),Ab=He(()=>Di?{target:Di}:null,[Di]);je(()=>{Zn(null)},[k]),je(()=>{xe(!1),xt([])},[k]);let[zi,Co]=_(null);je(()=>Co(null),[O,k]),je(()=>{ra(null),sa(null)},[k]);let[Ob,Uo]=_(null),[Xs,Eb]=_(!1),[$r,W]=_(""),[Ur,X]=_("default"),[jb,Zs]=_(null),Lb=Y(()=>Zs(null),[]),[Qs,Fi]=_("{}"),[el,Hi]=_("{}"),[Ib,$i]=_(null),[Db,Ui]=_(null),[zb,Qn]=_(!1),Mo=Or("left",{size:296,min:220,max:480,edge:"right"}),so=Or("inspector",{size:320,min:300,max:560,edge:"left"}),Vr=Or("dock",{size:300,min:160,max:640,edge:"top",open:!1}),[Dt,Fb]=_("outliner"),[Vi,tl]=_("sequences"),[ol,nl]=_("general"),[il,_r]=_(!1),[Kr,Hb]=_(!0),[$b,Gr]=_(!1),[Ub,qr]=_(!1),[ei,vt]=_("bindings"),_i=Y(a=>{Fb(a),vt(a==="assets"?"assets":a==="outliner"?"bindings":"scene")},[]),[lo,rl]=_({identity:!0,basics:!0,material:!0,decals:!0,actions:!0,camera:!1,transform:!0,metrics:!0,metadata:!0}),[Vb,_b]=_({pbr:!0,roughness:!0,emission:!1,opacity:!0,normalBump:!1,displacement:!1,ao:!1,clearcoat:!1,sheen:!1,anisotropy:!1,transmission:!1,faces:!1}),co=a=>rl(l=>({...l,[a]:!l[a]})),Kb=a=>_b(l=>({...l,[a]:!l[a]})),[Ki,al]=_(null),[Po,Wr]=_(!1),[yt,xn]=_("object"),[Vo,Yr]=_("model"),[sl,ll]=_(null),[dl,cl]=_(!1),[ul,Gb]=_(null),pl=Mo.setOpen,bl=Y(()=>{pl(!0),_i("measure"),cl(!0)},[pl,_i]),[qb,Wb]=_("metalness"),[Yb,Jr]=_(Vs()),ml=ie(null),[gl,Jb]=_(!1),[Xr,Xb]=_(!0),[Zr,Zb]=_(!0),[Qb,fl]=_(!1),[ti,hl]=_(null),[_o,Qr]=_(null),[em,ea]=_(!1),Gi=ie(null),qi=ie({modelUrl:k,modelName:L,modelOrder:le,parkedModels:G});qi.current={modelUrl:k,modelName:L,modelOrder:le,parkedModels:G};let[tm,vn]=_(!1),[Bo,ta]=_(null),[uo,oi]=_("select"),om=uo==="move"||uo==="rotate",nm=uo==="scale",[xl,im]=_("world"),Tt=ie({}),Ae=fi(p&&D?wr(p.sceneConfig,D):Ao),Ke=fi(p?Ka(p):Zo),[vl,yn]=_([]),ct=He(()=>({...Ke.value,placements:{...Object.fromEntries(vl.map(a=>[a,{deleted:!0}])),...Ke.value.placements}}),[Ke.value,vl]),[wn,Sn]=_(!1),yl=ie(null),oe=Ae.value,zt=Ae.setValue,rm=Y(a=>{let l=Nn(a);Ae.setValueAsStep(f=>({...f,selectionSets:l}))},[Ae.setValueAsStep]),Wi=Ae.setValueUntracked,oa=Y(a=>{let l=tt(oe,a.modelSettings);a.sceneHistory?Ae.restoreSnapshot({...a.sceneHistory,present:l}):Ae.reset(l)},[oe,Ae.restoreSnapshot,Ae.reset]),{hasEdits:am,markSessionEdited:ut,resetSessionEdits:na}=nb(te.edits,Ae.edits+Ke.edits),[Ko,wl]=_(!1),[sm,lm]=_(.5),[ia,dm]=_(!0),[kn,ra]=_(null),Cn=kn??{bindings:te.baseline,sceneConfig:Ae.baseline},[aa,cm]=_("modelObjectId"),[Yi,sa]=_(null),ni=He(()=>Ko?Zd({objectBindings:Cn.bindings,sceneConfig:Cn.sceneConfig},{objectBindings:q,sceneConfig:oe},{matchBy:aa}):null,[Ko,Cn.bindings,Cn.sceneConfig,q,oe,aa]),Sl=He(()=>ni&&ia?{before:za(ni,"before",Yi),after:za(ni,"after",Yi)}:null,[ni,Yi,ia]),[kl,la]=_("orbit"),[um,Cl]=_(!1),da=ie(void 0),ca=Y(()=>{Cl(!0),clearTimeout(da.current),da.current=setTimeout(()=>Cl(!1),5e3)},[]);je(()=>()=>clearTimeout(da.current),[]),je(()=>{k&&!Re&&ca()},[k,Re,ca]);let qe=kl==="pointerLock",[Ml,pm]=_(null),Pl=ie(null),bm=Ml?.objectKey===O&&Ml?.textureKey==="texture",[mm,Mn]=_(null),[gm,ua]=_(null),Go=Fd(i,r,o),qo=Id(Go.tier);Ii.current=qo;let Bl=Dd.models[qo],fm=He(()=>({isInsideEditor:!0,activeTab:yt,activeSubTab:Vo,tier:qo,setActiveTab:xn,setActiveSubTab:Yr,measurementPanelTarget:sl,setMeasurementPanelTarget:ll,measurementsPanelOpen:dl,setMeasurementsPanelOpen:cl,openMeasurementsPanel:bl,xrToolsTarget:ul,annotating:Dt==="annotations"}),[yt,Vo,qo,sl,dl,bl,ul,Dt]),Qe=ie(null),Pn=ie(0),Rt=ie(0),Tl=ie(p?`${p.id}:${p.revision}`:null),Rl=ie(null),By=ie(!1),Ji=ie(!1),Xi=ie(p?Fn(p):null),pa=ie(!1),Zi=ie(new Set),Qi=ie(new Map),er=ie(void 0),To=ie(0),hm=Od(Ob,To.current===100),$e=ie(null),at=ie(p?{requestId:0,modelName:D.name??"model",modelUrl:D.url,storedBindings:D.objectBindings,streaming:!!D.tilesetUrl}:null),We=ie(D?{model:{kind:"url",url:D.url,name:D.name??"model"}}:null),tr=ie(new Set),po=ie(new Map);Jp(te.snapshot,G,{modelUrl:k,modelSourceRef:We,uploadedFilesRef:po});let ii=ie(null),xm=ie(!1),bo=ie(null),Nt=ie(new Map),[ba,Nl]=_(0),Ro=He(()=>new Map(le.map(a=>{let l=a===k?We.current?.model:G.find(f=>f.url===a)?.sessionModel;return[a,l?eo(l):`url:${a}`]})),[le,k,G]),ri=a=>ct.placements[Ro.get(a)??`url:${a}`]??{},ye=He(()=>le.map((a,l)=>({id:Ro.get(a)??`url:${a}`,url:a,name:ri(a).label??(a===k?L:G.find(f=>f.url===a)?.name)??`Asset ${l+1}`,placement:ri(a),ready:Nt.current.has(a)})).filter(a=>!a.placement.deleted),[le,k,L,G,ct,Ro,ba]),Al=Ot(qo,"models",ye.length),mo=He(()=>{let a=Up(ye.map(l=>l.name));return new Map(ye.map((l,f)=>[l.url,a[f]]))},[ye]),[ma,vm]=_(!1),[Ol,El]=_(null),[ym,jl]=_(null),wm=Y(()=>{let a=k?Nt.current.get(k):void 0;!a||!k||El({url:k,report:Bd(a,{source:{...Pd(a),name:L},scope:Le?.tilesetUrl?"resident-tiles":"asset"})})},[k,L,Le?.tilesetUrl]);je(()=>{jl(null)},[k,ma]);let{materialVariantGroups:Ll,objectsWithoutUvs:Il,hierarchy:Sm}=sb({modelUrl:k,scenesRef:Nt,sceneRevision:ba,streaming:!!Le?.tilesetUrl});je(()=>{let a=new Set(ye.map(l=>l.url));for(let l of Nt.current.keys())a.has(l)||Nt.current.delete(l)},[ye]),ab({enabled:!Le?.tilesetUrl,modelUrl:k,bindings:q,mergeSources:De,parkedModels:G,scenesRef:Nt,sceneRevision:ba,setBindings:te.setValueUntracked,setParkedModels:ee});let Xt=ie(null),Dl=ie(null);je(()=>an,[]);let km=He(()=>({selectedLabel:O?q[O]?.label||O:null,get:a=>{let l=Xt.current,f=a==="model"?l?.raw.scene:O?l?.raw.nodes[O]:null;if(!f)return null;let w=new Ks().setFromObject(f);if(w.isEmpty())return null;let C=w.getSize(new Ei).multiplyScalar(.02);w.min.add(C),w.max.sub(C);let E=H=>H.toArray().map(F=>Number(F.toFixed(3)));return[E(w.min),E(w.max)]}}),[O,q]),ga=ie(null),Wo=ie(null),zl=Y(()=>{Wo.current=null;let a=ga.current,l=Xt.current,f=l?.raw.scene,w=l?.raw.controls.camera,C=A.current?.querySelector("canvas");if(!a?.overCanvas||!w||!C){Mr(null);return}let E=C.getBoundingClientRect();Ws.setFromCamera(new Qv((a.x-E.left)/E.width*2-1,-((a.y-E.top)/E.height)*2+1),w);let F=(f&&!ky(f)?Ws.intersectObject(f,!0).find(V=>Cy(V.object)):void 0)?.point??Ws.ray.intersectPlane(wy,Sy);Mr(F?F.toArray():null)},[]),Cm=Y(a=>{ga.current={x:a.clientX,y:a.clientY,overCanvas:a.target instanceof HTMLCanvasElement},Wo.current??(Wo.current=requestAnimationFrame(zl))},[zl]),fa=Y(()=>{Wo.current!==null&&cancelAnimationFrame(Wo.current),Wo.current=null,ga.current=null,Mr(null)},[]);je(()=>fa,[fa]);let[Mm,Pm]=_(null),[Fl,Bm]=_({}),Tm=He(()=>{if(!Te||be.length===0||!Xt.current)return null;let l=be.filter(f=>q[f]&&!q[f].removed).map(f=>Fl[f]).filter(f=>!!f);return l.length>0?l:null},[Te,be,Fl,q]),{cameraState:Ne,resetView:Hl,focusObject:Bn,fitScene:$l,setCameraState:or,handleCameraChange:Ul,handleViewerReady:Rm}=dd(),{markThumbnailOutdated:Nm,noteThumbnailActivity:Vl}=Qp({onCapture:S,hasThumbnail:B,viewerRef:Xt,isModelLoading:()=>!k||!!at.current}),Am=Y((...a)=>{Vl(),Ul(...a)},[Ul,Vl]),_l=Y(a=>{qe||or({position:a.position,target:a.target,fov:a.fov??Ne?.fov??null,zoom:a.zoom??Ne?.zoom??1,azimuthAngle:a.azimuthAngle,polarAngle:a.polarAngle},!0)},[qe,or,Ne]),Ft=tc(),Om=He(()=>ye.map(a=>a.url),[ye]),Ht=$c(Om),nr=Vc({modelUrl:k,sceneConfig:oe,setSceneConfig:zt,setSceneConfigUntracked:Wi,parkedModels:G,setParkedModels:ee,animations:Ht,markSessionEdited:ut}),Kl=yt==="configure"&&!Po&&Ki&&oe.product,Em=He(()=>Kl&&oe.product?{...oe,product:{...oe.product,selections:Ki}}:oe,[Kl,oe,Ki]),jm=Y(a=>zt(l=>({...a,product:l.product})),[zt]);je(()=>{yt!=="configure"&&al(null)},[yt]),je(()=>{if(!Po)return;let a=l=>{l.key==="Escape"&&Wr(!1)};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[Po]);let Pe=O?q[O]??null:null,ha=Pe?.style?.material,Gl=!Il.has(Pe?.modelObjectId??O??""),Lm=He(()=>{if(!(ye.length<2))return ye.map(a=>({url:a.url,label:mo.get(a.url)??a.name,bindings:a.url===k?q:G.find(l=>l.url===a.url)?.bindings??{},isActive:a.url===k}))},[ye,mo,k,q,G]),ai=He(()=>{let a=[];return ye.forEach((l,f)=>{let w=l.url,C=w===k,E=C?void 0:G.find(V=>V.url===w),H=mo.get(w)||l.name||`Asset ${f+1}`;a.push({kind:"model",url:w,label:H,name:C?L:E?.name??"Untitled model",isActive:C}),(C?De:E?.mergedModelSources??[]).forEach(V=>{a.push({kind:"merge",url:V.url,label:"Merged nodes",name:io(V.namePrefix),ownerLabel:H})})}),p&&ye.length<2?a.filter(l=>l.kind!=="model"):a},[p,ye,k,L,G,De]),xa=He(()=>De.map(a=>({url:a.url,namePrefix:a.namePrefix})),[De]),Im=He(()=>(p?le.length<2:le.length<1)?void 0:le.map((l,f)=>{let w=ct.placements[Ro.get(l)??`url:${l}`]??{},C={transform:w,visible:w.visible!==!1&&!w.deleted,label:w.label};if(l===k)return{url:l,label:mo.get(l)??C.label??(L||`Model ${f+1}`),transform:C.transform,visible:C.visible,objectBindings:q,originalNodePoses:Tt.current,mergeModels:xa};let H=G.find(F=>F.url===l);return{url:l,label:mo.get(l)??C.label??(H?.name||`Model ${f+1}`),transform:C.transform,visible:C.visible,objectBindings:H?.bindings??{},originalNodePoses:H?.originalTransforms,sceneConfig:tt(oe,H?.modelSettings),mergeModels:(H?.mergedModelSources??[]).map(F=>({url:F.url,namePrefix:F.namePrefix}))}}).filter(l=>!ct.placements[Ro.get(l.url)??`url:${l.url}`]?.deleted),[p,le,k,L,q,G,xa,oe,ct,Ro,mo]);je(()=>{let a=A.current;if(a)return a.style.setProperty("--bb-canvas-hint-top",Ko?"48px":"12px"),()=>{a.style.removeProperty("--bb-canvas-hint-top")}},[Ko]);let No=Pe?.cameraState,Dm=Ne?{position:ds(Ne.position),target:ds(Ne.target)}:null,zm=Y(a=>{vt("scene"),zt(l=>{let f=l.annotations.map(C=>C.id).join(","),w=a.map(C=>C.id).join(",");return f===w?l:a.length>l.annotations.length&&!Ot(Ii.current,"annotations",l.annotations.length)?(W(`More annotations require the ${Ia[en("annotations",l.annotations.length)]} plan or higher.`),X("error"),l):{...l,annotations:a}})},[]),Fm=Y(a=>{Mn(a?{annotation:a}:null)},[]);je(()=>{if(!Pe){Fi("{}"),Hi("{}"),$i(null),Ui(null);return}Fi(ls(Pe.metrics)),Hi(ls(Pe.metadata)),$i(null),Ui(null)},[Pe]),je(()=>{let a=Vs(ha);if(ml.current!==O){ml.current=O,Jr(a);return}Jr(l=>{let f=!1,w={...l};for(let C of vb)a[C]&&!l[C]&&(w[C]=!0,f=!0);return f?w:l})},[O,ha]),je(()=>()=>{Qe.current?.cleanup(),$e.current&&clearTimeout($e.current)},[]);let ir=Y((a,l)=>{let f=ui(a);if(l){let w=new Map(Object.values(l).map(C=>[C.modelObjectId,C]));for(let C of a){let E=w.get(C);E&&(f[C]=E)}}return f},[]);je(()=>{if(!p)return;let a=`${p.id}:${p.revision}`;if(Tl.current===a)return;Tl.current=a,Ze.current=qa(p);let l=p.models.find(ne=>ne.url===k),f=l&&!p.composition.placements[rn(l.url)]?.deleted?l:_a(p),w=wr(p.sceneConfig,f),C=k!==f.url||Xe?.tilesetUrl!==f.tilesetUrl||Xe?.assetVersion!==f.assetVersion,E=Fn(p);if(!C&&Zi.current.delete(E)){Xi.current=E;return}Zi.current.clear();let H=!Sr(q,f.objectBindings),F=!Sr(oe,w);Z(f),Me(f.name??"model");let V=f.objectBindings;if(H){let ne=Rl.current;V=ne?ir(ne,f.objectBindings):f.objectBindings,te.reset(V)}else V=q;F&&Ae.reset(w),ee(ne=>p.models.filter(Be=>Be.url!==f.url).map(Be=>{let wt=ne.find($t=>$t.url===Be.url);if(!wt)return Ga(Be);let Ce=JSON.stringify(wt.mergedModelSources.map($t=>$t.url))===JSON.stringify((Be.mergeModels??[]).map($t=>$t.url));return{...wt,name:Be.name??wt.name,bindings:Be.objectBindings,modelSettings:Be.modelSettings,mergedModelSources:Ce?wt.mergedModelSources:zn(Be),bindingHistory:Ce?wt.bindingHistory:void 0}})),P(p.models.map(ne=>ne.url));let ae=(f.mergeModels??[]).map(ne=>ne.url);if(JSON.stringify(De.map(ne=>ne.url))!==JSON.stringify(ae)&&(ko(zn(f)),te.clearHistory()),Sr(Ke.value,p.composition)||Ke.reset(Ka(p)),C){Ft.clearAnimations();let ne=++Rt.current;at.current={requestId:ne,modelName:f.name??"model",modelUrl:f.url,storedBindings:f.objectBindings,streaming:!!f.tilesetUrl},We.current={model:{kind:"url",url:f.url,name:f.name??"model"}},bo.current=null,z(null),ao(!0),Q(f.url)}Xi.current=Fn({models:p.models.map(ne=>ne===f?{...ne,objectBindings:V}:ne),composition:p.composition,sceneConfig:p.sceneConfig})},[Xe,q,ir,Ke,De,p,k,oe,te,Ae,ko,Ft.clearAnimations]);let va=ie(x);va.current=x;let ql=ie(M);ql.current=M,je(()=>{if(!p||!va.current||!k||at.current)return;let a=()=>Cc({project:p,modelUrl:k,modelName:L,bindings:q,sceneConfig:oe,mergedModelSources:De,parkedModels:G,modelOrder:le,composition:ct,sources:Ze.current});Ji.current&&(Ji.current=!1,Xi.current=Fn({...a(),composition:p.composition,sceneConfig:p.sceneConfig}));let l=window.setTimeout(()=>{if(pa.current)return;let f=a(),w=Fn(f);if(w===Xi.current||Zi.current.has(w))return;let C=ql.current,E=C?nn(f.models).size+nn(f.sceneConfig).size:0;if(C&&E>0){pa.current=!0;let H=nn(f.sceneConfig,nn(f.models));Promise.all([...H].map(async F=>{if(!Qi.current.has(F))try{Qi.current.set(F,await C(await Pc(F),F))}catch(V){W(V instanceof Error?V.message:"Could not save an image."),X("error"),Qi.current.set(F,"")}})).then(()=>{pa.current=!1;let F=V=>yr(V,Qi.current);te.setValueUntracked(F),Ae.setValueUntracked(F),ee(V=>V.map(ae=>({...ae,bindings:F(ae.bindings),modelSettings:F(ae.modelSettings)})))});return}Zi.current.add(w),va.current?.(f,"local"),Nm()},b);return()=>window.clearTimeout(l)},[q,ct,De,L,le,k,G,p,b,oe]);let Yo=ei==="assets"?Ke:ei==="scene"?Ae:te;je(()=>{let a=l=>{l.key.toLowerCase()!=="z"||!(l.metaKey||l.ctrlKey)||Rb(l.target)||(l.preventDefault(),l.shiftKey?Yo.redo():Yo.undo())};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[Yo]);let rr=!p&&u,{handleTextureUpload:Hm}=Xp({composition:ct,autosaveEnabled:rr,hasEdits:am,modelUrl:k,bindings:q,sceneConfig:oe,parkedModels:G,mergedModelSources:De,modelOrder:le,onTextureUpload:M,modelSourceRef:We,pendingLoadRef:at,storedModelKeysRef:tr,uploadedFilesRef:po,pendingAutosaveRef:ii,autosaveFailureShownRef:xm,setStatusMessage:W,setStatusTone:X});je(()=>{Re||Ur==="default"||Zs({id:Date.now(),text:$r,tone:Ur})},[$r,Ur,Re]);let Zt=He(()=>Object.keys(q),[q]),$m=He(()=>!O||!Pe?null:Pe.id.trim()?Object.entries(q).some(([f,w])=>f!==O&&w.id===Pe.id)?"Another binding already uses this ID.":null:"ID is required.",[q,O,Pe]),At=(a,l)=>{$o(f=>{let w=Js.current,C=w.mode&&w.keys.includes(a)?w.keys.filter(H=>f[H]):[a];if(C.length<=1)return{...f,[a]:l(f[a],a)};let E={...f};for(let H of C){let F=f[H];E[H]={...l(F,H),id:F.id,modelObjectId:F.modelObjectId}}return E})},ya=(a,l)=>{At(a,f=>{let w=Us(l(f.style?.material));return _s(f,w)})},Um=(a,l,f)=>{ya(a,w=>({...w,[l]:f?{path:f}:void 0}))},Vm=(a,l)=>{Jr(f=>({...f,[a]:l})),!l&&O&&At(O,f=>{let w=Us(wb(f.style?.material,a));return _s(f,w)})},wa=Y((a,l,f)=>{let{bindings:w,originalTransforms:C,nodeNames:E}=Ri(a,f);Tt.current=C,te.reset(mn(a,f??{},De,w)),z(E[0]??null),f||Wi(F=>({...F,annotations:[]})),W(`Generated ${E.length} bindings from ${l}.`),X("success"),$e.current&&clearTimeout($e.current);let H=setTimeout(()=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{$e.current===H&&(To.current=100,Uo(100),$e.current=setTimeout(()=>{$e.current=null,ao(!1),Uo(null)},400))})})},0);$e.current=H},[te,Wi,De]),Sa=(a,l,f,w)=>{ii.current?.();let C=++Rt.current;na(),Ke.reset(Zo),yn([]),p||Ae.reset(a!==k?tt(oe):oe),a!==k&&Ft.clearAnimations(),G.forEach(F=>F.resolved?.cleanup()),ee([]),P([a]),ko([]),ao(!0),Uo(null),To.current=0,$e.current&&(clearTimeout($e.current),$e.current=null),er.current=f;let E=f?f/1048576:0;W(E>=100?`Reading the file. At ${Math.round(E)} MB, this can take a while.`:"Reading the file and generating bindings."),X("default"),Me(l),Z(w??{url:a,name:l}),Mn(null);let H=bo.current;if(a===k&&H?.url===a){at.current=null,wa(H.scene,l);return}at.current={requestId:C,modelName:l,modelUrl:a,streaming:!!w?.tilesetUrl},Q(a),te.reset({}),z(null)},_m=Y(a=>{k&&Nt.current.get(k)!==a&&(Nt.current.set(k,a),Nl(f=>f+1));let l=at.current;if(!(l&&l.requestId!==Rt.current)&&(k&&(bo.current={url:k,scene:a}),Co(null),Zn(null),!!l)){if(at.current=null,l.streaming){W(`Streaming ${l.modelName}.`),X("success"),ao(!1);return}l.storedBindings&&(Ji.current=!0),wa(a,l.modelName,l.storedBindings),l.restoring&&W(`Restored your last session with ${l.modelName}.`)}},[wa,k]),Km=Y(a=>{if(!Le?.tilesetUrl)return;let l=a.map(C=>C.name);if(l.length===0)return;Rl.current=l,Ji.current=!0;let f=p?.models.find(C=>C.url===k)?.objectBindings,w=ir(l,f);te.reset(w),z(C=>C??l[0]??null),W(`Streaming ${l.length} bindable objects.`),X("success"),ao(!1)},[ir,te,k,p,Le]),Gm=Y(a=>{let l=at.current;if(!(l&&l.requestId!==Rt.current)){if(at.current=null,console.error(a),l?.restoring)We.current=null,Q(null),W(qs(l.modelName));else if(l)W(Rd(a)?`${l.modelName} is a point cloud: it has points but no faces. Turn it into a mesh first, for example with MeshLab or Blender.`:`Could not read ${l.modelName}. Make sure the file is a valid GLB, GLTF, OBJ, FBX, USDZ, STL, or PLY asset.`);else{let{detail:f}=br(a,k??"",Qe.current?.format);W(`Could not read ${L||"the model"}. ${f}`)}X("error"),$e.current&&(clearTimeout($e.current),$e.current=null),To.current=0,ao(!1),Uo(null)}},[k,L]),qm=Y(a=>{let l=null;if(a.lengthComputable&&a.total>0)l=a.loaded/a.total*100;else{let w=er.current;w&&w>0&&(l=a.loaded/w*100)}if(l===null)return;let f=Math.min(99,Math.floor(l));f>To.current&&(To.current=f),Uo(w=>l>=99.5?100:Math.max(w??0,f)),l>=99.5&&W(w=>w.startsWith("Finalizing")?w:"Finalizing: parsing geometry and textures.")},[]),Wm=Y(a=>{Ft.handleAnimationsReady(a),k&&Ht.handleModelAnimationsReady(k,a)},[Ft,k,Ht.handleModelAnimationsReady]),Ty=async()=>{Qe.current?.cleanup(),Qe.current=null,We.current={model:{kind:"url",url:Cb,name:"room.glb"}},await Sa(Cb,"room.glb")},Wl=async a=>{if(!u)return;if(a.name.toLowerCase().endsWith(".ri.zip")){await od(a);return}if(h){try{ao(!0),W(`Uploading ${a.name}...`),X("default");let w=await h(a);Ze.current.set(w.url,w),We.current={model:{kind:"url",url:w.url,name:w.name??a.name}},await Sa(w.url,w.name??a.name,a.size,w)}catch(w){ao(!1),W(w instanceof Error?w.message:`Could not upload ${a.name}.`),X("error")}return}let l;try{l=await Oo(a)}catch(w){W(w instanceof Error?w.message:"Could not read model file. Upload a .glb, .gltf, .obj, .fbx, .usdz, .stl, .ply, or .zip asset."),X("error");return}Qe.current?.cleanup(),Qe.current=l;let f=Gs();po.current.set(f,a),We.current={model:{kind:"file",key:f,name:l.name},file:a},await Sa(l.url,l.name,a.size,{url:l.url,name:l.name})},Ym=async a=>{let l=a.target.files?.[0];l&&(await Wl(l),a.target.value="")},ar=()=>{ii.current?.(),ut(),Qe.current?.cleanup(),Qe.current=null,bo.current=null,at.current=null,We.current=null,Ft.clearAnimations(),Tt.current={},Pn.current=0,Qn(!1),$e.current&&(clearTimeout($e.current),$e.current=null),To.current=0,Uo(null),er.current=void 0,Q(null),Me(""),G.forEach(a=>a.resolved?.cleanup()),ee([]),P([]),Ke.reset(Zo),yn([]),ko([]),Z(null),z(null),Mn(null),te.reset({}),Fi("{}"),Hi("{}"),$i(null),Ui(null),ua(null),oi("select"),Wi(a=>tt(a)),W(""),X("default")},Yl=a=>p?{...a,bindingHistory:void 0}:a,Jm=()=>{ai.length>1?vn(!0):ar()},Xm=()=>{vn(!1)},Zm=a=>{if(vn(!1),le.length<=1){ar();return}if(!le.includes(a))return;if(ut(),a!==k){let E=G.find(H=>H.url===a);E?.resolved?.cleanup(),ee(H=>H.filter(F=>F.url!==a)),P(H=>H.filter(F=>F!==a)),W(`Removed ${E?.name??"the model"}.`),X("success");return}let l=le.filter(E=>E!==a),f=l[0],w=G.findIndex(E=>E.url===f),C=G[w];if(!C){ar();return}Qe.current?.cleanup(),ee(E=>E.filter((H,F)=>F!==w)),P(l),Qe.current=C.resolved??null,We.current={model:C.sessionModel??{kind:"url",url:C.url,name:C.name}},bo.current=null,at.current=null,Tt.current=C.originalTransforms,Ft.clearAnimations(),oa(C),Q(C.url),Me(C.name),Z(Ze.current.get(C.url)??{url:C.url,name:C.name}),te.restoreModel(C),z(Object.keys(C.bindings)[0]??null),Mn(null),W(`Removed the model \u2014 now viewing ${C.name}.`),X("success")},Qm=a=>{vn(!1);let l=De.find(C=>C.url===a);if(l){ut(),te.removeMerge(a),p&&te.clearHistory(),W(`Removed ${io(l.namePrefix)}.`),X("success");return}let f=G.find(C=>C.mergedModelSources.some(E=>E.url===a));if(!f)return;let w=f.mergedModelSources.find(C=>C.url===a);w&&(ut(),ee(C=>C.map(E=>E.url!==f.url?E:Yl(Os(E,H=>As(H,a))))),W(`Removed ${io(w.namePrefix)}.`),X("success"))},Jl=()=>{m.current?.click()},ka=()=>{ea(!0)},eg=a=>{let l=a.target.files?.[0];a.target.value="";let f=Gi.current;Gi.current=null,!(!l||!u||!f)&&(f.mode==="separate"?ng(l):ig(l,f.targetUrl))},tg=Y(()=>{Gi.current=null,ea(!1)},[]),og=Y(a=>{Gi.current=a,ea(!1),N.current?.click()},[]),Ca=Y(async a=>{if(p&&h){W(`Uploading ${a.name}...`),X("default");let w=await h(a);Ze.current.set(w.url,w);let C=w.name??a.name;return{resolved:{url:w.url,name:C,format:"glb",cleanup:()=>{}},sessionModel:{kind:"url",url:w.url,name:C}}}let l=await Oo(a),f=Gs();return po.current.set(f,a),{resolved:l,sessionModel:{kind:"file",key:f,name:l.name}}},[p,h]),ng=Y(async a=>{if(!Ot(Ii.current,"models",qi.current.modelOrder.length)){W("Your plan has no room for another model in this project. Upgrade to add more."),X("error");return}let l,f;try{({resolved:l,sessionModel:f}=await Ca(a))}catch(w){W(w instanceof Error?w.message:"Could not read model file. Upload a .glb, .gltf, .obj, .fbx, .usdz, or .zip asset."),X("error");return}ee(w=>[...w,{url:l.url,name:l.name,bindings:{},originalTransforms:{},resolved:l,sessionModel:f,mergedModelSources:[]}]),P(w=>[...w,l.url]),ut(),W(`Added ${l.name} as a separate model.`),X("success")},[ut,Ca]),ig=Y(async(a,l)=>{let f,w;try{({resolved:f,sessionModel:w}=await Ca(a))}catch(V){W(V instanceof Error?V.message:"Could not read model file. Upload a .glb, .gltf, .obj, .fbx, .usdz, or .zip asset."),X("error");return}let C=qi.current,E=C.parkedModels.find(V=>V.url===l);if(!C.modelOrder.includes(l)||l!==C.modelUrl&&!E){f.cleanup(),W("The destination model was removed. Choose a model and add the file again."),X("error");return}let H={url:f.url,resolved:f,sessionModel:w,nodeNames:[],loadState:"loading"};l===C.modelUrl?(te.addMerge(V=>({...H,namePrefix:Rs(f.name,V.mergeSources,V.bindings)})),p&&te.clearHistory()):ee(V=>{let ae=V.findIndex(Be=>Be.url===l);if(ae===-1)return V;let ne=[...V];return ne[ae]=Yl(Os(ne[ae],Be=>({...Be,mergeSources:[...Be.mergeSources,{...H,namePrefix:Rs(f.name,Be.mergeSources,Be.bindings)}]}))),ne});let F=l===C.modelUrl?C.modelName:E?.name;ut(),W(`Merging ${f.name} into ${F||"the model"}...`),X("default")},[te.addMerge,ut]),rg=Y((a,l)=>{let f=De.find(V=>V.url===a);if(f){let{bindings:V,originalTransforms:ae,nodeNames:ne}=Ns(l,q);te.hydrateMerge(a,{nodeNames:ne,loadState:"loaded"},V),Tt.current={...Tt.current,...ae},W(`Merged ${ne.length} node${ne.length===1?"":"s"} from ${f.namePrefix||"the added model"} into ${L||"the model"}.`),X("success");return}let w=G.find(V=>V.mergedModelSources.some(ae=>ae.url===a));if(!w)return;let C=w.mergedModelSources.find(V=>V.url===a);if(!C)return;let{bindings:E,originalTransforms:H,nodeNames:F}=Ns(l,w.bindings);ee(V=>V.map(ae=>ae.url!==w.url?ae:{...Es(ae,a,{nodeNames:F,loadState:"loaded"},E),originalTransforms:{...ae.originalTransforms,...H}})),W(`Merged ${F.length} node${F.length===1?"":"s"} from ${C.namePrefix||"the added model"} into ${w.name||"the model"}.`),X("success")},[te.hydrateMerge,L,De,q,G]),ag=Y((a,l)=>{let f=De.find(C=>C.url===a)??G.flatMap(C=>C.mergedModelSources).find(C=>C.url===a);if(!f)return;te.hydrateMerge(a,{loadState:"failed"}),ee(C=>C.map(E=>E.mergedModelSources.some(H=>H.url===a)?Es(E,a,{loadState:"failed"}):E));let{detail:w}=br(l,a,f.resolved.format);W(`Could not merge ${f.resolved.name}. ${w} Remove the failed file using the Remove model menu.`),X("error")},[De,G,te.hydrateMerge]),sg=Y((a,l)=>{let f=G.find(C=>C.url===a);if(!f)return;let{detail:w}=br(l,a,f.resolved?.format);W(`Could not read ${f.name}. ${w} Remove the failed file using the Remove model menu.`),X("error")},[G]),lg=Y((a,l)=>{Nt.current.get(a)!==l&&(Nt.current.set(a,l),Nl(f=>f+1)),ee(f=>{let w=f.findIndex(F=>F.url===a);if(w===-1)return f;let{bindings:C,originalTransforms:E}=Ri(l,f[w].bindings),H=[...f];return H[w]={...qp(H[w],C),bindings:mn(l,f[w].bindings,f[w].mergedModelSources,C),originalTransforms:{...E,...f[w].originalTransforms}},H})},[]),Jo=Y(a=>{if(a===k)return;let l=G.findIndex(C=>C.url===a);if(l===-1)return;let f=G[l];ii.current?.(),ut();let w=k?{url:k,name:L,bindings:q,originalTransforms:Tt.current,resolved:Qe.current??void 0,sessionModel:We.current?.model,mergedModelSources:De,modelSettings:Eo(oe),bindingHistory:te.snapshot,sceneHistory:Ae.snapshot}:null;ee(C=>{let E=C.filter((H,F)=>F!==l);return w?[...E,w]:E}),Qe.current=f.resolved??null,We.current={model:f.sessionModel??{kind:"url",url:f.url,name:f.name}},bo.current=null,at.current=null,Ft.clearAnimations(),oa(f),Tt.current=f.originalTransforms,Q(f.url),Me(f.name),Z(Ze.current.get(f.url)??{url:f.url,name:f.name}),te.restoreModel(f),z(Object.keys(f.bindings)[0]??null),Mn(null)},[k,L,q,G,te,De,oe,Ae,oa,Ft.clearAnimations,ut]),dg=()=>{K.current?.click()};je(()=>{k&&ye.length&&!ye.some(a=>a.url===k)&&Jo(ye[0].url)},[k,ye,Jo]);let{handleExportBindings:Xl,handleExportSceneConfig:Zl,handleImportBindingsChange:cg,openSceneConfigImportPicker:ug,handleImportSceneConfigChange:pg}=xb({bindings:q,setBindings:$o,sceneConfig:oe,setSceneConfig:zt,nodeKeys:Zt,sceneConfigInputRef:T,setIsExporting:Eb,setStatusMessage:W,setStatusTone:X}),bg=a=>{a.preventDefault(),a.stopPropagation(),!(Re||k)&&(Pn.current+=1,Qn(!0))},mg=a=>{a.preventDefault(),a.stopPropagation(),!(Re||k)&&(a.dataTransfer.dropEffect="copy",Qn(!0))},gg=a=>{a.preventDefault(),a.stopPropagation(),!(Re||k)&&(Pn.current=Math.max(0,Pn.current-1),Pn.current===0&&Qn(!1))},fg=async a=>{if(a.preventDefault(),a.stopPropagation(),Pn.current=0,Qn(!1),Re||k)return;let l=a.dataTransfer.files?.[0];l&&await Wl(l)},Ql=(a,l,f)=>{if(!O)return;let w;try{w=JSON.parse(l)}catch{f("Invalid JSON");return}if(w===null||typeof w!="object"||Array.isArray(w)){f("Expected a JSON object");return}if(a==="metrics"&&Object.values(w).some(E=>typeof E!="number"||!Number.isFinite(E))){f("Metrics values must be numbers");return}At(O,C=>({...C,[a]:w})),f(null)},Ma=Y((a,l)=>{rr&&Dn(a,l).catch(f=>console.warn("[BindingBuilder] Could not store decal image for autosave:",f))},[rr]),hg=He(()=>{let a=bo.current?.scene,f=(a&&O?li(a,O):null)?.geometry;if(!f)return .2;f.boundingBox||f.computeBoundingBox();let w=f.boundingBox?.getSize(new Ei),C=w?Math.max(w.x,w.y,w.z):0;return C>0&&Number.isFinite(C)?C/3:.2},[O,k,Re]),xg=He(()=>{if(!zi?.moving)return null;let{nodeKey:a,decal:l}=zi,f=q[a],w=f?.decals?.find(C=>C.id===l.id);return w?{objectId:f.modelObjectId??a,decal:w,onCancel:()=>Co(null),onCommit:C=>{$o(E=>{let H=E[a];return H?{...E,[a]:{...H,decals:H.decals?.map(F=>F.id===w.id?{...F,...C}:F)}}:E}),Co(null)}}:null},[q,zi,$o]),vg=Y((a,l)=>{if(!O)return;let f=q[O],w=f?.decals?.find(F=>F.id===a);if(!w)return;let C=Xt.current,E=C?.raw.nodes[f.modelObjectId??O],H=qd(E,C?.raw.controls.camera,w,l);if(!H){W("No visible surface in that direction. Try another arrow or rotate the view."),X("error");return}Co(null),At(O,F=>({...F,decals:F.decals?.map(V=>V.id===a?{...V,...H}:V)}))},[q,O,At]),yg=Y(a=>{if(!a||a.moving){Co(a);return}let l=Xt.current,f=q[a.nodeKey],w=l?.raw.nodes[f?.modelObjectId??a.nodeKey],C=Gd(w,l?.raw.controls.camera);if(!C){W("Could not find a surface on this object for the decal."),X("error");return}let E={...a.decal,...C};$o(H=>{let F=H[a.nodeKey];if(!F)return H;let V=(F.decals??[]).filter(ae=>ae.id!==E.id);return{...H,[a.nodeKey]:{...F,decals:[...V,E]}}}),Co({...a,moving:!0})},[q,$o]),wg=Y((a,l)=>{let f=Object.entries(q).find(([F,V])=>V===a||F===a.modelObjectId||V.modelObjectId===a.modelObjectId)?.[0],w=f?q[f]?.decals?.find(F=>F.id===l):void 0;if(!f||!w)return;xn("object"),rl(F=>({...F,decals:!0})),z(f);let{position:C,normal:E,...H}=w;setTimeout(()=>Co({nodeKey:f,decal:H,moving:!0}),0)},[q]),Sg=Y(a=>{let l=[...new Set(a)].filter(f=>q[f]&&!q[f].removed);Jn(l)},[q,Jn]),kg=Y(a=>{let l=Li.current;if(Li.current={shiftKey:!1,ctrlKey:!1,metaKey:!1},qe){la("orbit");return}if(!a){ro(null);return}let f=Object.entries(q).find(([w,C])=>C===a||w===a.modelObjectId||C.modelObjectId===a.modelObjectId)?.[0]??null;ro(f,l)},[qe,q,ro]),Pa=Y(async a=>{if(qe){la("orbit");return}ro(a),!U&&(ua(null),await Bn(a))},[qe,Bn,U,ro]),Cg=Y(a=>{ua(a?q[a]??null:null)},[q]),Mg=Y(()=>{if(qe){W("Camera positions aren't available while Pointer Lock is the active camera controller."),X("error");return}if(!O||!Ne)return;let a={position:Ne.position,target:Ne.target,...Ne.fov!=null?{fov:Ne.fov}:{},zoom:Ne.zoom};At(O,l=>({...l,cameraState:a}))},[qe,O,Ne]),Pg=Y(()=>{if(qe){W("Camera positions aren't available while Pointer Lock is the active camera controller."),X("error");return}!No?.position||!No?.target||or({position:No.position,target:No.target,fov:No.fov??Ne?.fov??null,zoom:No.zoom??Ne?.zoom??1},!0)},[qe,No,or,Ne]),Bg=Y(()=>{qe||O&&At(O,a=>({...a,cameraState:void 0}))},[qe,O]),ed=Y(async()=>{if(qe){W("Reset view isn't available while Pointer Lock is the active camera controller."),X("error");return}await Hl()},[qe,Hl]),si=Y(async()=>{if(qe){W("Fit scene isn't available while Pointer Lock is the active camera controller."),X("error");return}await $l()},[qe,$l]),Tg=Y(()=>{W("Texture position saved."),X("success"),Pl.current?.()},[]),Rg=Y(a=>{hl(a),fl(!0)},[]),sr=Y(()=>{fl(!1),hl(null)},[]),Ng=Y(()=>{if(ti==="bindings"){if(!Zt.length){sr();return}let a=ui(Zt,Il);te.reset(a,{asEdit:!0}),z(Zt[0]??null),W("Object bindings reset to default values."),X("success")}else ti==="assets"?(Ke.setValueAsStep(a=>({...a,gridSize:Zo.gridSize,placements:Object.fromEntries(Object.entries(a.placements).map(([l,f])=>{let{position:w,rotation:C,scale:E,...H}=f;return[l,H]}))})),W("Asset placements reset to default values."),X("success")):ti==="scene"&&(Ae.reset(Ao,{asEdit:!0}),W("Scene config reset to default values."),X("success"));sr()},[ti,Zt,te,Ae,Ke,sr]),td=Y(a=>{a.length>0&&ta(a)},[]),Ag=Y((a,l)=>{vt("bindings"),te.setValueAsStep(f=>Op(f,a,l))},[te.setValueAsStep]),Og=Y((a,l)=>{vt("bindings"),te.setValueAsStep(f=>Ep(f,a,l))},[te.setValueAsStep]),Eg=Y(()=>{ta(null)},[]),jg=Y(()=>{let a=Bo;if(!a||a.length===0)return;vt("bindings");let l=new Set(a);te.setValueAsStep(f=>{let w={...f};for(let C of a)f[C]&&(w[C]={...f[C],removed:!0});return w}),z(f=>f&&l.has(f)?null:f),xt(f=>f.filter(w=>!l.has(w))),Zn(f=>f&&l.has(f)?null:f),W(a.length===1?`Deleted ${q[a[0]]?.label||a[0]}.`:`Deleted ${a.length} objects.`),X("success"),ta(null)},[Bo,q,te.setValueAsStep]),Lg=Y(()=>{Qr(null)},[]),Ig=async()=>{let a;try{a=await kc()}catch(l){console.warn("[BindingBuilder] Could not read the saved session:",l),W("Couldn't read the saved session from this browser."),X("error");return}if(!a){W("No saved session in this browser. Sessions are saved when you edit a model or add another one."),X("error");return}Qr(a)},Ba=async(a,l)=>(await Promise.all(a.map(async({entry:w,file:C})=>{if(w.model.kind==="url"&&p)return zn({url:"",objectBindings:{},mergeModels:[{url:w.model.url,namePrefix:w.namePrefix}]})[0];if(w.model.kind==="url")return console.warn(`[BindingBuilder] Could not restore merged model "${w.model.name}" \u2014 merged models must come from an uploaded file.`),null;if(!C)return console.warn(`[BindingBuilder] Could not restore merged model "${w.model.name}" \u2014 its file is no longer in this browser's storage.`),null;try{let E=await Oo(C);return l.set(w.model.key,C),{url:E.url,namePrefix:w.namePrefix,resolved:E,sessionModel:w.model,nodeNames:[],loadState:"loading"}}catch(E){return console.warn(`[BindingBuilder] Could not restore merged model "${w.model.name}":`,E),null}}))).filter(w=>w!==null),Dg=async(a,l,f)=>{let w=await Promise.all(a.map(async({entry:E,file:H,mergeFiles:F})=>{if(await Oi(E.modelSettings?.product),E.model.kind==="url")return{url:E.model.url,name:E.model.name,bindings:await fn(E.bindings),originalTransforms:E.originalTransforms,modelSettings:E.modelSettings,sessionModel:E.model,mergedModelSources:await Ba(F,f)};if(!H)return console.warn(`[BindingBuilder] Could not restore parked model "${E.model.name}" \u2014 its file is no longer in this browser's storage.`),null;try{let V=await Oo(H);return f.set(E.model.key,H),{url:V.url,name:E.model.name,bindings:await fn(E.bindings),originalTransforms:E.originalTransforms,modelSettings:E.modelSettings,resolved:V,sessionModel:E.model,mergedModelSources:await Ba(F,f)}}catch(V){return console.warn(`[BindingBuilder] Could not restore parked model "${E.model.name}":`,V),null}})),C=await Ba(l,f);return{parkedModels:w.filter(E=>E!==null),mergedModelSources:C}},Ta=(a,l)=>{Ke.setValue(f=>({...f,placements:{...f.placements,[a]:{...f.placements[a],...l}}}))},zg=async a=>{if(wn||!u||!Al)return;let l=a===k?{url:a,name:L,bindings:q,originalTransforms:Tt.current,resolved:Qe.current??void 0,sessionModel:We.current?.model,mergedModelSources:De,modelSettings:Eo(oe)}:G.find(C=>C.url===a);if(!l?.sessionModel)return;if(p){let C=`${a.split("#")[0]}#copy-${crypto.randomUUID()}`,E=rn(C),H=Ze.current.get(a);Ze.current.set(C,{...H,url:C});let F=`${l.name} copy`,V=structuredClone(l.modelSettings);V?.measurements&&(V.measurements.items=V.measurements.items.map(Ce=>({...Ce,modelId:E}))),ee(Ce=>[...Ce,{...l,url:C,name:F,resolved:void 0,sessionModel:{kind:"url",url:C,name:F},bindings:structuredClone(l.bindings),originalTransforms:structuredClone(l.originalTransforms),modelSettings:V,mergedModelSources:l.mergedModelSources.map($t=>({...$t,loadState:"loading"})),bindingHistory:void 0,sceneHistory:void 0}]),P(Ce=>[...Ce,C]),yn(Ce=>[...Ce,E]);let ae=ri(a),[ne,Be,wt]=ae.position??[0,0,0];Ke.setValueAsStep(Ce=>({...Ce,placements:{...Ce.placements,[E]:{...ae,deleted:!1,label:`${ae.label??l.name} copy`,position:[ne+ct.gridSize,Be,wt]}}})),ut(),W(`Duplicated ${l.name}.`),X("success");return}Sn(!0);let f=Rt.current,w=[];try{let E=(l.sessionModel.kind==="file"?po.current.get(l.sessionModel.key):void 0)??new File([await(await fetch(l.url)).blob()],l.name),H=await Oo(E);w.push(H);let F=Gs(),V=`file:${F}`,ae=[];for(let we of l.mergedModelSources){if(we.sessionModel.kind!=="file")throw new Error("Cannot duplicate a merged source without its original file.");let st=po.current.get(we.sessionModel.key);if(!st)throw new Error("An added source file is unavailable.");let Ut=await Oo(st);w.push(Ut),ae.push({...we,resolved:Ut,url:Ut.url,loadState:"loading"})}if(f!==Rt.current||!qi.current.modelOrder.includes(a)){w.forEach(we=>we.cleanup());return}po.current.set(F,E);let ne=structuredClone(l.modelSettings);ne?.measurements&&(ne.measurements.items=ne.measurements.items.map(we=>({...we,modelId:V}))),ee(we=>[...we,{...l,url:H.url,name:`${l.name} copy`,resolved:H,sessionModel:{kind:"file",key:F,name:E.name},bindings:structuredClone(l.bindings),originalTransforms:structuredClone(l.originalTransforms),modelSettings:ne,mergedModelSources:ae,bindingHistory:void 0,sceneHistory:void 0}]),P(we=>[...we,H.url]),yn(we=>[...we,V]);let Be=ri(a),[wt,Ce,$t]=Be.position??[0,0,0];Ke.setValueAsStep(we=>({...we,placements:{...we.placements,[V]:{...Be,deleted:!1,label:`${Be.label??l.name} copy`,position:[wt+ct.gridSize,Ce,$t]}}})),ut(),W(`Duplicated ${l.name}.`),X("success")}catch(C){w.forEach(E=>E.cleanup()),W(C instanceof Error?C.message:"Could not duplicate asset."),X("error")}finally{Sn(!1)}},Fg=a=>{if(ye.length<2||!u)return;let l=ye.find(f=>f.url===a);l&&(a===k&&Jo(ye.find(f=>f.url!==a).url),Ke.setValueAsStep(f=>({...f,placements:{...f.placements,[l.id]:{...f.placements[l.id],deleted:!0}}})))},od=async a=>{if(!(wn||!u)){if(!lt(Ii.current,"sceneBundle")){W(`Importing a complete scene requires the ${Ia.starter} plan or higher.`),X("error");return}Sn(!0);try{let l=await Ac(a);if(p){if(!h)throw new Error("This project can't accept new models.");let f=w=>l.session.composition?.placements[eo(w)]?.deleted;if(1+l.parkedFiles.filter(w=>!f(w.entry.model)).length>Bl)throw new Error(`Your plan allows ${Bl} models per project. Upgrade to import this scene.`);W(`Uploading the models in ${a.name}...`),X("default"),l=await Bc(l,async w=>{let C=await h(w);return Ze.current.set(C.url,C),C})}await nd(l),ut()}catch(l){W(l instanceof Error?l.message:"Could not load scene bundle."),X("error")}finally{Sn(!1)}}},Hg=async()=>{let a=We.current;if(!(!a||!k||wn)){Sn(!0);try{let l=C=>({model:C.sessionModel,namePrefix:C.namePrefix}),f={model:a.model,bindings:q,sceneConfig:oe,composition:ct,mergeModels:De.map(l),parkedModels:G.map(C=>({model:C.sessionModel??{kind:"url",url:C.url,name:C.name},bindings:C.bindings,originalTransforms:C.originalTransforms,modelSettings:C.modelSettings,mergeModels:C.mergedModelSources.map(l)})),modelOrder:le.map(C=>Ro.get(C)).filter(Boolean)},w=await Nc(f,new Map(po.current));An(w,"scene.ri.zip"),W("Saved complete scene bundle."),X("success")}catch(l){W(l instanceof Error?l.message:"Could not save scene."),X("error")}finally{Sn(!1)}}},nd=async a=>{let l=a??_o;if(Qr(null),!l)return;let{session:f,file:w}=l,{model:C}=f;ii.current=null;let E=Rt.current,H=await hb(gi(Ao,f.sceneConfig));await Oi(H.product);let F=await fn(f.bindings);if(await Hr(H),Rt.current!==E)return;let V=new Map,{parkedModels:ae,mergedModelSources:ne}=await Dg(l.parkedFiles,l.mergeFiles,V);if(Rt.current!==E){ae.forEach(Ti),ne.forEach(Yn);return}let Be=we=>{let st=new Map;st.set(eo(C),we),ae.forEach(Vt=>{Vt.sessionModel&&st.set(eo(Vt.sessionModel),Vt.url)});let Ut=(f.modelOrder??[]).map(Vt=>st.get(Vt)).filter(Vt=>!!Vt),sd=new Set(Ut);for(let Vt of[we,...ae.map(_g=>_g.url)])sd.has(Vt)||(Ut.push(Vt),sd.add(Vt));return Ut},wt=()=>{for(let[we,st]of V)po.current.set(we,st),a?tr.current.delete(we):tr.current.add(we)},Ce;if(C.kind==="file"){if(!w){ae.forEach(Ti),ne.forEach(Yn);return}let we=Rt.current,st;try{st=await Oo(w)}catch(Ut){console.warn("[BindingBuilder] Could not read the saved model:",Ut),W(qs(C.name)),X("error"),ae.forEach(Ti),ne.forEach(Yn);return}if(Rt.current!==we){st.cleanup(),ae.forEach(Ti),ne.forEach(Yn);return}Qe.current?.cleanup(),Qe.current=st,Ce=st.url,V.set(C.key,w),wt(),na(),G.forEach(Ut=>Ut.resolved?.cleanup()),ee(ae),ko(ne),P(Be(Ce)),Ke.reset(f.composition?Qo(f.composition):Zo),yn([])}else{Ce=C.url,wt(),na(),G.forEach(st=>st.resolved?.cleanup()),ee(ae),ko(ne),P(Be(Ce)),Ke.reset(f.composition?Qo(f.composition):Zo),yn([]);let we=bo.current;if(Ce===k&&we?.url===Ce&&!at.current){We.current={model:C},te.reset(mn(we.scene,F,ne,Ri(we.scene,F).bindings)),Ae.reset(H),W(`Restored your last session with ${C.name}.`),X("success");return}Qe.current?.cleanup(),Qe.current=null}We.current={model:C,file:w??void 0},C.kind==="file"&&!a&&tr.current.add(C.key);let $t=++Rt.current;Ce!==k&&Ft.clearAnimations(),ao(!0),Uo(null),To.current=0,$e.current&&(clearTimeout($e.current),$e.current=null),er.current=w?.size,W("Restoring your last session."),X("default"),Me(C.name),Z({url:Ce,name:C.name}),Mn(null),z(null),bo.current=null,te.reset({}),Ae.reset(H),at.current={requestId:$t,modelName:C.name,modelUrl:Ce,storedBindings:F,restoring:!0},Q(Ce)};je(()=>{let a=l=>{if((l.metaKey||l.ctrlKey)&&l.key.toLowerCase()==="k"){l.preventDefault(),Gr(w=>!w);return}if(l.metaKey||l.ctrlKey||l.altKey||Rb(l.target,!0))return;if(l.key==="?"){l.preventDefault(),qr(w=>!w);return}if(!k)return;let f=Nr.find(w=>w.shortcut.toLowerCase()===l.key.toLowerCase());f?(l.preventDefault(),oi(f.id)):l.key.toLowerCase()==="f"&&(l.preventDefault(),O?Bn(O):si())};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[k,O,Bn,si]);let Tn=Gc();if(Go.status==="checking")return R("div",{className:"bb-root bb-root--licenseChecking",children:!v&&R(Oa,{title:"Validating license key\u2026"})});if(Go.status==="invalid")return R("div",{className:"bb-root bb-root--licenseInvalid",children:R(Oa,{tone:"error",title:"Invalid license",showKeySetup:Go.isLocalDomain&&Go.reason==="No license key provided",message:Go.isLocalDomain?Go.reason??"License has been revoked or has expired":"Failed to load. Please contact the site administrator."})});let id=(Dt==="annotations"||Vr.open&&Vi==="cinematic")&&Ne?{position:Ne.position,target:Ne.target,azimuthAngle:Ne.azimuthAngle,polarAngle:Ne.polarAngle,fov:Ne.fov,zoom:Ne.zoom}:null,$g=k?mo.get(k)??"Model":"Untitled scene",Xo=Te&&!Mb.find(a=>a.id===ol)?.group?"general":ol,Ug=a=>{a.panel==="object"?(so.setOpen(!0),xn("object"),nl(a.tab)):a.panel==="scene"?(so.setOpen(!0),xn("scene"),Yr(a.tab)):a.panel==="configure"?(xn("configure"),vt("scene")):a.panel==="left"?(Mo.setOpen(!0),_i(a.tab)):(tl(a.tab),Vr.setOpen(!0)),a.section&&sp(a.section)},Vg=()=>[...Nr.map(a=>({id:`tool-${a.id}`,label:`${a.label} tool`,hint:"Tool",shortcut:a.shortcut,run:()=>oi(a.id)})),{id:"frame",label:"Frame selection",hint:"Camera",shortcut:"F",run:()=>{O?Bn(O):si()}},{id:"fit",label:"Fit scene",hint:"Camera",run:()=>{si()}},{id:"reset-view",label:"Reset view",hint:"Camera",run:()=>{ed()}},{id:"code",label:"Show code",hint:"Code panel",keywords:"json typescript export",run:()=>{so.setOpen(!0),_r(!0)}},{id:"compare",label:"Compare before and after",hint:"Preview",run:()=>wl(!0)},{id:"shortcuts",label:"Keyboard shortcuts",hint:"Help",shortcut:"?",run:()=>qr(!0)},...u?[{id:"add-model",label:"Add model",hint:"Model",keywords:"upload import asset",run:ka}]:[],...ap.map(a=>({id:`setting-${a.label}-${a.where.tab}`,label:a.label,hint:a.hint,keywords:a.keywords,run:()=>Ug(a.where)}))],rd=[{title:"Scene settings",description:"Lighting, camera, and environment for the active model. No model files or bindings.",onImport:ug,onExportJson:()=>Zl("json"),onExportTs:()=>Zl("ts"),importDisabled:!Zt.length||Re,exportDisabled:!Zt.length||Re},{title:"Object bindings",description:"Bindings for the active model, with uploaded textures when available. No model files or scene settings.",onImport:dg,onExportJson:()=>Xl("json"),onExportTs:()=>Xl("ts"),importDisabled:!Zt.length||Re,exportDisabled:!Zt.length||Re}],ad=u&&lt(qo,"sceneBundle")?{onImport:()=>yl.current?.click(),onExport:Hg,importDisabled:Re,exportDisabled:Re||!ye.length||ye.some(a=>!a.ready)}:void 0,Ra=qe?R(rt,{children:"Click the preview to look around \xB7 Esc to release"}):uo!=="select"&&!O?R(rt,{children:"Select an object to transform it"}):uo==="move"?R(rt,{children:"Drag an arrow or plane to move"}):uo==="rotate"?R(rt,{children:"Drag a ring to rotate"}):uo==="scale"?R(rt,{children:"Drag the handle to scale"}):um&&Zr?ce(rt,{children:[ce("span",{children:[R("kbd",{children:"W"}),R("kbd",{children:"A"}),R("kbd",{children:"S"}),R("kbd",{children:"D"})," move"]}),ce("span",{children:["\xB7 ",R("kbd",{children:"Space"}),"/",R("kbd",{children:"C"})," up \xB7 down"]}),R("span",{children:"\xB7 drag to look"})]}):null;return R(zd.Provider,{value:fm,children:ce(ps.Provider,{value:Ma,children:[ce("div",{className:"bb-root","data-input":"pointer",onPointerDownCapture:a=>{a.currentTarget.dataset.input="pointer"},onKeyDownCapture:a=>{a.key==="Tab"&&(a.currentTarget.dataset.input="keyboard")},onMouseOver:Tn.onMouseOver,onContextMenu:Tn.onContextMenu,onKeyDown:a=>{a.key!=="Escape"||a.defaultPrevented||!Te||a.target.closest('input:not([type="checkbox"]), textarea, select, [contenteditable="true"]')||(a.preventDefault(),a.stopPropagation(),U?ji():Ys())},children:[R("input",{ref:m,type:"file",accept:Aa,className:"bb-hiddenInput",onChange:Ym,disabled:Re}),R("input",{ref:N,type:"file",accept:Aa,className:"bb-hiddenInput",onChange:eg,disabled:Re}),R("input",{ref:K,type:"file",accept:".json,application/json",className:"bb-hiddenInput",onChange:cg,disabled:Re}),R("input",{ref:T,type:"file",accept:".json,application/json",className:"bb-hiddenInput",onChange:pg,disabled:Re}),R("input",{ref:yl,type:"file",accept:".zip,application/zip",hidden:!0,onChange:async a=>{let l=a.target.files?.[0];a.target.value="",l&&await od(l)}}),R(_u,{modelName:$g,modelMenu:u||ye.length>1?a=>R(jc,{close:a,models:ye.length>1?ye.map(l=>({url:l.url,label:mo.get(l.url)??l.name})):void 0,activeModelUrl:k,onSelectModel:Jo,onRestore:!u||k||p?void 0:Ig,restoreDisabled:Re,onAddModel:u&&k?ka:void 0,onUpload:u&&!k?Jl:void 0,addModelDisabled:Re,onReset:u&&k?()=>Rg(ei):void 0,resetLabel:`Reset ${Tb[ei]} changes\u2026`,onRemove:u&&k&&(!p||ai.length>1)?Jm:void 0,confirmRemove:ai.length<=1}):void 0,canUndo:Yo.canUndo,canRedo:Yo.canRedo,undoTarget:Tb[ei],onUndo:Yo.undo,onRedo:Yo.redo,tool:uo,onToolChange:a=>{oi(a),a!=="select"&&vt("bindings")},space:xl,onSpaceChange:im,hasModel:!!k,compareOpen:Ko,onToggleCompare:()=>{wl(a=>!a),ra(null)},codeOpen:il,onToggleCode:()=>_r(a=>!a),onOpenCommands:()=>Gr(!0),start:e,xrToolsSlot:Gb,fileActions:ce(rt,{children:[R(Vu,{scopes:rd,sceneBundle:ad,busy:wn||Xs}),R(Uu,{scopes:rd,sceneBundle:ad,busy:wn||Xs})]})}),ce("div",{className:`bb-workspace ${Po?"bb-workspace--customerPreview":""}`,children:[Mo.open?ce(rt,{children:[ce("aside",{className:"bb-panel bb-panel--left",style:{width:Mo.size},onPointerDownCapture:()=>{Dt==="assets"&&vt("assets"),Dt==="annotations"&&vt("scene")},children:[ce("div",{className:"bb-tabs",role:"tablist","aria-label":"Scene contents",children:[vy.filter(a=>a.id!=="assets"||u).map(a=>R("button",{type:"button",role:"tab","aria-selected":Dt===a.id,className:`bb-tab ${Dt===a.id?"bb-tab--active":""}`,onClick:()=>_i(a.id),children:a.label},a.id)),R("span",{className:"bb-topBarSpacer"}),R("button",{type:"button",className:"bb-toolButton bb-toolButton--small","aria-label":"Hide left panel",title:"Hide panel",onClick:()=>Mo.setOpen(!1),children:R(ay,{size:14})})]}),R("div",{className:`bb-panelBody ${Dt==="outliner"?"bb-panelBody--fill":""}`,children:Dt==="outliner"?R($p,{bindings:q,selectedItem:O,onSelect:Pa,onHover:Cg,modelGroups:Lm,onSelectModel:Jo,isolatedItem:Di,onIsolate:Zn,multiSelectEnabled:U,onToggleMultiSelect:Jt,onExitMultiSelect:ji,multiSelectedKeys:be,onSetMultiSelected:Sg,hierarchy:Sm,selectionSets:oe.selectionSets,onSelectionSetsChange:rm,onRename:Ag,onSetVisible:Og,onDelete:td,onFocus:Bn}):k?Dt==="assets"?R(is,{assets:ye.map(a=>({...a,displayName:mo.get(a.url)})),activeUrl:k,composition:ct,busy:wn||Re,onFrameAll:()=>{let a=new Ks;for(let f of ye){if(f.placement.visible===!1)continue;let w=Nt.current.get(f.url);w&&(w.updateWorldMatrix(!0,!0),a.union(new Ks().setFromObject(w)))}let l=Xt.current;!a.isEmpty()&&l&&(Yd(a,l.raw.controls),l.raw.controls.fitToBox(a,!0,Jd).then(()=>l.invalidate()))},onSelect:Jo,onAdd:ka,addRequiresTier:Al?void 0:en("models",ye.length),onChange:Ta,onGridSize:a=>Ke.setValue(l=>({...l,gridSize:a})),onDuplicate:a=>{zg(a)},onDelete:p?()=>vn(!0):Fg,deleteIsPermanent:!!p,onSnap:a=>Ta(a,xd(ct.placements[a]??{},ct.gridSize)),onGround:a=>{let l=Nt.current.get(a),f=l?yd(l):null;f&&Ta(Ro.get(a),vd(ri(a),f))}}):Dt==="annotations"?R(by,{config:oe,onChange:a=>{vt("scene"),zt(a)},cameraState:id,onPreviewView:_l}):R("div",{ref:ll,className:"bb-measurePanel"}):R("p",{className:"bb-panelEmpty",children:"Open a model to use this."})})]}),R(Si,{orientation:"vertical",label:"Resize left panel",onPointerDown:Mo.startResize,onKeyDown:Mo.onResizeKey})]}):R("button",{type:"button",className:"bb-panelReveal bb-panelReveal--left","aria-label":"Show left panel",title:"Show panel",onClick:()=>Mo.setOpen(!0),children:R(sy,{size:14})}),ce("main",{className:"bb-previewShell",children:[ce("div",{className:"bb-preview",ref:A,onClickCapture:a=>{let l=Zc(),f=Dl.current;if(!l.active||!(a.target instanceof HTMLCanvasElement)||!f||Math.hypot(a.clientX-f.x,a.clientY-f.y)>4)return;a.stopPropagation(),a.preventDefault();let w=Pr();if(!w)return;let C=Xt.current?.raw.controls.camera,E=A.current?.querySelector("canvas")?.getBoundingClientRect(),H=ae=>{if(!C||!E)return 1/0;let ne=new Ei(ae[0],l.floor,ae[1]).project(C);return Math.hypot(E.left+(ne.x+1)/2*E.width-a.clientX,E.top+(1-ne.y)/2*E.height-a.clientY)},[F]=l.points,V=l.points[l.points.length-1];if(F&&l.points.length>=3&&H(F)<12){xi();return}V&&H(V)<8||Xc([w[0],w[2]])},onPointerMove:Cm,onPointerLeave:fa,onPointerDownCapture:a=>{Dl.current={x:a.clientX,y:a.clientY},Li.current={shiftKey:a.shiftKey,ctrlKey:a.ctrlKey,metaKey:a.metaKey}},onKeyDownCapture:()=>{Li.current={shiftKey:!1,ctrlKey:!1,metaKey:!1}},onFocus:a=>{a.currentTarget.contains(a.relatedTarget)||ca()},children:[k?ce("div",{className:"bb-viewportBar",children:[R(Hn,{label:"View",icon:R(ry,{size:13,"aria-hidden":"true"}),title:"Preview options",children:()=>ce(rt,{children:[ce("label",{className:"bb-headerMenuItem",children:[R("input",{type:"checkbox",checked:gl,onChange:a=>Jb(a.target.checked)}),"Zoom on selected"]}),ce("label",{className:"bb-headerMenuItem",children:[R("input",{type:"checkbox",checked:Xr,onChange:a=>Xb(a.target.checked)}),"Highlight on hover"]}),ce("label",{className:"bb-headerMenuItem",children:[R("input",{type:"checkbox",checked:Zr,onChange:a=>Zb(a.target.checked)}),"Camera controls"]}),ce("label",{className:"bb-headerMenuItem",children:[R("input",{type:"checkbox",checked:Kr,onChange:a=>Hb(a.target.checked)}),"Floor grid"]})]})}),R("div",{"data-ri-path":"sceneConfig.model.renderer",children:R(Hn,{label:Bb.find(a=>a.value===oe.model.renderer)?.label??"PBR",title:"Renderer",children:a=>Bb.map(l=>ce("button",{type:"button",role:"radio","aria-checked":oe.model.renderer===l.value,className:"bb-headerMenuItem bb-modelMenuItem",onClick:()=>{a(),zt({...oe,model:{...oe.model,renderer:l.value}})},children:[R("span",{className:"bb-modelMenuCheck",children:oe.model.renderer===l.value?R(ty,{size:14,"aria-hidden":"true"}):null}),R("span",{className:"bb-modelMenuName",children:l.label})]},l.value))})})]}):null,R($d,{visible:Re,title:L||void 0,message:$r,progress:hm??void 0}),k&&R("div",{className:`bb-canvasHint ${Ra?"bb-canvasHint--visible":""} ${Ko?"bb-canvasHint--belowCompare":""}`,"aria-hidden":!Ra,children:Ra}),Po?R("button",{type:"button",className:"bb-customerPreviewExit",onClick:()=>Wr(!1),children:"Previewing as a customer \xB7 Exit"}):null,k?R(Da,{loading:"eager",enableXR:!0,arHandoff:n,mobileHandoffUrl:c,modelUrl:k,tilesetUrl:Le?.tilesetUrl,models:Im,onModelChange:Jo,onExtraModelLoaded:lg,onExtraModelError:sg,mergeModels:xa,onMergeModelLoaded:rg,onMergeModelError:ag,originalNodePoses:Tt.current,objectBindings:q,comparisonHighlights:Sl?.after,selectedObject:Pe,selectedObjectRefs:Tm,selectedObjectOutlineColor:"#35c0dc",onObjectSelect:kg,onSelectionClear:Ys,onEmptyCanvasClick:()=>oi("select"),unsafe_sceneChildren:R(Wu,{outline:oe.camera.limits?.floorOutline,visible:yt==="scene"&&Vo==="camera"}),onObjectBindingsChange:$o,onTextureUpload:Hm,onObjectEditLeaseChange:(a,l)=>y?.(`${k}|${a.modelObjectId||a.id}`,l),showObjectBindingDataPanel:!1,showSceneObjectsPanel:!1,onCameraChange:Am,onViewerReady:a=>{Xt.current=a,Bm(a.raw.nodes),Rm(a)},onAnnotationsChange:zm,activeAnnotation:mm?.annotation??null,onActiveAnnotationChange:Fm,onSequencesReady:Pm,showSequenceControls:!1,sequenceAutoPlay:!1,onAnimationsReady:Wm,onModelAnimationsReady:Ht.handleModelAnimationsReady,onSceneLoaded:_m,onAssetDiagnostics:ma?a=>El({url:k,report:a}):void 0,onRuntimeStats:ma?jl:void 0,onLoadError:Gm,onObjectCatalog:Le?.tilesetUrl?Km:void 0,onProgress:qm,onCameraControllerChange:la,cameraControllerType:kl,onTexturePositioningChange:pm,endTexturePositioningRef:Pl,licenseKey:i,licenseValidationUrl:r,dracoDecoderPath:d,ktx2TranscoderPath:s,meshopt:g,sceneConfig:Em,onSceneConfigChange:jm,productOptions:Po?!0:void 0,preserveDrawingBuffer:!0,disableZoom:!1,zoomOnSelected:gl,highlightOnHover:Xr,enableCameraControls:Zr,moveModeEnabled:om,scaleModeEnabled:nm,gizmoTool:uo==="rotate"?"rotate":"move",showFloorGrid:Kr&&!Po,objectTransformSpace:xl,enableKeyboardNavigation:!0,showViewGizmo:!Po,showMeasureTools:!0,measurementModelId:We.current?.model.kind==="file"?eo(We.current.model):void 0,showSectionTools:!0,isolation:Ab,onIsolationChange:()=>Zn(null),showIsolateControls:!0,decalMove:xg,onDecalDoubleClick:wg,panelHoveredObject:Xr?gm:null,showLoadingOverlay:!1,autoRotate:qe?!1:oe.model.autoRotate??!1,autoRotateSpeed:oe.model.autoRotateSpeed??1}):R("div",{className:`bb-previewPlaceholder ${zb?"bb-previewPlaceholder--dragActive":""}`,onDragEnter:bg,onDragOver:mg,onDragLeave:gg,onDrop:fg,children:ce("div",{className:"bb-dropCard",children:[R(ey,{size:18,"aria-hidden":"true"}),R("h3",{children:"Drop a model to start"}),R("p",{children:"Each object becomes a binding you can edit and export as code."}),R("div",{className:"bb-formatChips","aria-label":"Supported formats",children:["GLB","GLTF","OBJ","FBX","USDZ","STL","PLY","ZIP"].map(a=>R("span",{children:a},a))}),u?R("button",{type:"button",className:"bb-button bb-button--primary",onClick:Jl,disabled:Re,children:"Choose file"}):null]})}),k&&Ko?R(Dc,{showOutlines:ia,onShowOutlinesChange:dm,matchBy:aa,onMatchByChange:a=>{cm(a),sa(null)},report:ni??void 0,selected:Yi,onSelect:a=>{sa(a?.id??null),a?.afterKey&&Pa(a.afterKey)},liveViewerRef:Xt,split:sm,onSplitChange:lm,labels:[kn?"Pinned":"Before","Now"],beforeAction:ce("button",{type:"button",className:"ri-compare__labelAction",onClick:()=>ra(a=>a?null:{bindings:q,sceneConfig:oe}),"aria-pressed":!!kn,title:kn?"Unpin: compare with the project as it was opened again":"Pin as before: compare later changes with how the preview looks now",children:[kn?R(uy,{size:12}):R(cy,{size:12}),kn?"Unpin":"Pin"]}),renderBefore:a=>R(Da,{loading:"eager",modelUrl:k,tilesetUrl:Le?.tilesetUrl,comparisonHighlights:Sl?.before,objectBindings:Cn.bindings,sceneConfig:{...Cn.sceneConfig,section:oe.section},licenseKey:i,licenseValidationUrl:r,dracoDecoderPath:d,ktx2TranscoderPath:s,meshopt:g,preset:"minimal",showFloorGrid:Kr,showLoadingOverlay:!1,showObjectNavigator:!1,selectedObject:null,zoomOnSelected:!1,highlightOnHover:!1,autoRotate:!1,cinematic:!1,onViewerReady:a})}):null]}),R(kb,{panel:Vr,tabs:yy,tab:Vi,onTabChange:tl,hasModel:!!k,onPointerDownCapture:()=>vt("scene"),children:Vi==="sequences"?R(gy,{config:oe,onChange:zt,controls:Mm,bindings:q,clipDetails:Ft.clipDetails}):Vi==="clips"?R(my,{config:nr.config?{...oe,animations:nr.config}:oe,onChange:nr.onChange?a=>nr.onChange?.(a.animations):zt,clipDetails:Ht.clipDetails,active:Ht.active,play:Ht.play,pause:Ht.pause,stop:Ht.stop,setSpeed:Ht.setSpeed,seek:Ht.seek}):lt(qo,"cinematic")?R(fy,{config:oe,onChange:zt,cameraState:id,onPreviewWaypoint:_l}):R(Ye,{requiredTier:"starter",feature:"Cinematic"})})]}),so.open?ce(rt,{children:[R(Si,{orientation:"vertical",label:"Resize inspector",onPointerDown:so.startResize,onKeyDown:so.onResizeKey}),ce("aside",{className:"bb-panel bb-panel--right",style:{width:so.size},onPointerDownCapture:()=>vt(yt!=="object"?"scene":"bindings"),children:[ce("div",{className:"bb-inspectorScope",children:[R("div",{className:"bb-scopeSwitch",role:"tablist","aria-label":"What to edit",children:["object","scene","configure"].map(a=>R("button",{type:"button",role:"tab","aria-selected":yt===a,className:yt===a?"is-active":"",onClick:()=>{xn(a),vt(a==="object"?"bindings":"scene")},children:a==="object"?"Object":a==="scene"?"Scene":"Configure"},a))}),R("button",{type:"button",className:"bb-toolButton bb-toolButton--small","aria-label":"Hide inspector",title:"Hide panel",onClick:()=>so.setOpen(!1),children:R(ly,{size:14})})]}),yt==="configure"?k?R("section",{className:"bb-editor",children:R(hy,{config:oe,onChange:Ae.setValueAsStep,objectBindings:q,materialVariantGroups:Ll,selectedKey:O,previewSelections:Ki,onPreviewChange:al,onPreviewAsCustomer:()=>Wr(!0),publish:t,modelFileName:L})}):R("p",{className:"bb-panelEmpty",children:"Open a model to let customers customise it."}):yt==="scene"?k?ce(rt,{children:[R("div",{className:"bb-tabs",role:"tablist","aria-label":"Scene settings",children:ju.map(a=>R("button",{type:"button",role:"tab","aria-selected":Vo===a.id,className:`bb-tab ${Vo===a.id?"bb-tab--active":""}`,onClick:()=>Yr(a.id),children:a.label},a.id))}),R("section",{className:"bb-editor",children:R(ns,{diagnostics:{report:Ol?.url===k?Ol.report:null,runtimeStats:ym,onRefresh:wm,onSelectObject:a=>{let l=Object.keys(q).find(f=>f===a||q[f].modelObjectId===a);l&&Pa(l)}},onDiagnosticsOpenChange:vm,config:oe,onChange:zt,activeSubTab:Vo,materialVariantGroups:Ll,onImageFile:Ma,objectBindings:q,limitBounds:km})})]}):R("p",{className:"bb-panelEmpty",children:"Open a model to edit its scene."}):!Pe||!O?R("p",{className:"bb-panelEmpty",children:k?"Select an object to edit it.":"Open a model, then select an object to edit it."}):ce(rt,{children:[ce("div",{className:"bb-objectHeader",children:[ce("div",{className:"bb-objectHeaderText",children:[R("h2",{children:Te&&be.length>1?`${be.length} objects`:Pe.label||O}),R("code",{title:Te?void 0:Pe.modelObjectId,children:Te&&be.length>1?"Edits apply to all of them":Pe.id})]}),R(Hn,{icon:R(iy,{size:14,"aria-hidden":"true"}),title:"Object actions",align:"right",children:a=>ce(rt,{children:[ce("button",{type:"button",className:"bb-headerMenuItem",onClick:()=>{a(),Nb({name:Pe.label||O,style:rc(Pe)})},children:[R(ny,{size:13,"aria-hidden":"true"}),"Copy style"]}),ce("button",{type:"button",className:"bb-headerMenuItem",disabled:!Xn,title:Xn?`Copied from ${Xn.name}`:void 0,onClick:()=>{if(a(),!Xn)return;let l=Te?be:[O];te.setValueAsStep(f=>ac(f,l,Xn.style))},children:[R(oy,{size:13,"aria-hidden":"true"}),"Paste style",Te&&be.length>1?` to ${be.length}`:""]}),ce("button",{type:"button",className:"bb-headerMenuItem bb-headerMenuItem--danger",onClick:()=>{a(),td(Te&&be.length>0?be:[O])},children:[R(py,{size:13,"aria-hidden":"true"}),Te&&be.length>1?`Delete ${be.length} objects\u2026`:"Delete object\u2026"]})]})})]}),R("div",{className:"bb-tabs",role:"tablist","aria-label":"Object settings",children:Mb.filter(a=>!Te||a.group).map(a=>R("button",{type:"button",role:"tab","aria-selected":Xo===a.id,className:`bb-tab ${Xo===a.id?"bb-tab--active":""}`,onClick:()=>nl(a.id),children:a.label},a.id))}),ce("section",{className:"bb-editor",children:[Xo==="general"&&ce(rt,{children:[!Te&&R(hp,{selectedItem:O,selectedBinding:Pe,open:lo.identity,onToggle:()=>co("identity"),updateBinding:At,idError:$m}),!Te&&R(vp,{selectedItem:O,selectedBinding:Pe,open:lo.basics,onToggle:()=>co("basics"),updateBinding:At}),Te&&R(Je,{title:"Basics",open:lo.basics,onToggle:()=>co("basics"),children:R("div",{className:"bb-groupFlags",children:["selectable","hoverable","visible"].map(a=>R(xy,{label:a.charAt(0).toUpperCase()+a.slice(1),values:be.map(l=>q[l]).filter(l=>l&&!l.removed).map(l=>l[a]!==!1),onChange:l=>te.setValueAsStep(f=>{let w={...f};for(let C of be)f[C]&&!f[C].removed&&(w[C]={...f[C],[a]:l});return w})},a))})}),R(Np,{selectedItem:O,selectedBinding:Pe,open:lo.transform,onToggle:()=>co("transform"),updateBinding:At,originalTransform:Tt.current[O]??null,originalTransforms:Tt.current}),!Te&&R(Pp,{selectedBinding:Pe,open:lo.camera,onToggle:()=>co("camera"),cameraState:Ne,formattedCameraState:Dm,savedCameraPosition:No,onSaveCameraPosition:Mg,onGoToSavedCamera:Pg,onClearSavedCamera:Bg,onResetView:ed,onFitScene:si})]}),Xo==="material"&&ce("div",{className:"bb-singleSection",children:[R(fp,{disabled:!O,onApply:a=>O&&ya(O,l=>({...l,...a}))}),R(mp,{selectedItem:O,selectedMaterial:ha,pbrWorkflow:qb,onPbrWorkflowChange:Wb,openMaterialPanels:Vb,materialPanelEnabled:Yb,onToggleMaterialPanel:Kb,onSetMaterialPanelState:Vm,updateSelectedMaterial:ya,setSelectedTexturePath:Um,isTexturePositioningEnabled:bm,onConfirmTexturePosition:Tg,takesImage:Gl})]}),Xo==="decals"&&R("div",{className:"bb-singleSection",children:!Te&&R(Mp,{selectedItem:O,selectedBinding:Pe,open:lo.decals,onToggle:()=>co("decals"),updateBinding:At,placement:zi,onPlacementChange:yg,defaultSize:hg,onImageFile:Ma,onNudge:vg})}),Xo==="actions"&&R("div",{className:"bb-singleSection",children:!Te&&R(wp,{selectedItem:O,selectedBinding:Pe,open:lo.actions,onToggle:()=>co("actions"),updateBinding:At,takesImage:Gl})}),Xo==="data"&&ce(rt,{children:[R(Bs,{title:"Metrics",label:"Metrics JSON",open:lo.metrics,onToggle:()=>co("metrics"),draft:Qs,error:Ib,example:'{"area": 42}',onDraftChange:Fi,onCommit:()=>Ql("metrics",Qs,$i)}),R(Bs,{title:"Metadata",label:"Metadata JSON",open:lo.metadata,onToggle:()=>co("metadata"),draft:el,error:Db,example:'{"room": "kitchen"}',onDraftChange:Hi,onCommit:()=>Ql("metadata",el,Ui)})]})]})]}),il?R(tp,{scope:yt==="object"?"object":"scene",selectedKey:O,selectedBinding:Pe??null,sceneConfig:oe,sceneTab:yt==="configure"?"product":Vo,onClose:()=>_r(!1)}):null]})]}):R("button",{type:"button",className:"bb-panelReveal bb-panelReveal--right","aria-label":"Show inspector",title:"Show panel",onClick:()=>so.setOpen(!0),children:R(dy,{size:14})})]}),R(Yc,{saveState:rr&&k?"Saved in this browser":void 0,objectCount:Zt.filter(a=>!q[a]?.removed).length,selectedCount:Te?be.length:O?1:0,path:Tn.path,hints:My}),R(Xu,{toast:jb,onDismiss:Lb}),Tn.menu?R(qc,{...Tn.menu,onClose:Tn.closeMenu}):null,$b?R(ip,{commands:Vg(),onClose:()=>Gr(!1)}):null,Ub?R(rp,{onClose:()=>qr(!1)}):null]}),Qb&&R(db,{target:ti,onCancel:sr,onConfirm:Ng}),_o&&R(cb,{models:[{name:_o.session.model.name,mergedCount:_o.session.mergeModels?.length??0},...(_o.session.parkedModels??[]).map(a=>({name:a.model.name,mergedCount:a.mergeModels?.length??0}))],savedAt:_o.session.savedAt,onCancel:Lg,onConfirm:()=>{let{name:a}=_o.session.model;nd().catch(l=>{console.warn("[BindingBuilder] Could not restore the session:",l),W(qs(a)),X("error")})}}),em&&R(pb,{destinations:ai.filter(a=>a.kind==="model"),onCancel:tg,onChoose:og}),tm&&R(bb,{options:ai,onCancel:Xm,onRemoveModel:Zm,onRemoveMerge:Qm,permanent:!!p,onRemoveAll:p?void 0:()=>{vn(!1),ar()}}),Bo&&R(ub,{nodeLabel:Bo.length===1?q[Bo[0]]?.label||Bo[0]:`${Bo.length} objects`,count:Bo.length,onCancel:Eg,onConfirm:jg})]})})}export{wr as a,Vy as b,Py as c};