1import{h as N,r as i,j as e,L as M}from"./vendor-react-BLwSIrhn.js";import{a as s}from"./main-CHB6up03.js";import{v as P}from"./vendor-storysplat-Dn-Nx1Ma.js";import{r as $,j as O,z as T,A as B,B as f}from"./index-Dp5DqzpU.js";import{r as F}from"./adminSceneAccess-B5JJwc--.js";import"./vendor-runtime-BlTxHScW.js";import"./vendor-firebase-B0_Ym3gQ.js";import"./vendor-playcanvas-BqMBX6_M.js";const _="allow-scripts allow-pointer-lock allow-popups",k="storysplat-admin-preview";function y(n){return JSON.stringify(n).replace(/</g,"\\u003c").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}function V(n,d){return`<!doctype html> 2<html><head><meta charset="utf-8"><meta name="referrer" content="no-referrer"> 3<style>html,body,#viewer{width:100%;height:100%;margin:0;overflow:hidden;background:#0d0d0f}</style> 4</head><body><div id="viewer"></div><script> 5(() => { 6 const scene = ${y(n)}; 7 const report = (type, detail) => parent.postMessage({ 8 source: ${y(k)}, type, ...detail 9 }, '*'); 10 const fail = error => report('error', { message: String(error?.message || error).slice(0, 1000) }); 11 const runtime = document.createElement('script'); 12 runtime.src = ${y(d)}; 13 // Classic UMD scripts can load from an opaque frame on static hosts that 14 // do not send CORS headers (including local Vite and Netlify previews). 15 runtime.onerror = () => fail('Could not load the viewer runtime.'); 16 runtime.onload = async () => { 17 try { 18 const viewer = await StorySplatViewer.createViewer(document.getElementById('viewer'), scene, { 19 showUI: true, autoPlay: false, lazyLoad: false, disableAnalytics: true 20 }); 21 viewer.on('error', fail); 22 // The host offers a trusted navigation link. Messages from authored code 23 // must never automatically fetch another private scene using admin auth. 24 viewer.on('portalActivated', data => { 25 if (typeof data?.targetSceneId === 'string') { 26 report('portal', { sceneId: data.targetSceneId }); 27 } 28 }); 29 window.addEventListener('pagehide', () => viewer.destroy(), { once: true }); 30 report('ready', {}); 31 } catch (error) { fail(error); } 32 }; 33 document.head.appendChild(runtime); 34})(); 35<\/script></body></html>`}const J=s.div` 36 position: fixed; 37 inset: 0; 38 display: flex; 39 flex-direction: column; 40 background: #0d0d0f; 41 color: #f5f5f7; 42`,q=s.header` 43 display: flex; 44 align-items: center; 45 gap: 16px; 46 flex-wrap: wrap; 47 padding: 10px 18px; 48 background: #17171b; 49 border-bottom: 1px solid #2a2a31; 50 font-size: 13px; 51 z-index: 2; 52`,I=s(M)` 53 display: inline-flex; 54 align-items: center; 55 gap: 6px; 56 color: #a8a8b3; 57 text-decoration: none; 58 &:hover { color: #f5f5f7; } 59`,G=s.span` 60 font-weight: 600; 61 overflow: hidden; 62 text-overflow: ellipsis; 63 white-space: nowrap; 64 max-width: 40vw; 65`,H=s.span` 66 color: #a8a8b3; 67`,L={private:{bg:"rgba(244, 165, 96, 0.16)",fg:"#f4a560"},unlisted:{bg:"rgba(140, 170, 240, 0.16)",fg:"#8caaf0"},public:{bg:"rgba(96, 200, 140, 0.16)",fg:"#60c88c"}},W={private:"Private",unlisted:"Unlisted",public:"Public"},X=s.span` 68 display: inline-flex; 69 align-items: center; 70 gap: 5px; 71 padding: 3px 9px; 72 border-radius: 999px; 73 font-size: 11px; 74 font-weight: 600; 75 letter-spacing: 0.03em; 76 text-transform: uppercase; 77 background: ${n=>L[n.$tone].bg}; 78 color: ${n=>L[n.$tone].fg}; 79`,Y=s.span` 80 margin-left: auto; 81 color: #6f6f7c; 82 font-size: 12px; 83`,Z=s.div` 84 position: relative; 85 flex: 1; 86 min-height: 0; 87`,K=s.iframe` 88 position: absolute; 89 inset: 0; 90 width: 100%; 91 height: 100%; 92 border: 0; 93`,v=s.div` 94 position: absolute; 95 inset: 0; 96 display: flex; 97 flex-direction: column; 98 align-items: center; 99 justify-content: center; 100 gap: 12px; 101 padding: 32px; 102 text-align: center; 103`,U=s.h2` 104 margin: 0; 105 font-size: 18px; 106 font-weight: 600; 107`,p=s.p` 108 margin: 0; 109 max-width: 560px; 110 color: #a8a8b3; 111 font-size: 13px; 112 line-height: 1.6; 113 word-break: break-word; 114`,R=s.div` 115 position: absolute; 116 left: 50%; 117 bottom: 20px; 118 transform: translateX(-50%); 119 display: flex; 120 align-items: center; 121 gap: 8px; 122 max-width: 80vw; 123 padding: 9px 14px; 124 border-radius: 8px; 125 background: rgba(244, 165, 96, 0.14); 126 border: 1px solid rgba(244, 165, 96, 0.32); 127 color: #f4a560; 128 font-size: 12px; 129 z-index: 2; 130`,oe=()=>{const{sceneId:n}=N(),d=i.useRef(null),[u,b]=i.useState(null),[r,S]=i.useState(null),[m,g]=i.useState(null),[j,E]=i.useState(null),[z,h]=i.useState(!0);i.useEffect(()=>{if(!n){g("No scene id in the URL."),h(!1);return}let l=!1;return h(!0),g(null),E(null),b(null),S(null),F(n).then(t=>{l||S(t)}
130).catch(t=>{l||g(t instanceof Error?t.message:String(t))}).finally(()=>{l||h(!1)}),()=>{l=!0}},[n]);const c=i.useMemo(()=>!r||r.scene.id!==n?null:r.isolatedSceneData||r.sceneData||{splatUrl:r.scene.splatUrl,sogUrl:r.scene.sogUrl,lodMetaUrl:r.scene.lodMetaUrl,compressedPlyUrl:r.scene.compressedPlyUrl},[r,n]),A=i.useMemo(()=>c?V(c,new URL(P,window.location.href).href):void 0,[c]);i.useEffect(()=>{const l=t=>{if(!(!d.current||t.source!==d.current.contentWindow||t.origin!=="null"||t.data?.source!==k)&&(t.data.type==="error"&&typeof t.data.message=="string"&&E(t.data.message.slice(0,1e3)),t.data.type==="portal"&&typeof t.data.sceneId=="string")){const x=t.data.sceneId,w=Array.isArray(c?.portals)?c.portals.find(C=>C?.targetSceneId===x):void 0;w&&/^[a-zA-Z0-9._-]{10,250}$/.test(x)&&b({id:x,name:typeof w.targetSceneName=="string"?w.targetSceneName.slice(0,200):"linked scene"})}};return window.addEventListener("message",l),()=>window.removeEventListener("message",l)},[c]);const a=r?.scene,D=a?.ownerDisplayName||a?.ownerId||"",o=a?.visibility??(a?.isPublic?a.unlisted?"unlisted":"public":"private");return e.jsxs(J,{children:[e.jsxs(q,{children:[e.jsxs(I,{to:"/admin",children:[e.jsx($,{size:14})," Admin"]}),a&&e.jsxs(e.Fragment,{children:[e.jsx(G,{title:a.name,children:a.name||"Untitled"}
130),e.jsxs(H,{children:["by ",D]}),e.jsxs(X,{$tone:o,children:[o==="public"&&e.jsx(O,{size:11}),o==="unlisted"&&e.jsx(T,{size:11}),o==="private"&&e.jsx(B,{size:11}),W[o]]})]}),u&&e.jsxs(I,{to:`/admin/scene/${encodeURIComponent(u.id)}`,children:["Open ",u.name," â"]}),e.jsx(Y,{children:o!=="public"?`Read-only admin view · ${o} access audit recorded`:"Read-only admin view"})]}),e.jsxs(Z,{children:[A&&e.jsx(K,{ref:d,title:"Interactive admin scene preview",sandbox:_,allow:"autoplay; fullscreen",allowFullScreen:!0,referrerPolicy:"no-referrer",srcDoc:A},n),z&&e.jsx(v,{children:e.jsx(p,{children:"Resolving sceneâ¦"})}),m&&!z&&e.jsxs(v,{children:[e.jsx(f,{size:28,color:"#f4a560"}),e.jsx(U,{children:"Could not resolve this scene"}),e.jsx(p,{children:m}),e.jsx(p,{children:"Scenes that are deleted, retired, or missing from the live scene index cannot be opened here. Those are still recoverable through Clone on the admin page, which reads the owner document directly."})]}),j&&!m&&e.jsxs(v,{children:[e.jsx(f,{size:28,color:"#f4a560"}),e.jsx(U,{children:"Scene resolved, but the viewer failed to start"}),e.jsx(p,{children:j}),e.jsx(p,{children:"The scene record is fine â its assets failed to load or render. Check the browser console for the failing request; a 404 usually means the owner's splat file is missing from Storage."})]}),r&&r.isolatedSceneData===void 0&&!r.sceneDataError&&e.jsxs(R,{children:[e.jsx(f,{size:13}),"This server provides a visual-only preview. Deploy the updated resolveAdminScene function to enable scene controls."]}),r?.sceneDataError&&e.jsxs(R,{children:[e.jsx(f,{size:13}),"Scene JSON unavailable (",r.sceneDataError,") â rendering from index asset URLs, which may be stale."]})]})]})};export{oe as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.