@three-blocks/devtools 1.0.1-alpha.229.gb2f4ea7d182c → 2.0.0-alpha.238.g8723f0a28ca3
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.
- package/CHANGELOG.md +30 -2
- package/README.md +27 -4
- package/dist/browser/shader-capture.d.ts +13 -1
- package/dist/browser/shader-capture.js +2 -2
- package/dist/{browser-smoke-X3NBYPHI.js → browser-smoke-EIKJ6OVK.js} +4 -4
- package/dist/chunk-4YRR36JN.js +97 -0
- package/dist/chunk-65VEJRRT.js +2 -0
- package/dist/chunk-GA7PGW2R.js +18 -0
- package/dist/{chunk-JMS5NTP7.js → chunk-JHBQB7WC.js} +1 -1
- package/dist/chunk-LUULHXFK.js +17 -0
- package/dist/chunk-NPLE7PPF.js +3 -0
- package/dist/{chunk-YLN3G2JS.js → chunk-OQLHTDDH.js} +1 -1
- package/dist/chunk-TRHSN2DJ.cjs +1 -0
- package/dist/{chunk-ILOEBEIQ.js → chunk-TUIINI6U.js} +1 -1
- package/dist/chunk-V34C7NIM.js +80 -0
- package/dist/chunk-W6UL2OW7.js +2 -0
- package/dist/cli.js +22 -22
- package/dist/environment-bake-XMRKQJXM.js +4 -0
- package/dist/index.d.ts +38 -8
- package/dist/index.js +24 -21
- package/dist/{shader-autowire-DCODBFMX.js → shader-autowire-SPE5DM2X.js} +1 -1
- package/dist/{shader-browser-ZGPGYM2U.js → shader-browser-EYE3UT2U.js} +1 -1
- package/dist/{shader-browser-FSCRBXJ7.js → shader-browser-WF4HNSAV.js} +1 -1
- package/dist/shader-capture-server.d.ts +22 -2
- package/dist/shader-capture-server.js +14 -14
- package/dist/shader-config-EOFU5D3Y.js +2 -0
- package/dist/{shader-project-runner-FJXPTLUO.js → shader-project-runner-S2AID2RJ.js} +1 -1
- package/dist/{shader-transform-DSFaVrux.d.ts → shader-transform-D160zMyt.d.ts} +3 -0
- package/dist/shader-watch-ISNWIAXN.js +2 -0
- package/dist/shader-workflow-T72N2CLS.js +2 -0
- package/dist/status-D2RF6QTL.js +2 -0
- package/dist/{text-atlas-BHPSDU7C.js → text-atlas-WRYJT3E7.js} +1 -1
- package/dist/transform.cjs +1 -1
- package/dist/transform.d.ts +1 -1
- package/dist/transform.js +1 -1
- package/dist/webpack-loader.cjs +1 -1
- package/dist/webpack-loader.d.ts +1 -1
- package/dist/webpack-loader.js +1 -1
- package/package.json +3 -3
- package/dist/chunk-4M7M55NS.js +0 -93
- package/dist/chunk-5X5NS5EW.js +0 -18
- package/dist/chunk-J6OESAZM.js +0 -76
- package/dist/chunk-NE7SC2BX.js +0 -2
- package/dist/chunk-NEWSG5RX.js +0 -3
- package/dist/chunk-PAH76FDD.js +0 -14
- package/dist/chunk-PY2ZLMZF.cjs +0 -1
- package/dist/chunk-ZDNZCQUQ.js +0 -2
- package/dist/environment-bake-5P4IAL4O.js +0 -4
- package/dist/shader-config-BYBJUL3C.js +0 -2
- package/dist/shader-watch-FVQNE263.js +0 -2
- package/dist/shader-workflow-HZWFWHTS.js +0 -2
- package/dist/status-TV3G3PG4.js +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {b,a as a$3}from'./chunk-
|
|
2
|
+
import {b,a as a$3}from'./chunk-TUIINI6U.js';import'./chunk-76WRV5MZ.js';import'./chunk-JHBQB7WC.js';import'./chunk-LUULHXFK.js';import'./chunk-4YRR36JN.js';import {a as a$2,b as b$1,d}from'./chunk-W6UL2OW7.js';import'./chunk-ZT6T2W4B.js';import'./chunk-NPLE7PPF.js';import {a as a$1}from'./chunk-65VEJRRT.js';import {j,a as a$4,c}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {randomUUID}from'crypto';import {mkdir,realpath,writeFile,rename,rm}from'fs/promises';import F from'path';import {PNG}from'pngjs';var ye="virtual:three-blocks-devtools/browser-smoke",ve=`\0${ye}`,Ke=`/@id/__x00__${ye}`,Be=9e4;async function Ee(){try{let[e,r]=await Promise.all([import('playwright'),import('vite')]);return {chromium:e.chromium,vite:r}}catch(e){throw new Error('Browser smoke and preview require the optional "playwright" and "vite" packages. Install both in the project and run `npx playwright install chromium`.',{cause:e})}}a(Ee,"loadBrowserSmokeTools");function V(e,r,o,t,n){let a=e??n;if(!Number.isSafeInteger(a)||a<o||a>t)throw new Error(`${r} must be an integer in ${o}...${t}.`);return a}a(V,"boundedInteger");function _e(e,r,o,t,n){let a=e??n;if(!Number.isFinite(a)||a<o||a>t)throw new Error(`${r} must be a finite number in ${o}...${t}.`);return a}a(_e,"boundedRatio");function Pe(e){let r=e??"/";if(r.length===0||r.length>2048||/[\u0000-\u001f\u007f]/u.test(r))throw new Error("Browser smoke route must be a bounded project URL.");let o=new URL(r,"http://three-blocks.invalid/");if(o.origin!=="http://three-blocks.invalid"||o.hash.length>0)throw new Error("Browser smoke route must stay within the project and have no fragment.");return `${o.pathname}${o.search}`}a(Pe,"safeRoute");function N(e,r){return e[r]===true}a(N,"booleanField");function $(e,r){if(!a$1(e)||!a$1(e.value))return {source:"missing",backend:"unknown",worker:false,workerReady:false,assetsReady:false,compileEnd:false,textEnabled:r,textReady:!r,firstFrame:false};let o=e.value,t=e.source==="public";if(t&&o.protocolVersion!==1)return {source:"public",backend:"unknown",worker:false,workerReady:false,assetsReady:false,compileEnd:false,textEnabled:r,textReady:!r,firstFrame:false};let n=a$1(o.readiness)?o.readiness:o,a=o.worker,d=t&&a$1(a)?a.offscreenCanvas===true&&a.visible===true:a===true;return {source:t?"public":"legacy",backend:t&&a$1(a)?a.offscreenCanvas===true?"OffscreenCanvas":"MainThread":a===true?"OffscreenCanvas":"unknown",worker:d,workerReady:N(n,"workerReady"),assetsReady:N(n,"assetsReady")||N(n,"loadEnd"),compileEnd:N(n,"compileEnd"),textEnabled:r,textReady:!r||N(n,"textReady"),firstFrame:N(n,"firstFrame")}}a($,"parseBrowserSmokeLifecycle");function ie(e){let r=PNG.sync.read(e),o=Math.floor(r.width*.25),t=Math.floor(r.width*.75),n=Math.floor(r.height*.25),a=Math.floor(r.height*.75),d=0,c=0;for(let f=n;f<a;f+=2)for(let p=o;p<t;p+=2){let h=(f*r.width+p)*4,l=r.data[h],i=r.data[h+1],s=r.data[h+2];l===void 0||i===void 0||s===void 0||(d+=Math.max(l,i,s),c+=1);}return c===0?0:d/c}a(ie,"screenshotLuminance");function Je(){return `
|
|
3
3
|
import * as THREE from 'three/webgpu';
|
|
4
4
|
import { createAssetLoaderRegistry, createAssetManager, createThreeAssetAdapters, defineAssets } from 'three-blocks/assets';
|
|
5
5
|
import { SceneHotReloader } from 'three-blocks/hmr';
|
|
@@ -225,7 +225,7 @@ export async function probe() {
|
|
|
225
225
|
};
|
|
226
226
|
}
|
|
227
227
|
`}a(Je,"browserProbeSource");function Xe(){return {name:"three-blocks:browser-smoke-probe",enforce:"post",resolveId(e){return e===ye?ve:void 0},load(e){return e===ve?Je():void 0}}}a(Xe,"browserProbePlugin");function Te(e){let r={console:[],page:[]};return e.on("console",o=>{o.type()!=="error"||a$2(o.text())||r.console.push(o.text());}),e.on("pageerror",o=>{a$2(o.message)||r.page.push(o.message);}),r}a(Te,"collectPageErrors");async function U(e){return e.evaluate(()=>{let r=globalThis,o=r.__threeBlocksSmoke;if(o!==void 0)return {source:"public",value:o};let t=r.__threeBlocksBrowserTools;if(t&&typeof t=="object"){let n=Reflect.get(t,"smoke");if(n!==void 0)return {source:"public",value:n}}return {source:r.__threeBlocks===void 0?"missing":"legacy",value:r.__threeBlocks??null}})}a(U,"readBridge");async function Ye(e){return e.evaluate(()=>{let r=globalThis,o=r.document.querySelector("[data-tb-fatal-code]"),t=o?.getAttribute("data-tb-fatal-code")??"",n=(o?.title||o?.textContent||"")?.replace(/^three-blocks — error:\s*/u,"").replace(/^Uncaught(?:\s+Error)?:\s*/u,"").trim()??"";return {fatalVisible:o!==null&&/^[a-z][a-z0-9-]{0,63}$/u.test(t)&&r.getComputedStyle(o).display!=="none"&&r.getComputedStyle(o).visibility!=="hidden",code:t.length>0?t:null,detail:n.length>0?n:null}})}a(Ye,"readCompatibilityFailure");async function xe(e){return e.evaluate(()=>{let r=globalThis,o=r.__threeBlocksTextFallbackProbe?.states,t=Array.isArray(o)?o.filter(c=>typeof c=="string").slice(0,32):[],n=t.indexOf("fallback"),a=t.lastIndexOf("ready"),d=[...r.document.querySelectorAll("[data-canvas-text]")];return {states:t,fallbackObserved:n>=0,recovered:n>=0&&a>n,visibleElements:d.filter(c=>c.getAttribute("data-canvas-text-fallback")!=="false").length,totalElements:d.length}})}a(xe,"readTextFallbackEvidence");async function Y(e){return e.evaluate(()=>{let r=globalThis,o=r.__threeBlocksSmoke?.diagnostics?.shaderMode;return {snapshots:Math.max(0,Number(r.__threeBlocksSmoke?.stats?.snapshots)||0),textures:Math.max(0,Number(r.__threeBlocksSmoke?.stats?.textures)||0),shaderMode:o==="precompiled"||o==="live"?o:null,mainPanels:r.document.querySelector("[data-three-blocks-stats-mode]")!==null}})}a(Y,"readBrowserRuntimeObservation");async function Ze(e,r){let o=Buffer.from(`${JSON.stringify(r,null,2)}
|
|
228
|
-
`,"utf8");if(o.byteLength>b)throw new Error(`Runtime status receipt exceeds ${b} bytes.`);let t=F.join(e,...a$3.split("/")),n=F.dirname(t);await mkdir(n,{recursive:true});let a=await realpath(n),d=F.relative(e,a);if(d.startsWith("..")||F.isAbsolute(d))throw new Error("Runtime status receipt directory escapes the project root.");let c=F.join(a,`.status.${process.pid}.${randomUUID()}.tmp`);try{await writeFile(c,o,{flag:"wx",mode:384}),await rename(c,t);}finally{await rm(c,{force:true});}}a(Ze,"writeRuntimeStatusReceipt");async function Z(e,r,o){await e.waitForFunction(t=>{let n=globalThis,a=n.__threeBlocksSmoke,d=a!==void 0;if(a===void 0){let l=n.__threeBlocksBrowserTools;l&&typeof l=="object"&&(a=Reflect.get(l,"smoke")),d=a!==void 0;}if(a===void 0&&(a=n.__threeBlocks),!a||typeof a!="object")return false;let c=a;if(d&&c.protocolVersion!==1)return false;let f=c.readiness&&typeof c.readiness=="object"?c.readiness:c,p=c.worker;return (d&&p&&typeof p=="object"?Reflect.get(p,"offscreenCanvas")===true&&Reflect.get(p,"visible")===true:p===true)&&f.workerReady===true&&(f.assetsReady===true||f.loadEnd===true)&&f.compileEnd===true&&f.firstFrame===true&&(!t||f.textReady===true)},r,{timeout:o});}a(Z,"waitForLifecycle");async function Se(e,r){await e.waitForFunction(()=>{let t=[...globalThis.document.querySelectorAll("[data-canvas-text]")];return t.length>0&&t.every(n=>n.getAttribute("data-canvas-text-fallback")==="true")},void 0,{timeout:Math.min(r,3e4)});}a(Se,"waitForTextFallback");async function de(e,r,o){await r();let t=250,n=performance.now()+Math.min(o,5e3),a$1=performance.now(),d=a(()=>{a$1=performance.now();},"navigated");e.on("framenavigated",d);try{for(;performance.now()-a$1<t;){if(performance.now()>=n)throw new Error("Timed out waiting for startup navigation to settle.");await e.waitForTimeout(25);}}finally{e.off("framenavigated",d);}await r();}a(de,"waitForStableReadiness");async function Re(e,r){return await e(),r()}a(Re,"readAfterInitialReadiness");function Qe(e,r,o){if(!a$1(e)||typeof e.route!="string"||!e.route.startsWith("/")||e.route.length>2048||!Number.isSafeInteger(e.bytes)||Number(e.bytes)<=0||typeof e.contentType!="string"||e.contentType.length>256)throw new Error(`Browser codec ${r} route ${o} is invalid.`);let t=e.route.endsWith(".wasm")?"application/wasm":"javascript";if(!e.contentType.includes(t))throw new Error(`Browser codec route ${e.route} returned unexpected content-type ${JSON.stringify(e.contentType)}.`);return {route:e.route,bytes:Number(e.bytes),contentType:e.contentType}}a(Qe,"parseCodecRoute");function G(e,r,o){if(typeof e!="string"||!r.includes(e))throw new Error(`${o} is invalid.`);return e}a(G,"literal");function le(e,r){if(!Number.isSafeInteger(e)||Number(e)<0)throw new Error(`${r} is invalid.`);return Number(e)}a(le,"nonnegativeInteger");function er(e){if(!a$1(e)||e.schemaVersion!==2||!a$1(e.renderer)||!a$1(e.assets)||!a$1(e.shaders)||!a$1(e.stats)||typeof e.output!="string"||e.output.length===0||e.output.length>2048||typeof e.threeVersion!="string"||e.threeVersion.length===0||e.threeVersion.length>128)throw new Error("Browser build receipt is invalid.");if(e.renderer.owner!=="worker"||e.renderer.api!=="WebGPU"||e.renderer.fallback!=="WebGL")throw new Error("Browser build receipt does not declare the worker-owned WebGPU/WebGL renderer contract.");let r=e.text;if(r!==void 0&&(!a$1(r)||!["ready","generating","fallback","missing","invalid"].includes(String(r.state))))throw new Error("Browser build receipt text state is invalid.");return {schemaVersion:2,renderer:{owner:"worker",api:"WebGPU",fallback:"WebGL"},assets:{draco:G(e.assets.draco,["ready","disabled"],"Browser build receipt Draco state"),ktx2:G(e.assets.ktx2,["ready","disabled"],"Browser build receipt KTX2 state"),meshopt:G(e.assets.meshopt,["lazy","disabled"],"Browser build receipt Meshopt state")},shaders:{state:G(e.shaders.state,["fresh","stale","invalid","missing"],"Browser build receipt shader state"),mode:G(e.shaders.mode,["precompiled","live"],"Browser build receipt shader mode"),pipelines:le(e.shaders.pipelines,"Browser build receipt shader pipeline count")},...r===void 0?{}:{text:{state:G(r.state,["ready","generating","fallback","missing","invalid"],"Browser build receipt text state"),atlases:le(r.atlases,"Browser build receipt text atlas count"),glyphs:le(r.glyphs,"Browser build receipt text glyph count")}},stats:{enabled:e.stats.enabled===true,production:e.stats.production===true},output:e.output,threeVersion:e.threeVersion}}a(er,"parseBuildReceipt");var ce=Object.freeze({sceneIdentityReplaced:false,stateRestored:false,assetIdentityPreserved:false,assetReferencesPreserved:false,statsIdentityPreserved:false,statsSequenceAdvanced:false,shaderInvalidated:false,rollbackPreserved:false}),J=Object.freeze({requested:false,appIdentityStable:false,contentIdentityStable:false,canvasReplaced:false,workerIdentityChanged:false,generationAdvanced:false,restartCountAdvanced:false,stateReplayed:false,readinessRestored:false,shaderModeStable:false,statsSnapshotsAdvanced:false,statsTextureTransferred:false,statsTextureStopped:false,error:null}),rr=Object.freeze(["three-blocks/assets","three-blocks/hmr","three-blocks/runtime","three-blocks/shaders","three-blocks/stats","three-blocks/text","three-blocks/worker"]);function tr(e){if(!a$1(e))throw new Error("Browser HMR evidence is invalid.");let r={...ce};for(let o of Object.keys(r)){if(e[o]!==true)throw new Error(`Browser HMR evidence ${o} did not pass.`);r[o]=true;}return r}a(tr,"parseHmrEvidence");function or(e){if(!a$1(e)||typeof e.textEnabled!="boolean"||!Array.isArray(e.codecs)||e.codecs.length!==3)throw new Error("Browser codec probe returned an invalid payload.");let r=["draco","ktx2","meshopt"],o=e.codecs.map((t,n)=>{let a=r[n];if(a===void 0||!a$1(t)||t.name!==a||!["ready","disabled","error"].includes(String(t.state))||!Array.isArray(t.routes)||t.error!==null&&typeof t.error!="string")throw new Error(`Browser codec probe entry ${n} is invalid.`);let d=t.state,c=t.routes.map((p,h)=>Qe(p,a,h)),f=G(t.evidence,["delivery","decoder-ready","text-atlas-decoded","asset-manager-decoded"],`Browser codec ${a} evidence`);if(typeof t.decoded!="boolean"||t.blocker!==null&&typeof t.blocker!="string")throw new Error(`Browser codec ${a} decode evidence is invalid.`);if(d==="ready"&&a!=="meshopt"&&c.length===0)throw new Error(`Browser codec ${a} exposed no routes.`);if(d==="error"&&(typeof t.error!="string"||t.error.length===0||t.error.length>8192))throw new Error(`Browser codec ${a} has an invalid error.`);return {name:a,state:d,routes:c,decoded:t.decoded,evidence:f,blocker:typeof t.blocker=="string"?t.blocker:null,error:typeof t.error=="string"?t.error:null}});return {textEnabled:e.textEnabled,codecs:o,receipt:er(e.receipt),hmrEvidence:tr(e.hmrEvidence)}}a(or,"parseCodecProbe");async function nr(e){let r=await e.evaluate(async o=>{let t=await import(o);if(typeof t.probe!="function")throw new Error("Browser smoke probe module has no probe() export.");return await t.probe()},Ke);return or(r)}a(nr,"probeCodecs");function ar(e){return e instanceof Error&&/execution context was destroyed|most likely because of a navigation/iu.test(e.message)}a(ar,"isNavigationRace");async function sr(e,r,o){for(let t=0;t<3;t++)try{return await nr(e)}catch(n){if(!ar(n)||t===2)throw n;await de(e,r,o);}throw new Error("Browser codec probe did not complete.")}a(sr,"probeCodecsAfterNavigation");async function ue(e){return e.evaluate(()=>{let r=globalThis,o=0;for(let t of r.document.querySelectorAll("canvas")){if(t.width<=0||t.height<=0)continue;let n=null;try{n=t.getContext("2d");}catch{continue}if(n)try{let a=n.getImageData(0,0,t.width,t.height).data,d=0,c=0;for(let f=0;f+2<a.length;f+=4)d+=Math.max(a[f]??0,a[f+1]??0,a[f+2]??0),c+=1;c>0&&(o=Math.max(o,d/c));}catch{}}return o})}a(ue,"panelLuminance");function lr(e){return e.split(F.sep).join("/")}a(lr,"portablePath");async function ir(e){return e.evaluate(()=>{let o=globalThis.__threeBlocksSmokeProbe;if(!o||typeof o!="object")return 0;let t=Reflect.get(o,"after");return typeof t=="number"&&Number.isSafeInteger(t)?t:0})}a(ir,"hmrEventCount");async function dr(e,r,o,t,n,a,d){if(t===void 0)return {requested:false,module:null,dispatched:false,acknowledged:false,lifecycleStable:true,sourceUnchanged:true,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:null};let c$1=lr(t),f=false,p=false,h=false,l=false;try{let i=await j(o,F.join(o,t),a$4.semanticInput,"HMR scene module"),s=c(i.data),w=e.moduleGraph.getModulesByFile(i.path);if(!w||w.size===0)throw new Error(`HMR scene module ${JSON.stringify(c$1)} is not in Vite's module graph.`);let m=await ir(r);e.watcher.emit("change",i.path),f=!0,await r.waitForFunction(T=>{let y=globalThis.__threeBlocksSmokeProbe;return !!(y&&typeof y=="object"&&Number(Reflect.get(y,"after"))>T)},m,{timeout:Math.min(n,3e4)}),p=!0,await Z(r,a,Math.min(n,3e4)),h=!0;let g=await j(o,i.path,a$4.semanticInput,"HMR scene module");if(l=c(g.data)===s,!l)throw new Error("HMR scene source changed during the smoke run.");return {requested:!0,module:c$1,dispatched:f,acknowledged:p,lifecycleStable:h,sourceUnchanged:l,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:null}}catch(i){return {requested:true,module:c$1,dispatched:f,acknowledged:p,lifecycleStable:h,sourceUnchanged:l,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:i instanceof Error?i.message:String(i)}}}a(dr,"exerciseHmr");async function cr(e,r,o,t){let n="stats-baseline";try{let a=await e.evaluate(()=>{let l=globalThis;return new URL(l.location.href).searchParams.get("tbStats")==="1"});a&&(n="stats-query-boot",await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!0,void 0,{timeout:Math.min(r,3e4)}));let d=await e.evaluate(()=>{let l=globalThis;return {panelVisible:l.__threeBlocksSmoke?.stats?.panelVisible,textures:Number(l.__threeBlocksSmoke?.stats?.textures)||0,panelAttached:l.document.querySelector("[data-three-blocks-stats-mode]")!==null}});if(!a&&(d.panelVisible!==!1||d.textures!==0||d.panelAttached))throw new Error("Generated stats panel is not default-off before browser-smoke activation.");n="stats-enable",await e.evaluate(async()=>{let i=globalThis.__threeBlocksSmoke?.stats;if(!i||typeof i.setPanelVisible!="function"||typeof i.setPanelMode!="function")throw new Error("Generated stats panel controls are unavailable.");if(await Reflect.apply(i.setPanelVisible,i,[!0])!==!0)throw new Error("Generated stats panel could not be enabled.");if(await Reflect.apply(i.setPanelMode,i,["expanded"])!==!0)throw new Error("Generated stats panel could not be expanded.")}),n="stats-expanded",await e.waitForFunction(()=>{let l=globalThis;return l.__threeBlocksSmoke?.stats?.panelVisible===!0&&l.document.querySelector('[data-three-blocks-stats-mode="expanded"]')!==null},void 0,{timeout:Math.min(r,3e4)}),n="stats-initial-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,d.textures,{timeout:Math.min(r,3e4)}),n="snapshot";let c=await e.evaluate(()=>{let l=globalThis,i=l.__threeBlocksSmoke,s=l.document.querySelector("#app"),w=l.document.querySelector("#scene"),m=l.document.querySelector("main")??s;if(!i||typeof i.restartWorker!="function"||!s||!w||!m||typeof i.diagnostics?.workerId!="string")throw new Error("Generated worker restart diagnostics are unavailable.");return l.__threeBlocksWorkerRestartProbe={app:s,content:m,canvas:w},{workerId:i.diagnostics.workerId,generation:i.worker.generation,restartCount:i.restart.count,snapshots:i.stats.snapshots,textures:i.stats.textures}});n="restart-call",await e.evaluate(async()=>{let l=globalThis,i=l.__threeBlocksSmoke?.restartWorker;if(typeof i!="function")throw new Error("Generated restartWorker() is unavailable.");await Reflect.apply(i,l.__threeBlocksSmoke,["browser smoke worker restart"]);}),n="restart-readiness",await e.waitForFunction(l=>{let s=globalThis.__threeBlocksSmoke,w=s?.readiness;return typeof s?.diagnostics?.workerId=="string"&&s.diagnostics.workerId!==l.workerId&&Number(s.worker?.generation)>l.generation&&s.restart?.stateReplayed===!0&&w?.workerReady===!0&&w.assetsReady===!0&&w.compileEnd===!0&&w.firstFrame===!0&&(!l.textEnabled||w.textReady===!0)},{workerId:c.workerId,generation:c.generation,textEnabled:o},{timeout:Math.min(r,45e3)}),n="stats-snapshot",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.snapshots)>l,c.snapshots,{timeout:Math.min(r,3e4)}),n="stats-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,c.textures,{timeout:Math.min(r,3e4)});let f=await e.evaluate(l=>{let i=globalThis,s=i.__threeBlocksSmoke,w=i.__threeBlocksWorkerRestartProbe,m=s?.readiness;if(!s||!w||!m)throw new Error("Generated restart evidence disappeared.");return {requested:!0,appIdentityStable:w.app===i.document.querySelector("#app"),contentIdentityStable:w.content===(i.document.querySelector("main")??i.document.querySelector("#app")),canvasReplaced:s.restart.canvasReplaced&&w.canvas!==i.document.querySelector("#scene"),workerIdentityChanged:typeof s.diagnostics?.workerId=="string"&&s.diagnostics.workerId!==l.workerId,generationAdvanced:s.worker.generation===l.generation+1,restartCountAdvanced:s.restart.count===l.restartCount+1,stateReplayed:s.restart.stateReplayed&&s.restart.lastReason==="browser smoke worker restart",readinessRestored:m.workerReady===!0&&m.assetsReady===!0&&m.compileEnd===!0&&m.firstFrame===!0&&(!l.textEnabled||m.textReady===!0),shaderModeStable:s.diagnostics?.shaderMode===l.expectedShaderMode,statsSnapshotsAdvanced:s.stats.snapshots>l.snapshots,statsTextureTransferred:s.stats.textures>l.textures,statsTextureStopped:!1,error:null}},{...c,textEnabled:o,expectedShaderMode:t});n="stats-disable",await e.evaluate(async()=>{let i=globalThis.__threeBlocksSmoke?.stats;if(!i||typeof i.setPanelVisible!="function")throw new Error("Generated stats visibility control disappeared before disable.");if(await Reflect.apply(i.setPanelVisible,i,[!1])!==!0)throw new Error("Generated stats panel could not be disabled.")}),await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!1,void 0,{timeout:Math.min(r,3e4)}),await e.waitForTimeout(750);let p=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);await e.waitForTimeout(1100);let h=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);if(h!==p)throw new Error(`Stats textures advanced after disable (${p} -> ${h}).`);return {...f,statsTextureStopped:!0}}catch(a){return {...J,requested:true,error:`${n}: ${a instanceof Error?a.message:String(a)}`}}}a(cr,"exerciseWorkerRestart");function D(e){return [...new Set(e)].sort((r,o)=>r.localeCompare(o))}a(D,"sortedUnique");function ur(e,r,o){let t=D(e),n=D(r),a=o?D([...t,...n].filter(c=>/MSDF atlases are missing code points:/iu.test(c))):[],d=new Set(a);return {console:t.filter(c=>!d.has(c)),page:n.filter(c=>!d.has(c)),resolved:a}}a(ur,"classifyRecoveredTextErrors");function mr(e){return e.replace(/\u001b\[[0-?]*[ -/]*[@-~]/gu,"")}a(mr,"stripTerminalControl");function yr(e,r,o){let t=e.config.base.startsWith("/")?e.config.base:"/";return new URL(o.replace(/^\/+/,""),`${r}${t.endsWith("/")?t:`${t}/`}`).href}a(yr,"projectUrl");async function xr(e){let{chromium:r,vite:{createLogger:o,createServer:t}}=await Ee();if(e.forceWebgl===true&&e.unsupportedWorker===true)throw new Error("Browser smoke forceWebgl and unsupportedWorker modes are mutually exclusive.");if(e.unsupportedWorker===true&&e.expectTextGenerationFailure===true)throw new Error("Browser smoke unsupportedWorker and expectTextGenerationFailure modes are mutually exclusive.");let n=await realpath(e.root),a$1=Pe(e.route),d=V(e.timeoutMs,"Browser smoke timeoutMs",1e3,15*6e4,Be),c=V(e.settleMs,"Browser smoke settleMs",0,1e4,1e3),f={width:V(e.viewport?.width,"Browser smoke viewport width",64,8192,1024),height:V(e.viewport?.height,"Browser smoke viewport height",64,8192,640)},p=_e(e.minimumLuminance,"Browser smoke minimumLuminance",0,255,2),h,l,i,s,w=false,m=$(void 0,false),g=[],T=null,z=ce,y={requested:e.hmrModule!==void 0,module:e.hmrModule??null,dispatched:false,acknowledged:false,lifecycleStable:e.hmrModule===void 0,sourceUnchanged:e.hmrModule===void 0,evidenceSource:"public-runtime-browser-probe",evidence:ce,restart:J,error:e.hmrModule===void 0?null:"HMR was not reached."},q=false,B=false,O={fatalVisible:false,code:null,detail:null},E={states:[],fallbackObserved:false,recovered:false,visibleElements:0,totalElements:0},v={snapshots:0,textures:0,shaderMode:null,mainPanels:false},A=[],I=0,L=0,P={console:[],page:[]},j,K=process.env.PATH;process.env.PATH=[F.join(n,"node_modules",".bin"),K].filter(Boolean).join(F.delimiter);try{let k=o("silent");k.warn=H=>{A.push(mr(H));},h=await t({root:n,logLevel:"silent",customLogger:k,plugins:[Xe()],optimizeDeps:{force:!0,include:[...rr]},server:{host:"127.0.0.1",port:0,strictPort:!1}}),await h.listen();let x=h.httpServer?.address();if(!x||typeof x=="string")throw new Error("Vite did not expose an ephemeral TCP address.");let R=`http://127.0.0.1:${x.port}`;l=await r.launch({headless:c$1(e.headed===!0),args:[...b$1()]}),i=await l.newContext({viewport:f}),await i.addInitScript({content:`
|
|
228
|
+
`,"utf8");if(o.byteLength>b)throw new Error(`Runtime status receipt exceeds ${b} bytes.`);let t=F.join(e,...a$3.split("/")),n=F.dirname(t);await mkdir(n,{recursive:true});let a=await realpath(n),d=F.relative(e,a);if(d.startsWith("..")||F.isAbsolute(d))throw new Error("Runtime status receipt directory escapes the project root.");let c=F.join(a,`.status.${process.pid}.${randomUUID()}.tmp`);try{await writeFile(c,o,{flag:"wx",mode:384}),await rename(c,t);}finally{await rm(c,{force:true});}}a(Ze,"writeRuntimeStatusReceipt");async function Z(e,r,o){await e.waitForFunction(t=>{let n=globalThis,a=n.__threeBlocksSmoke,d=a!==void 0;if(a===void 0){let l=n.__threeBlocksBrowserTools;l&&typeof l=="object"&&(a=Reflect.get(l,"smoke")),d=a!==void 0;}if(a===void 0&&(a=n.__threeBlocks),!a||typeof a!="object")return false;let c=a;if(d&&c.protocolVersion!==1)return false;let f=c.readiness&&typeof c.readiness=="object"?c.readiness:c,p=c.worker;return (d&&p&&typeof p=="object"?Reflect.get(p,"offscreenCanvas")===true&&Reflect.get(p,"visible")===true:p===true)&&f.workerReady===true&&(f.assetsReady===true||f.loadEnd===true)&&f.compileEnd===true&&f.firstFrame===true&&(!t||f.textReady===true)},r,{timeout:o});}a(Z,"waitForLifecycle");async function Se(e,r){await e.waitForFunction(()=>{let t=[...globalThis.document.querySelectorAll("[data-canvas-text]")];return t.length>0&&t.every(n=>n.getAttribute("data-canvas-text-fallback")==="true")},void 0,{timeout:Math.min(r,3e4)});}a(Se,"waitForTextFallback");async function de(e,r,o){await r();let t=250,n=performance.now()+Math.min(o,5e3),a$1=performance.now(),d=a(()=>{a$1=performance.now();},"navigated");e.on("framenavigated",d);try{for(;performance.now()-a$1<t;){if(performance.now()>=n)throw new Error("Timed out waiting for startup navigation to settle.");await e.waitForTimeout(25);}}finally{e.off("framenavigated",d);}await r();}a(de,"waitForStableReadiness");async function Re(e,r){return await e(),r()}a(Re,"readAfterInitialReadiness");function Qe(e,r,o){if(!a$1(e)||typeof e.route!="string"||!e.route.startsWith("/")||e.route.length>2048||!Number.isSafeInteger(e.bytes)||Number(e.bytes)<=0||typeof e.contentType!="string"||e.contentType.length>256)throw new Error(`Browser codec ${r} route ${o} is invalid.`);let t=e.route.endsWith(".wasm")?"application/wasm":"javascript";if(!e.contentType.includes(t))throw new Error(`Browser codec route ${e.route} returned unexpected content-type ${JSON.stringify(e.contentType)}.`);return {route:e.route,bytes:Number(e.bytes),contentType:e.contentType}}a(Qe,"parseCodecRoute");function G(e,r,o){if(typeof e!="string"||!r.includes(e))throw new Error(`${o} is invalid.`);return e}a(G,"literal");function le(e,r){if(!Number.isSafeInteger(e)||Number(e)<0)throw new Error(`${r} is invalid.`);return Number(e)}a(le,"nonnegativeInteger");function er(e){if(!a$1(e)||e.schemaVersion!==2||!a$1(e.renderer)||!a$1(e.assets)||!a$1(e.shaders)||!a$1(e.stats)||typeof e.output!="string"||e.output.length===0||e.output.length>2048||typeof e.threeVersion!="string"||e.threeVersion.length===0||e.threeVersion.length>128)throw new Error("Browser build receipt is invalid.");if(e.renderer.owner!=="worker"||e.renderer.api!=="WebGPU"||e.renderer.fallback!=="WebGL")throw new Error("Browser build receipt does not declare the worker-owned WebGPU/WebGL renderer contract.");let r=e.text;if(r!==void 0&&(!a$1(r)||!["ready","generating","fallback","missing","invalid"].includes(String(r.state))))throw new Error("Browser build receipt text state is invalid.");return {schemaVersion:2,renderer:{owner:"worker",api:"WebGPU",fallback:"WebGL"},assets:{draco:G(e.assets.draco,["ready","disabled"],"Browser build receipt Draco state"),ktx2:G(e.assets.ktx2,["ready","disabled"],"Browser build receipt KTX2 state"),meshopt:G(e.assets.meshopt,["lazy","disabled"],"Browser build receipt Meshopt state")},shaders:{state:G(e.shaders.state,["fresh","stale","invalid","missing"],"Browser build receipt shader state"),mode:G(e.shaders.mode,["precompiled","live"],"Browser build receipt shader mode"),pipelines:le(e.shaders.pipelines,"Browser build receipt shader pipeline count")},...r===void 0?{}:{text:{state:G(r.state,["ready","generating","fallback","missing","invalid"],"Browser build receipt text state"),atlases:le(r.atlases,"Browser build receipt text atlas count"),glyphs:le(r.glyphs,"Browser build receipt text glyph count")}},stats:{enabled:e.stats.enabled===true,production:e.stats.production===true},output:e.output,threeVersion:e.threeVersion}}a(er,"parseBuildReceipt");var ce=Object.freeze({sceneIdentityReplaced:false,stateRestored:false,assetIdentityPreserved:false,assetReferencesPreserved:false,statsIdentityPreserved:false,statsSequenceAdvanced:false,shaderInvalidated:false,rollbackPreserved:false}),J=Object.freeze({requested:false,appIdentityStable:false,contentIdentityStable:false,canvasReplaced:false,workerIdentityChanged:false,generationAdvanced:false,restartCountAdvanced:false,stateReplayed:false,readinessRestored:false,shaderModeStable:false,statsSnapshotsAdvanced:false,statsTextureTransferred:false,statsTextureStopped:false,error:null}),rr=Object.freeze(["three-blocks/assets","three-blocks/hmr","three-blocks/runtime","three-blocks/shaders","three-blocks/stats","three-blocks/text","three-blocks/worker"]);function tr(e){if(!a$1(e))throw new Error("Browser HMR evidence is invalid.");let r={...ce};for(let o of Object.keys(r)){if(e[o]!==true)throw new Error(`Browser HMR evidence ${o} did not pass.`);r[o]=true;}return r}a(tr,"parseHmrEvidence");function or(e){if(!a$1(e)||typeof e.textEnabled!="boolean"||!Array.isArray(e.codecs)||e.codecs.length!==3)throw new Error("Browser codec probe returned an invalid payload.");let r=["draco","ktx2","meshopt"],o=e.codecs.map((t,n)=>{let a=r[n];if(a===void 0||!a$1(t)||t.name!==a||!["ready","disabled","error"].includes(String(t.state))||!Array.isArray(t.routes)||t.error!==null&&typeof t.error!="string")throw new Error(`Browser codec probe entry ${n} is invalid.`);let d=t.state,c=t.routes.map((p,h)=>Qe(p,a,h)),f=G(t.evidence,["delivery","decoder-ready","text-atlas-decoded","asset-manager-decoded"],`Browser codec ${a} evidence`);if(typeof t.decoded!="boolean"||t.blocker!==null&&typeof t.blocker!="string")throw new Error(`Browser codec ${a} decode evidence is invalid.`);if(d==="ready"&&a!=="meshopt"&&c.length===0)throw new Error(`Browser codec ${a} exposed no routes.`);if(d==="error"&&(typeof t.error!="string"||t.error.length===0||t.error.length>8192))throw new Error(`Browser codec ${a} has an invalid error.`);return {name:a,state:d,routes:c,decoded:t.decoded,evidence:f,blocker:typeof t.blocker=="string"?t.blocker:null,error:typeof t.error=="string"?t.error:null}});return {textEnabled:e.textEnabled,codecs:o,receipt:er(e.receipt),hmrEvidence:tr(e.hmrEvidence)}}a(or,"parseCodecProbe");async function nr(e){let r=await e.evaluate(async o=>{let t=await import(o);if(typeof t.probe!="function")throw new Error("Browser smoke probe module has no probe() export.");return await t.probe()},Ke);return or(r)}a(nr,"probeCodecs");function ar(e){return e instanceof Error&&/execution context was destroyed|most likely because of a navigation/iu.test(e.message)}a(ar,"isNavigationRace");async function sr(e,r,o){for(let t=0;t<3;t++)try{return await nr(e)}catch(n){if(!ar(n)||t===2)throw n;await de(e,r,o);}throw new Error("Browser codec probe did not complete.")}a(sr,"probeCodecsAfterNavigation");async function ue(e){return e.evaluate(()=>{let r=globalThis,o=0;for(let t of r.document.querySelectorAll("canvas")){if(t.width<=0||t.height<=0)continue;let n=null;try{n=t.getContext("2d");}catch{continue}if(n)try{let a=n.getImageData(0,0,t.width,t.height).data,d=0,c=0;for(let f=0;f+2<a.length;f+=4)d+=Math.max(a[f]??0,a[f+1]??0,a[f+2]??0),c+=1;c>0&&(o=Math.max(o,d/c));}catch{}}return o})}a(ue,"panelLuminance");function lr(e){return e.split(F.sep).join("/")}a(lr,"portablePath");async function ir(e){return e.evaluate(()=>{let o=globalThis.__threeBlocksSmokeProbe;if(!o||typeof o!="object")return 0;let t=Reflect.get(o,"after");return typeof t=="number"&&Number.isSafeInteger(t)?t:0})}a(ir,"hmrEventCount");async function dr(e,r,o,t,n,a,d){if(t===void 0)return {requested:false,module:null,dispatched:false,acknowledged:false,lifecycleStable:true,sourceUnchanged:true,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:null};let c$1=lr(t),f=false,p=false,h=false,l=false;try{let i=await j(o,F.join(o,t),a$4.semanticInput,"HMR scene module"),s=c(i.data),w=e.moduleGraph.getModulesByFile(i.path);if(!w||w.size===0)throw new Error(`HMR scene module ${JSON.stringify(c$1)} is not in Vite's module graph.`);let m=await ir(r);e.watcher.emit("change",i.path),f=!0,await r.waitForFunction(T=>{let y=globalThis.__threeBlocksSmokeProbe;return !!(y&&typeof y=="object"&&Number(Reflect.get(y,"after"))>T)},m,{timeout:Math.min(n,3e4)}),p=!0,await Z(r,a,Math.min(n,3e4)),h=!0;let g=await j(o,i.path,a$4.semanticInput,"HMR scene module");if(l=c(g.data)===s,!l)throw new Error("HMR scene source changed during the smoke run.");return {requested:!0,module:c$1,dispatched:f,acknowledged:p,lifecycleStable:h,sourceUnchanged:l,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:null}}catch(i){return {requested:true,module:c$1,dispatched:f,acknowledged:p,lifecycleStable:h,sourceUnchanged:l,evidenceSource:"public-runtime-browser-probe",evidence:d,restart:J,error:i instanceof Error?i.message:String(i)}}}a(dr,"exerciseHmr");async function cr(e,r,o,t){let n="stats-baseline";try{let a=await e.evaluate(()=>{let l=globalThis;return new URL(l.location.href).searchParams.get("tbStats")==="1"});a&&(n="stats-query-boot",await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!0,void 0,{timeout:Math.min(r,3e4)}));let d=await e.evaluate(()=>{let l=globalThis;return {panelVisible:l.__threeBlocksSmoke?.stats?.panelVisible,textures:Number(l.__threeBlocksSmoke?.stats?.textures)||0,panelAttached:l.document.querySelector("[data-three-blocks-stats-mode]")!==null}});if(!a&&(d.panelVisible!==!1||d.textures!==0||d.panelAttached))throw new Error("Generated stats panel is not default-off before browser-smoke activation.");n="stats-enable",await e.evaluate(async()=>{let i=globalThis.__threeBlocksSmoke?.stats;if(!i||typeof i.setPanelVisible!="function"||typeof i.setPanelMode!="function")throw new Error("Generated stats panel controls are unavailable.");if(await Reflect.apply(i.setPanelVisible,i,[!0])!==!0)throw new Error("Generated stats panel could not be enabled.");if(await Reflect.apply(i.setPanelMode,i,["expanded"])!==!0)throw new Error("Generated stats panel could not be expanded.")}),n="stats-expanded",await e.waitForFunction(()=>{let l=globalThis;return l.__threeBlocksSmoke?.stats?.panelVisible===!0&&l.document.querySelector('[data-three-blocks-stats-mode="expanded"]')!==null},void 0,{timeout:Math.min(r,3e4)}),n="stats-initial-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,d.textures,{timeout:Math.min(r,3e4)}),n="snapshot";let c=await e.evaluate(()=>{let l=globalThis,i=l.__threeBlocksSmoke,s=l.document.querySelector("#app"),w=l.document.querySelector("#scene"),m=l.document.querySelector("main")??s;if(!i||typeof i.restartWorker!="function"||!s||!w||!m||typeof i.diagnostics?.workerId!="string")throw new Error("Generated worker restart diagnostics are unavailable.");return l.__threeBlocksWorkerRestartProbe={app:s,content:m,canvas:w},{workerId:i.diagnostics.workerId,generation:i.worker.generation,restartCount:i.restart.count,snapshots:i.stats.snapshots,textures:i.stats.textures}});n="restart-call",await e.evaluate(async()=>{let l=globalThis,i=l.__threeBlocksSmoke?.restartWorker;if(typeof i!="function")throw new Error("Generated restartWorker() is unavailable.");await Reflect.apply(i,l.__threeBlocksSmoke,["browser smoke worker restart"]);}),n="restart-readiness",await e.waitForFunction(l=>{let s=globalThis.__threeBlocksSmoke,w=s?.readiness;return typeof s?.diagnostics?.workerId=="string"&&s.diagnostics.workerId!==l.workerId&&Number(s.worker?.generation)>l.generation&&s.restart?.stateReplayed===!0&&w?.workerReady===!0&&w.assetsReady===!0&&w.compileEnd===!0&&w.firstFrame===!0&&(!l.textEnabled||w.textReady===!0)},{workerId:c.workerId,generation:c.generation,textEnabled:o},{timeout:Math.min(r,45e3)}),n="stats-snapshot",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.snapshots)>l,c.snapshots,{timeout:Math.min(r,3e4)}),n="stats-texture",await e.waitForFunction(l=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)>l,c.textures,{timeout:Math.min(r,3e4)});let f=await e.evaluate(l=>{let i=globalThis,s=i.__threeBlocksSmoke,w=i.__threeBlocksWorkerRestartProbe,m=s?.readiness;if(!s||!w||!m)throw new Error("Generated restart evidence disappeared.");return {requested:!0,appIdentityStable:w.app===i.document.querySelector("#app"),contentIdentityStable:w.content===(i.document.querySelector("main")??i.document.querySelector("#app")),canvasReplaced:s.restart.canvasReplaced&&w.canvas!==i.document.querySelector("#scene"),workerIdentityChanged:typeof s.diagnostics?.workerId=="string"&&s.diagnostics.workerId!==l.workerId,generationAdvanced:s.worker.generation===l.generation+1,restartCountAdvanced:s.restart.count===l.restartCount+1,stateReplayed:s.restart.stateReplayed&&s.restart.lastReason==="browser smoke worker restart",readinessRestored:m.workerReady===!0&&m.assetsReady===!0&&m.compileEnd===!0&&m.firstFrame===!0&&(!l.textEnabled||m.textReady===!0),shaderModeStable:s.diagnostics?.shaderMode===l.expectedShaderMode,statsSnapshotsAdvanced:s.stats.snapshots>l.snapshots,statsTextureTransferred:s.stats.textures>l.textures,statsTextureStopped:!1,error:null}},{...c,textEnabled:o,expectedShaderMode:t});n="stats-disable",await e.evaluate(async()=>{let i=globalThis.__threeBlocksSmoke?.stats;if(!i||typeof i.setPanelVisible!="function")throw new Error("Generated stats visibility control disappeared before disable.");if(await Reflect.apply(i.setPanelVisible,i,[!1])!==!0)throw new Error("Generated stats panel could not be disabled.")}),await e.waitForFunction(()=>globalThis.__threeBlocksSmoke?.stats?.panelVisible===!1,void 0,{timeout:Math.min(r,3e4)}),await e.waitForTimeout(750);let p=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);await e.waitForTimeout(1100);let h=await e.evaluate(()=>Number(globalThis.__threeBlocksSmoke?.stats?.textures)||0);if(h!==p)throw new Error(`Stats textures advanced after disable (${p} -> ${h}).`);return {...f,statsTextureStopped:!0}}catch(a){return {...J,requested:true,error:`${n}: ${a instanceof Error?a.message:String(a)}`}}}a(cr,"exerciseWorkerRestart");function D(e){return [...new Set(e)].sort((r,o)=>r.localeCompare(o))}a(D,"sortedUnique");function ur(e,r,o){let t=D(e),n=D(r),a=o?D([...t,...n].filter(c=>/MSDF atlases are missing code points:/iu.test(c))):[],d=new Set(a);return {console:t.filter(c=>!d.has(c)),page:n.filter(c=>!d.has(c)),resolved:a}}a(ur,"classifyRecoveredTextErrors");function mr(e){return e.replace(/\u001b\[[0-?]*[ -/]*[@-~]/gu,"")}a(mr,"stripTerminalControl");function yr(e,r,o){let t=e.config.base.startsWith("/")?e.config.base:"/";return new URL(o.replace(/^\/+/,""),`${r}${t.endsWith("/")?t:`${t}/`}`).href}a(yr,"projectUrl");async function xr(e){let{chromium:r,vite:{createLogger:o,createServer:t}}=await Ee();if(e.forceWebgl===true&&e.unsupportedWorker===true)throw new Error("Browser smoke forceWebgl and unsupportedWorker modes are mutually exclusive.");if(e.unsupportedWorker===true&&e.expectTextGenerationFailure===true)throw new Error("Browser smoke unsupportedWorker and expectTextGenerationFailure modes are mutually exclusive.");let n=await realpath(e.root),a$1=Pe(e.route),d$1=V(e.timeoutMs,"Browser smoke timeoutMs",1e3,15*6e4,Be),c=V(e.settleMs,"Browser smoke settleMs",0,1e4,1e3),f={width:V(e.viewport?.width,"Browser smoke viewport width",64,8192,1024),height:V(e.viewport?.height,"Browser smoke viewport height",64,8192,640)},p=_e(e.minimumLuminance,"Browser smoke minimumLuminance",0,255,2),h,l,i,s,w=false,m=$(void 0,false),g=[],T=null,z=ce,y={requested:e.hmrModule!==void 0,module:e.hmrModule??null,dispatched:false,acknowledged:false,lifecycleStable:e.hmrModule===void 0,sourceUnchanged:e.hmrModule===void 0,evidenceSource:"public-runtime-browser-probe",evidence:ce,restart:J,error:e.hmrModule===void 0?null:"HMR was not reached."},q=false,B=false,O={fatalVisible:false,code:null,detail:null},E={states:[],fallbackObserved:false,recovered:false,visibleElements:0,totalElements:0},v={snapshots:0,textures:0,shaderMode:null,mainPanels:false},A=[],I=0,L=0,P={console:[],page:[]},j,K=process.env.PATH;process.env.PATH=[F.join(n,"node_modules",".bin"),K].filter(Boolean).join(F.delimiter);try{let k=o("silent");k.warn=H=>{A.push(mr(H));},h=await t({root:n,logLevel:"silent",customLogger:k,plugins:[Xe()],optimizeDeps:{force:!0,include:[...rr]},server:{host:"127.0.0.1",port:0,strictPort:!1}}),await h.listen();let x=h.httpServer?.address();if(!x||typeof x=="string")throw new Error("Vite did not expose an ephemeral TCP address.");let R=`http://127.0.0.1:${x.port}`;l=await r.launch({headless:d(e.headed===!0),args:[...b$1()]}),i=await l.newContext({viewport:f}),await i.addInitScript({content:`
|
|
229
229
|
(() => {
|
|
230
230
|
const key = '__three-blocks-text-fallback-states-v1';
|
|
231
231
|
let states = [];
|
|
@@ -249,6 +249,6 @@ export async function probe() {
|
|
|
249
249
|
}
|
|
250
250
|
} ).observe( document, { subtree: true, childList: true, attributes: true, attributeFilter: [ 'data-three-blocks-text-state' ] } );
|
|
251
251
|
})();
|
|
252
|
-
`}),e.forceWebgl===!0&&await i.addInitScript(()=>{Object.defineProperty(Navigator.prototype,"gpu",{configurable:!0,value:void 0});}),e.unsupportedWorker===!0&&await i.addInitScript(()=>{Object.defineProperty(globalThis,"Worker",{configurable:!0,value:void 0});}),s=await i.newPage();let C=s;if(j=Te(s),s.on("console",H=>{/WebGPU is not available, running under WebGL2 backend/iu.test(H.text())&&(B=!0);}),await s.goto(yr(h,R,a$1),{waitUntil:"domcontentloaded",timeout:d}),e.unsupportedWorker===!0)q=await Re(async()=>{await de(C,a(async()=>{await C.waitForFunction(()=>globalThis.document.querySelector("#three-blocks-dev-overlay")?.shadowRoot?.querySelector(".dot")?.dataset.tone==="error",void 0,{timeout:Math.min(d,15e3)});},"waitForFailure"),d);},()=>C.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0)),O=await Ye(s),m=$(await U(s),!1);else {let H=a(()=>e.expectTextGenerationFailure===!0?Se(C,d):Z(C,!1,d),"initialReadiness");q=await Re(()=>de(C,H,d),()=>C.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0));let _=await sr(s,H,d);if(w=_.textEnabled,g=_.codecs,T=_.receipt,z=_.hmrEvidence,e.expectTextGenerationFailure===!0){if(!_.textEnabled)throw new Error("Expected text-generation failure mode requires a text-enabled project.");await Se(s,d);let W=performance.now()+Math.min(d,3e4);for(;!A.some(je=>/automatic atlas generation failed/iu.test(je));){if(performance.now()>=W)throw new Error("Timed out waiting for the automatic text-generation failure warning.");await s.waitForTimeout(50);}m=$(await U(s),!0);}else if(await Z(s,_.textEnabled,d),m=$(await U(s),_.textEnabled),_.textEnabled&&m.textReady&&(g=g.map(W=>W.name==="ktx2"?{...W,decoded:!0,evidence:"text-atlas-decoded",blocker:null}:W)),y=await dr(h,s,n,e.hmrModule,d,_.textEnabled,z),e.hmrModule!==void 0){let W=await cr(s,d,_.textEnabled,_.receipt.shaders.mode);y={...y,restart:W},m=$(await U(s),_.textEnabled);}}c>0&&await s.waitForTimeout(c),E=await xe(s),v=await Y(s);let Oe=await s.screenshot({type:"png"});I=ie(Oe),L=await ue(s);}catch(k){if(s!==void 0)try{m=$(await U(s),w),E=await xe(s),v=await Y(s);let x=await s.screenshot({type:"png"});I=ie(x),L=await ue(s);}catch(x){P.page.push(`Failure diagnostics could not be captured: ${x instanceof Error?x.message:String(x)}`);}P.page.push(k instanceof Error?k.message:String(k));}finally{j!==void 0&&(P.console.push(...j.console),P.page.push(...j.page)),await i?.close().catch(R=>{P.page.push(`Browser context cleanup failed: ${R instanceof Error?R.message:String(R)}`);}),await l?.close().catch(R=>{P.page.push(`Browser cleanup failed: ${R instanceof Error?R.message:String(R)}`);});let k=h?.httpServer,x=k?Reflect.get(k,"closeAllConnections"):void 0;k&&typeof x=="function"&&Reflect.apply(x,k,[]),await h?.close().catch(R=>{P.page.push(`Vite cleanup failed: ${R instanceof Error?R.message:String(R)}`);}),K===void 0?delete process.env.PATH:process.env.PATH=K;}let X=Number(I.toFixed(2)),M=Number(L.toFixed(2)),fe=I<=p&&L<=p,Q=ur(P.console,P.page,E.recovered),pe=Q.console,we=Q.page,Me=Q.resolved,he=m.worker&&m.workerReady&&m.assetsReady&&m.compileEnd&&m.textReady&&m.firstFrame,Ce=g.length===3&&g.every(k=>k.state!=="error"),Fe=Object.values(y.evidence).every(Boolean),Ae=!y.restart.requested||y.restart.error===null&&[y.restart.appIdentityStable,y.restart.contentIdentityStable,y.restart.canvasReplaced,y.restart.workerIdentityChanged,y.restart.generationAdvanced,y.restart.restartCountAdvanced,y.restart.stateReplayed,y.restart.readinessRestored,y.restart.shaderModeStable,y.restart.statsSnapshotsAdvanced,y.restart.statsTextureTransferred,y.restart.statsTextureStopped].every(Boolean),be=!y.requested||y.dispatched&&y.acknowledged&&y.lifecycleStable&&y.sourceUnchanged&&Fe&&Ae&&y.error===null,ke=A.filter(k=>/automatic atlas generation failed/iu.test(k)),$e=ke.reduce((k,x)=>k+(x.match(/three-blocks text generate/gu)?.length??0),0),Ie=e.expectTextGenerationFailure===true&&w&&E.fallbackObserved&&!E.recovered&&E.totalElements>0&&E.visibleElements===E.totalElements&&ke.length===1&&$e===1,Le=e.unsupportedWorker===true&&O.fatalVisible&&O.code==="render-worker-unavailable"&&!m.workerReady&&!m.compileEnd&&!m.firstFrame,We=e.unsupportedWorker===true?"unsupported-worker":e.forceWebgl===true?"WebGL-fallback":"WebGPU-first",Ve=e.unsupportedWorker===true?"none":he?e.forceWebgl===true||!q?"WebGL":"WebGPU":"unknown",qe=m.workerReady&&m.compileEnd&&m.firstFrame,b={schemaVersion:1,command:"browser smoke",passed:e.unsupportedWorker===true?Le:e.expectTextGenerationFailure===true?Ie:he&&Ce&&be&&!fe&&pe.length===0&&we.length===0,scene:a$1,lifecycle:m,renderer:{requested:We,active:Ve,navigatorGpu:q,workerOwned:qe,fallbackDiagnostic:B},compatibility:{...O,silentMainThreadRenderer:e.unsupportedWorker===true&&(m.compileEnd||m.firstFrame)},receipt:T,textFallback:E,warnings:D(A),rendering:{luminance:X,panelLuminance:M,threshold:p,blackFrame:fe},codecs:g,hmr:y,errors:{console:pe,page:we,resolved:Me}};if(b.passed&&e.unsupportedWorker!==true&&e.expectTextGenerationFailure!==true){if(b.receipt===null||b.lifecycle.backend==="unknown"||b.renderer.active!=="WebGPU"&&b.renderer.active!=="WebGL")throw new Error("A successful browser smoke cannot write runtime status without an observed backend and renderer/build receipt.");let k=b.hmr.requested,x=k?be:null,R={schemaVersion:1,observedAt:new Date().toISOString(),worker:{backend:b.lifecycle.backend,renderer:b.renderer.active,protocolVersion:1},assets:{codecs:b.codecs.map(C=>({name:C.name,available:C.state==="ready",decoded:C.decoded})),resources:0},hmr:{capabilities:{scene:true,component:true,assetManifest:true,workerRestart:true},outcome:{attempted:k,succeeded:x,rollbackPreserved:k?b.hmr.evidence.rollbackPreserved:null,workerRestarted:b.hmr.restart.requested&&b.hmr.restart.workerIdentityChanged}},stats:{snapshots:v.snapshots,textures:v.textures,workerProfiler:v.snapshots>0,mainPanels:v.mainPanels},lifecycle:{state:"first frame",workerReady:b.lifecycle.workerReady,assetsReady:b.lifecycle.assetsReady,compiled:b.lifecycle.compileEnd,firstFrame:b.lifecycle.firstFrame},shaders:{mode:v.shaderMode??b.receipt.shaders.mode,pipelines:b.receipt.shaders.pipelines},...b.receipt.text===void 0?{}:{text:{state:b.receipt.text.state,atlases:b.receipt.text.atlases,glyphs:b.receipt.text.glyphs,requiredGlyphs:b.receipt.text.glyphs}},error:null};await Ze(n,R);}return b}a(xr,"runBrowserSmoke");function Sr(e){let r=e.lifecycle,o=[`${e.passed?"\u2713":"\u2717"} Browser ${e.scene} \xB7 worker ${r.worker&&r.workerReady?"ready":"failed"} \xB7 assets ${r.assetsReady?"ready":"failed"} \xB7 compile ${r.compileEnd?"ready":"failed"}`,` Renderer ${e.renderer.active} \xB7 ${e.renderer.workerOwned?"worker-owned":e.renderer.requested}`,` Frame ${e.rendering.luminance.toFixed(2)} \xB7 panel ${e.rendering.panelLuminance.toFixed(2)}${e.rendering.blackFrame?" \xB7 black":""}`,` Codecs ${e.codecs.map(t=>`${t.name} ${t.state}${t.decoded?" decoded":""}`).join(" \xB7 ")||"not observed"}`];e.compatibility.fatalVisible&&o.push(` Compatibility ${e.compatibility.detail??"fatal compatibility screen visible"}`),e.textFallback.states.length>0&&o.push(` Text ${e.textFallback.states.join(" \u2192 ")}`),e.hmr.requested&&o.push(` HMR ${e.hmr.acknowledged&&e.hmr.sourceUnchanged&&Object.values(e.hmr.evidence).every(Boolean)?"ready":"failed"} \xB7 ${e.hmr.module??"unknown module"}`),e.hmr.restart.requested&&o.push(` Restart ${e.hmr.restart.error===null&&e.hmr.restart.workerIdentityChanged&&e.hmr.restart.stateReplayed?"ready":"failed"} \xB7 worker/state/stats`);for(let t of e.warnings)o.push(` Warning ${t}`);for(let t of e.errors.console)o.push(` Console ${t}`);for(let t of e.errors.page)o.push(` Page ${t}`);for(let t of e.errors.resolved)o.push(` Recovered ${t}`);e.hmr.error&&o.push(` HMR error ${e.hmr.error}`),e.hmr.restart.error&&o.push(` Restart error ${e.hmr.restart.error}`);for(let t of e.codecs)t.error&&o.push(` ${t.name} error ${t.error}`);return o.join(`
|
|
253
|
-
`)}a(Sr,"formatBrowserSmokeReport");async function Rr(e){let{chromium:r,vite:{build:o,preview:t}}=await Ee(),n=await realpath(e.root),a=(e.routes===void 0||e.routes.length===0?["/"]:e.routes).map(Pe),d=V(e.timeoutMs,"Browser preview timeoutMs",1e3,15*6e4,Be),c=V(e.settleMs,"Browser preview settleMs",0,1e4,500),f={width:V(e.viewport?.width,"Browser preview viewport width",64,8192,1024),height:V(e.viewport?.height,"Browser preview viewport height",64,8192,640)},p=_e(e.minimumLuminance,"Browser preview minimumLuminance",0,255,2),h=e.expectShaders??"precompiled",l=e.text===true,i=[],s,w,m=process.env.PATH;process.env.PATH=[F.join(n,"node_modules",".bin"),m].filter(Boolean).join(F.delimiter);try{await o({root:n,logLevel:"warn",...e.buildMode===void 0?{}:{mode:e.buildMode}}),s=await t({root:n,logLevel:"warn",preview:{host:"127.0.0.1",port:0,strictPort:!1,open:!1}});let g=s.httpServer?.address();if(!g||typeof g=="string")throw new Error("Vite preview did not expose an ephemeral TCP address.");let T=s.config.base.startsWith("/")?s.config.base:"/",z=`http://127.0.0.1:${g.port}${T.endsWith("/")?T:`${T}/`}`;w=await r.launch({headless:
|
|
252
|
+
`}),e.forceWebgl===!0&&await i.addInitScript(()=>{Object.defineProperty(Navigator.prototype,"gpu",{configurable:!0,value:void 0});}),e.unsupportedWorker===!0&&await i.addInitScript(()=>{Object.defineProperty(globalThis,"Worker",{configurable:!0,value:void 0});}),s=await i.newPage();let C=s;if(j=Te(s),s.on("console",H=>{/WebGPU is not available, running under WebGL2 backend/iu.test(H.text())&&(B=!0);}),await s.goto(yr(h,R,a$1),{waitUntil:"domcontentloaded",timeout:d$1}),e.unsupportedWorker===!0)q=await Re(async()=>{await de(C,a(async()=>{await C.waitForFunction(()=>globalThis.document.querySelector("#three-blocks-dev-overlay")?.shadowRoot?.querySelector(".dot")?.dataset.tone==="error",void 0,{timeout:Math.min(d$1,15e3)});},"waitForFailure"),d$1);},()=>C.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0)),O=await Ye(s),m=$(await U(s),!1);else {let H=a(()=>e.expectTextGenerationFailure===!0?Se(C,d$1):Z(C,!1,d$1),"initialReadiness");q=await Re(()=>de(C,H,d$1),()=>C.evaluate(()=>"gpu"in navigator&&navigator.gpu!==void 0));let _=await sr(s,H,d$1);if(w=_.textEnabled,g=_.codecs,T=_.receipt,z=_.hmrEvidence,e.expectTextGenerationFailure===!0){if(!_.textEnabled)throw new Error("Expected text-generation failure mode requires a text-enabled project.");await Se(s,d$1);let W=performance.now()+Math.min(d$1,3e4);for(;!A.some(je=>/automatic atlas generation failed/iu.test(je));){if(performance.now()>=W)throw new Error("Timed out waiting for the automatic text-generation failure warning.");await s.waitForTimeout(50);}m=$(await U(s),!0);}else if(await Z(s,_.textEnabled,d$1),m=$(await U(s),_.textEnabled),_.textEnabled&&m.textReady&&(g=g.map(W=>W.name==="ktx2"?{...W,decoded:!0,evidence:"text-atlas-decoded",blocker:null}:W)),y=await dr(h,s,n,e.hmrModule,d$1,_.textEnabled,z),e.hmrModule!==void 0){let W=await cr(s,d$1,_.textEnabled,_.receipt.shaders.mode);y={...y,restart:W},m=$(await U(s),_.textEnabled);}}c>0&&await s.waitForTimeout(c),E=await xe(s),v=await Y(s);let Oe=await s.screenshot({type:"png"});I=ie(Oe),L=await ue(s);}catch(k){if(s!==void 0)try{m=$(await U(s),w),E=await xe(s),v=await Y(s);let x=await s.screenshot({type:"png"});I=ie(x),L=await ue(s);}catch(x){P.page.push(`Failure diagnostics could not be captured: ${x instanceof Error?x.message:String(x)}`);}P.page.push(k instanceof Error?k.message:String(k));}finally{j!==void 0&&(P.console.push(...j.console),P.page.push(...j.page)),await i?.close().catch(R=>{P.page.push(`Browser context cleanup failed: ${R instanceof Error?R.message:String(R)}`);}),await l?.close().catch(R=>{P.page.push(`Browser cleanup failed: ${R instanceof Error?R.message:String(R)}`);});let k=h?.httpServer,x=k?Reflect.get(k,"closeAllConnections"):void 0;k&&typeof x=="function"&&Reflect.apply(x,k,[]),await h?.close().catch(R=>{P.page.push(`Vite cleanup failed: ${R instanceof Error?R.message:String(R)}`);}),K===void 0?delete process.env.PATH:process.env.PATH=K;}let X=Number(I.toFixed(2)),M=Number(L.toFixed(2)),fe=I<=p&&L<=p,Q=ur(P.console,P.page,E.recovered),pe=Q.console,we=Q.page,Me=Q.resolved,he=m.worker&&m.workerReady&&m.assetsReady&&m.compileEnd&&m.textReady&&m.firstFrame,Ce=g.length===3&&g.every(k=>k.state!=="error"),Fe=Object.values(y.evidence).every(Boolean),Ae=!y.restart.requested||y.restart.error===null&&[y.restart.appIdentityStable,y.restart.contentIdentityStable,y.restart.canvasReplaced,y.restart.workerIdentityChanged,y.restart.generationAdvanced,y.restart.restartCountAdvanced,y.restart.stateReplayed,y.restart.readinessRestored,y.restart.shaderModeStable,y.restart.statsSnapshotsAdvanced,y.restart.statsTextureTransferred,y.restart.statsTextureStopped].every(Boolean),be=!y.requested||y.dispatched&&y.acknowledged&&y.lifecycleStable&&y.sourceUnchanged&&Fe&&Ae&&y.error===null,ke=A.filter(k=>/automatic atlas generation failed/iu.test(k)),$e=ke.reduce((k,x)=>k+(x.match(/three-blocks text generate/gu)?.length??0),0),Ie=e.expectTextGenerationFailure===true&&w&&E.fallbackObserved&&!E.recovered&&E.totalElements>0&&E.visibleElements===E.totalElements&&ke.length===1&&$e===1,Le=e.unsupportedWorker===true&&O.fatalVisible&&O.code==="render-worker-unavailable"&&!m.workerReady&&!m.compileEnd&&!m.firstFrame,We=e.unsupportedWorker===true?"unsupported-worker":e.forceWebgl===true?"WebGL-fallback":"WebGPU-first",Ve=e.unsupportedWorker===true?"none":he?e.forceWebgl===true||!q?"WebGL":"WebGPU":"unknown",qe=m.workerReady&&m.compileEnd&&m.firstFrame,b={schemaVersion:1,command:"browser smoke",passed:e.unsupportedWorker===true?Le:e.expectTextGenerationFailure===true?Ie:he&&Ce&&be&&!fe&&pe.length===0&&we.length===0,scene:a$1,lifecycle:m,renderer:{requested:We,active:Ve,navigatorGpu:q,workerOwned:qe,fallbackDiagnostic:B},compatibility:{...O,silentMainThreadRenderer:e.unsupportedWorker===true&&(m.compileEnd||m.firstFrame)},receipt:T,textFallback:E,warnings:D(A),rendering:{luminance:X,panelLuminance:M,threshold:p,blackFrame:fe},codecs:g,hmr:y,errors:{console:pe,page:we,resolved:Me}};if(b.passed&&e.unsupportedWorker!==true&&e.expectTextGenerationFailure!==true){if(b.receipt===null||b.lifecycle.backend==="unknown"||b.renderer.active!=="WebGPU"&&b.renderer.active!=="WebGL")throw new Error("A successful browser smoke cannot write runtime status without an observed backend and renderer/build receipt.");let k=b.hmr.requested,x=k?be:null,R={schemaVersion:1,observedAt:new Date().toISOString(),worker:{backend:b.lifecycle.backend,renderer:b.renderer.active,protocolVersion:1},assets:{codecs:b.codecs.map(C=>({name:C.name,available:C.state==="ready",decoded:C.decoded})),resources:0},hmr:{capabilities:{scene:true,component:true,assetManifest:true,workerRestart:true},outcome:{attempted:k,succeeded:x,rollbackPreserved:k?b.hmr.evidence.rollbackPreserved:null,workerRestarted:b.hmr.restart.requested&&b.hmr.restart.workerIdentityChanged}},stats:{snapshots:v.snapshots,textures:v.textures,workerProfiler:v.snapshots>0,mainPanels:v.mainPanels},lifecycle:{state:"first frame",workerReady:b.lifecycle.workerReady,assetsReady:b.lifecycle.assetsReady,compiled:b.lifecycle.compileEnd,firstFrame:b.lifecycle.firstFrame},shaders:{mode:v.shaderMode??b.receipt.shaders.mode,pipelines:b.receipt.shaders.pipelines},...b.receipt.text===void 0?{}:{text:{state:b.receipt.text.state,atlases:b.receipt.text.atlases,glyphs:b.receipt.text.glyphs,requiredGlyphs:b.receipt.text.glyphs}},error:null};await Ze(n,R);}return b}a(xr,"runBrowserSmoke");function Sr(e){let r=e.lifecycle,o=[`${e.passed?"\u2713":"\u2717"} Browser ${e.scene} \xB7 worker ${r.worker&&r.workerReady?"ready":"failed"} \xB7 assets ${r.assetsReady?"ready":"failed"} \xB7 compile ${r.compileEnd?"ready":"failed"}`,` Renderer ${e.renderer.active} \xB7 ${e.renderer.workerOwned?"worker-owned":e.renderer.requested}`,` Frame ${e.rendering.luminance.toFixed(2)} \xB7 panel ${e.rendering.panelLuminance.toFixed(2)}${e.rendering.blackFrame?" \xB7 black":""}`,` Codecs ${e.codecs.map(t=>`${t.name} ${t.state}${t.decoded?" decoded":""}`).join(" \xB7 ")||"not observed"}`];e.compatibility.fatalVisible&&o.push(` Compatibility ${e.compatibility.detail??"fatal compatibility screen visible"}`),e.textFallback.states.length>0&&o.push(` Text ${e.textFallback.states.join(" \u2192 ")}`),e.hmr.requested&&o.push(` HMR ${e.hmr.acknowledged&&e.hmr.sourceUnchanged&&Object.values(e.hmr.evidence).every(Boolean)?"ready":"failed"} \xB7 ${e.hmr.module??"unknown module"}`),e.hmr.restart.requested&&o.push(` Restart ${e.hmr.restart.error===null&&e.hmr.restart.workerIdentityChanged&&e.hmr.restart.stateReplayed?"ready":"failed"} \xB7 worker/state/stats`);for(let t of e.warnings)o.push(` Warning ${t}`);for(let t of e.errors.console)o.push(` Console ${t}`);for(let t of e.errors.page)o.push(` Page ${t}`);for(let t of e.errors.resolved)o.push(` Recovered ${t}`);e.hmr.error&&o.push(` HMR error ${e.hmr.error}`),e.hmr.restart.error&&o.push(` Restart error ${e.hmr.restart.error}`);for(let t of e.codecs)t.error&&o.push(` ${t.name} error ${t.error}`);return o.join(`
|
|
253
|
+
`)}a(Sr,"formatBrowserSmokeReport");async function Rr(e){let{chromium:r,vite:{build:o,preview:t}}=await Ee(),n=await realpath(e.root),a=(e.routes===void 0||e.routes.length===0?["/"]:e.routes).map(Pe),d$1=V(e.timeoutMs,"Browser preview timeoutMs",1e3,15*6e4,Be),c=V(e.settleMs,"Browser preview settleMs",0,1e4,500),f={width:V(e.viewport?.width,"Browser preview viewport width",64,8192,1024),height:V(e.viewport?.height,"Browser preview viewport height",64,8192,640)},p=_e(e.minimumLuminance,"Browser preview minimumLuminance",0,255,2),h=e.expectShaders??"precompiled",l=e.text===true,i=[],s,w,m=process.env.PATH;process.env.PATH=[F.join(n,"node_modules",".bin"),m].filter(Boolean).join(F.delimiter);try{await o({root:n,logLevel:"warn",...e.buildMode===void 0?{}:{mode:e.buildMode}}),s=await t({root:n,logLevel:"warn",preview:{host:"127.0.0.1",port:0,strictPort:!1,open:!1}});let g=s.httpServer?.address();if(!g||typeof g=="string")throw new Error("Vite preview did not expose an ephemeral TCP address.");let T=s.config.base.startsWith("/")?s.config.base:"/",z=`http://127.0.0.1:${g.port}${T.endsWith("/")?T:`${T}/`}`;w=await r.launch({headless:d(e.headed===!0),args:[...b$1()]});for(let y of a){let q=await w.newContext({viewport:f}),B=await q.newPage(),O=Te(B),E=[],v=$(void 0,l),A=null,I=0,L=0;try{await B.goto(new URL(y.replace(/^\/+/,""),z).href,{waitUntil:"domcontentloaded",timeout:d$1}),await Z(B,l,d$1),c>0&&await B.waitForTimeout(c),v=$(await U(B),l),A=(await Y(B)).shaderMode;let M=await B.screenshot({type:"png"});I=ie(M),L=await ue(B);}catch(M){try{v=$(await U(B),l),A=(await Y(B)).shaderMode;}catch{}E.push(M instanceof Error?M.message:String(M));}finally{await q.close().catch(M=>{E.push(`Browser context cleanup failed: ${M instanceof Error?M.message:String(M)}`);});}let P=D(O.console),j=D([...O.page,...E]),K=v.worker&&v.workerReady&&v.assetsReady&&v.compileEnd&&v.textReady&&v.firstFrame,X=I<=p&&L<=p;i.push({route:y,passed:K&&!X&&A===h&&P.length===0&&j.length===0,lifecycle:v,shaderMode:A,rendering:{luminance:Number(I.toFixed(2)),panelLuminance:Number(L.toFixed(2)),threshold:p,blackFrame:X},errors:{console:P,page:j}});}}finally{await w?.close().catch(()=>{});let g=s?.httpServer,T=g?Reflect.get(g,"closeAllConnections"):void 0;g&&typeof T=="function"&&Reflect.apply(T,g,[]),await s?.close().catch(()=>{}),m===void 0?delete process.env.PATH:process.env.PATH=m;}return {schemaVersion:1,command:"browser preview",passed:i.length>0&&i.every(g=>g.passed),buildMode:e.buildMode??null,expectShaders:h,routes:i}}a(Rr,"runBrowserPreview");function Br(e){let r=[`${e.passed?"\u2713":"\u2717"} Preview production build${e.buildMode===null?"":` \xB7 --mode ${e.buildMode}`} \xB7 expects shaders ${e.expectShaders}`];for(let o of e.routes){let t=o.lifecycle;r.push(` ${o.passed?"\u2713":"\u2717"} ${o.route} \xB7 worker ${t.worker&&t.workerReady?"ready":"failed"} \xB7 compile ${t.compileEnd?"ready":"failed"} \xB7 shaders ${o.shaderMode??"unobserved"} \xB7 frame ${o.rendering.luminance.toFixed(2)}${o.rendering.blackFrame?" \xB7 black":""}`);for(let n of o.errors.console)r.push(` Console ${n}`);for(let n of o.errors.page)r.push(` Page ${n}`);}return r.join(`
|
|
254
254
|
`)}a(Br,"formatBrowserPreviewReport");export{rr as BROWSER_SMOKE_OPTIMIZE_DEPENDENCIES,ur as classifyRecoveredTextErrors,Br as formatBrowserPreviewReport,Sr as formatBrowserSmokeReport,$ as parseBrowserSmokeLifecycle,Re as readAfterInitialReadiness,Rr as runBrowserPreview,xr as runBrowserSmoke,ie as screenshotLuminance};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {c,b as b$1,d}from'./chunk-W6UL2OW7.js';import {a as a$3}from'./chunk-ZT6T2W4B.js';import {e as e$1,g}from'./chunk-NPLE7PPF.js';import {a as a$2,c as c$2}from'./chunk-65VEJRRT.js';import {a as a$1,c as c$1,d as d$1,f,e,i,j,k}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import D from'process';import {createServer}from'http';import {createRequire}from'module';import {mkdtemp,rm,lstat,readFile,unlink,mkdir,readdir,realpath}from'fs/promises';import b from'path';import {tmpdir}from'os';import {pathToFileURL}from'url';import {THREE_WEBGL_R185_COMPATIBILITY,THREE_WEBGPU_R185_COMPATIBILITY,THREE_R186DEV_VERSION,THREE_WEBGPU_R186DEV_COMPATIBILITY,parsePrecompiledManifest,SHADER_HYDRATION_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_ADDRESS_SCHEMA_VERSION,PRECOMPILED_MANIFEST_VERSION}from'three-blocks/shaders';import {transformThreeWebgpuProviderHooks,transformThreeWebgpuCaptureInstrumentation}from'three-blocks/vite';function x(r,e="webgpu"){if(/^0\.185\./u.test(r))return e==="webgl"?THREE_WEBGL_R185_COMPATIBILITY:THREE_WEBGPU_R185_COMPATIBILITY;if(r===THREE_R186DEV_VERSION&&e==="webgpu")return THREE_WEBGPU_R186DEV_COMPATIBILITY;throw new Error(`Three.js ${r} is outside the supported shader compatibility contracts.`)}a(x,"shaderCompatibilityForThree");var F=60,qe="timing.local.json",ze="timing.json",we="parity.json",ne=4096,_r=4096;function fe(r,e,t=8192){if(typeof r!="string"||r.length===0||r.length>t||/[\u0000\u007f]/u.test(r))throw new Error(`${e} must be a bounded non-empty string.`);return r}a(fe,"boundedString");function R(r,e,t=true){if(typeof r!="number"||!Number.isFinite(r)||r<0||t&&!Number.isSafeInteger(r))throw new Error(`${e} must be a non-negative ${t?"integer":"finite number"}.`);return r}a(R,"nonNegativeNumber");function Mr(r){if(!a$2(r))throw new Error("Shader capture stats are missing.");let e={buildCalls:R(r.buildCalls,"capture stats.buildCalls"),renderBuilds:R(r.renderBuilds,"capture stats.renderBuilds"),computeBuilds:R(r.computeBuilds,"capture stats.computeBuilds"),registeredBuilds:R(r.registeredBuilds,"capture stats.registeredBuilds"),registeredRenderBuilds:R(r.registeredRenderBuilds,"capture stats.registeredRenderBuilds"),registeredComputeBuilds:R(r.registeredComputeBuilds,"capture stats.registeredComputeBuilds"),buildMs:R(r.buildMs,"capture stats.buildMs",false),syncBuildMs:R(r.syncBuildMs,"capture stats.syncBuildMs",false),asyncBuildElapsedMs:R(r.asyncBuildElapsedMs,"capture stats.asyncBuildElapsedMs",false),precompiledSetupMs:R(r.precompiledSetupMs,"capture stats.precompiledSetupMs",false),maxSyncBuildMs:R(r.maxSyncBuildMs??r.syncBuildMs,"capture stats.maxSyncBuildMs",false),maxPrecompiledSetupMs:R(r.maxPrecompiledSetupMs??r.precompiledSetupMs,"capture stats.maxPrecompiledSetupMs",false),hydrationMs:R(r.hydrationMs??0,"capture stats.hydrationMs",false),maxHydrationMs:R(r.maxHydrationMs??r.hydrationMs??0,"capture stats.maxHydrationMs",false),injected:R(r.injected,"capture stats.injected"),injectedRender:R(r.injectedRender,"capture stats.injectedRender"),injectedCompute:R(r.injectedCompute,"capture stats.injectedCompute"),missed:R(r.missed,"capture stats.missed"),missedRender:R(r.missedRender,"capture stats.missedRender"),missedCompute:R(r.missedCompute,"capture stats.missedCompute"),...Array.isArray(r.missedKeys)&&r.missedKeys.every(t=>typeof t=="string")?{missedKeys:r.missedKeys.slice(0,ne)}:{}};if(e.renderBuilds+e.computeBuilds!==e.buildCalls||e.registeredRenderBuilds+e.registeredComputeBuilds!==e.registeredBuilds||e.injectedRender+e.injectedCompute!==e.injected||e.missedRender+e.missedCompute!==e.missed||e.registeredBuilds>e.buildCalls||Math.abs(e.syncBuildMs+e.asyncBuildElapsedMs-e.buildMs)>.001||e.maxSyncBuildMs>e.syncBuildMs+.001||e.maxPrecompiledSetupMs>e.precompiledSetupMs+.001||e.maxHydrationMs>e.hydrationMs+.001)throw new Error("Shader capture stats totals are inconsistent.");return e}a(Mr,"captureStats");function xr(r){if(!Array.isArray(r)||r.length>ne)throw new Error("Shader capture skipped builds are invalid.");return r.map((e,t)=>{if(!a$2(e)||e.kind!=="render"&&e.kind!=="compute")throw new Error(`Shader capture skipped build ${t} is invalid.`);return {kind:e.kind,name:fe(e.name,`skipped build ${t} name`,512),reason:fe(e.reason,`skipped build ${t} reason`)}})}a(xr,"skippedBuilds");function Ar(r){let e=0,t=0,n=0,i=0;for(let s of Object.values(r.entries)){let a=r.states[s];a!==void 0&&((a.vertex!==null||a.fragment!==null)&&e++,a.vertex!==null&&t++,a.fragment!==null&&n++,a.compute!==null&&i++);}return {render:e,vertex:t,fragment:n,compute:i}}a(Ar,"shaderCoverage");function vt(r,e){if(!a$2(r))throw new Error("Shader capture payload must be an object.");if(r.scene!==e.scene)throw new Error(`Shader capture scene does not match "${e.scene}".`);if(r.protocolVersion!==2)throw new Error("Shader capture protocolVersion must be 2.");let t=e.backend??"webgpu",n=x(e.runtime.three,t);if(r.compatibility!==n)throw new Error(`Shader capture compatibility must be "${n}".`);if(!a$2(r.entries))throw new Error("Shader capture entries must be an object.");if(typeof r.requiresSetup!="boolean")throw new Error("Shader capture requiresSetup must be boolean.");let i=Object.keys(r.entries).length;if(i>ne)throw new Error(`Shader capture must contain at most ${ne} entries.`);if(!Array.isArray(r.errors)||r.errors.length>_r)throw new Error("Shader capture errors are invalid.");let s=r.errors.map((S,l)=>fe(S,`capture error ${l}`,64*1024));if(s.length>0)throw new Error(`Shader capture failed:
|
|
3
|
+
- ${s.join(`
|
|
4
|
+
- `)}`);let a=xr(r.skipped);if(i===0&&(t!=="webgl"||a.length===0))throw new Error("Shader capture must contain an entry unless WebGL explicitly skipped every live build.");let o=Mr(r.stats),c=a$2(r.timing)?r.timing:void 0,m=c===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(S=>{let l=c[S];if(l===void 0)return [];if(typeof l!="number"||!Number.isFinite(l)||l<0)throw new Error(`Shader capture timing.${S} is invalid.`);return [[S,l]]})),p;if(r.provenance!==void 0){if(!a$2(r.provenance)||typeof r.provenance.userAgent!="string"||r.provenance.userAgent.length>1024||typeof r.provenance.adapter!="string"||r.provenance.adapter.length>1024||!Array.isArray(r.provenance.features)||r.provenance.features.length>256||!r.provenance.features.every(S=>typeof S=="string"&&S.length<=128))throw new Error("Shader capture provenance is invalid.");p={userAgent:r.provenance.userAgent,adapter:r.provenance.adapter,features:[...new Set(r.provenance.features)].sort()};}let y=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:e.scene,three:e.runtime.three,threeBlocks:e.runtime.threeBlocks,runtime:{id:n,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...r.automatic===void 0?{}:{automatic:r.automatic},requiresSetup:r.requiresSetup,modules:r.modules,nodes:r.nodes,layouts:r.layouts,attributePlans:r.attributePlans,updatePlans:r.updatePlans,requirementPlans:r.requirementPlans,states:r.states,entries:r.entries,...r.fallbacks===void 0?{}:{fallbacks:r.fallbacks}}),h=Ar(y);if(o.registeredRenderBuilds<h.render||o.registeredComputeBuilds<h.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:e.scene,backend:t,manifest:y,skipped:a,stats:o,coverage:h,...m===void 0?{}:{timing:m},...p===void 0?{}:{provenance:p}}}a(vt,"validateShaderCapture");function O(r,e=0){let t=" ".repeat(e),n=" ".repeat(e+1);if(Array.isArray(r))return r.length===0?"[]":r.every(s=>s===null||["number","string","boolean"].includes(typeof s))?JSON.stringify(r):`[
|
|
5
|
+
${r.map(s=>`${n}${O(s,e+1)}`).join(`,
|
|
6
|
+
`)}
|
|
7
|
+
${t}]`;if(r!==null&&typeof r=="object"){let s=r,a=Object.keys(s).sort();return a.length===0?"{}":`{
|
|
8
|
+
${a.map(o=>{let c=s[o];return `${n}${JSON.stringify(o)}: ${O(c,e+1)}`}).join(`,
|
|
9
|
+
`)}
|
|
10
|
+
${t}}`}let i=JSON.stringify(r);if(i===void 0)throw new Error("Shader artifact contains a non-serializable value.");return i}a(O,"stableStringify");function jr(r){return ["// GENERATED FILE \u2014 do not edit by hand.","// Produced by @three-blocks/devtools.","import type { PrecompiledManifest } from 'three-blocks/shaders';","",`export default ${O(r)} satisfies PrecompiledManifest;`,""].join(`
|
|
11
|
+
`)}a(jr,"serializeShaderManifest");function Fe(r,e){if(typeof r!="string"||r.length===0||r.length>256||/[\u0000-\u001f\u007f]/u.test(r))throw new Error(`${e} is invalid.`);return r}a(Fe,"timingLabel");function ye(r){if(!a$2(r)||r.schemaVersion!==3||r.source!=="latest-local-capture"&&r.source!=="committed-capture"||typeof r.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(r.receiptHash)||typeof r.measuredAt!="string"||!Number.isFinite(Date.parse(r.measuredAt))||!a$2(r.scenes))throw new Error("Shader timing is invalid.");let e={};for(let[n,i]of Object.entries(r.scenes)){if(n.length===0||n.length>128||!a$2(i))throw new Error("Shader timing scene is invalid.");let s={builds:R(i.builds,`timing ${n}.builds`),setupMeasured:i.setupMeasured===true,liveBuildMs:R(i.liveBuildMs,`timing ${n}.liveBuildMs`,false),precompiledBuildMs:R(i.precompiledBuildMs,`timing ${n}.precompiledBuildMs`,false),avoidedBuildMs:R(i.avoidedBuildMs,`timing ${n}.avoidedBuildMs`,false),runs:R(i.runs,`timing ${n}.runs`),spreadMs:R(i.spreadMs,`timing ${n}.spreadMs`,false)};if(s.runs<1)throw new Error(`Shader timing runs are invalid for scene "${n}".`);if(Math.abs(s.avoidedBuildMs-Math.max(0,s.liveBuildMs-s.precompiledBuildMs))>.001)throw new Error(`Shader timing delta is inconsistent for scene "${n}".`);e[n]=s;}if(Object.keys(e).length===0)throw new Error("Shader timing contains no scenes.");let t={schemaVersion:3,receiptHash:r.receiptHash,measuredAt:r.measuredAt,scenes:e};return r.source==="latest-local-capture"?{...t,source:"latest-local-capture"}:{...t,source:"committed-capture",adapter:Fe(r.adapter,"Shader timing adapter"),platform:Fe(r.platform,"Shader timing platform")}}a(ye,"parseShaderTiming");function ie(r){return /^[a-z0-9][a-z0-9_-]{0,63}(?:\.webgl)?$/u.test(r)}a(ie,"validParityScene");function He(r){return typeof r=="string"&&Number.isFinite(Date.parse(r))}a(He,"validParityTimestamp");function Se(r){if(!a$2(r))throw new Error("Shader parity evidence is invalid.");if(r.schemaVersion===1){if(typeof r.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(r.receiptHash)||!He(r.verifiedAt)||!Array.isArray(r.scenes)||r.scenes.length===0||r.scenes.length>64||!r.scenes.every(n=>typeof n=="string"&&ie(n)))throw new Error("Shader parity evidence is invalid.");return {schemaVersion:1,receiptHash:r.receiptHash,verifiedAt:r.verifiedAt,scenes:[...new Set(r.scenes)].sort()}}if(r.schemaVersion!==2||!a$2(r.scenes))throw new Error("Shader parity evidence is invalid.");let e=Object.entries(r.scenes);if(e.length===0||e.length>64)throw new Error("Shader parity evidence is invalid.");let t={};for(let[n,i]of e.sort(([s],[a])=>s.localeCompare(a))){if(!ie(n)||!a$2(i)||typeof i.fingerprint!="string"||!/^[a-f0-9]{64}$/u.test(i.fingerprint)||!He(i.verifiedAt))throw new Error("Shader parity evidence is invalid.");t[n]={fingerprint:i.fingerprint,verifiedAt:i.verifiedAt};}return {schemaVersion:2,scenes:t}}a(Se,"parseShaderParityEvidence");function ge(r,e){let t=r.scenes[e];if(t===void 0)throw new Error(`Shader receipt has no scene "${e}" for parity evidence.`);return c$1(O({runtime:{three:r.runtime.three,threeBlocks:r.runtime.threeBlocks,threeBlocksShaderClosure:r.runtime.threeBlocksShaderClosure},...r.tool===void 0?{}:{tool:r.tool},scene:t}))}a(ge,"shaderSceneParityFingerprint");async function Ue(r,e,t,n){let i=b.join(r,t);try{if(!await d$1(i))return;let s=await lstat(i);if(s.isSymbolicLink()||!s.isFile()||s.size>1024*1024)return;let a=ye(JSON.parse(await readFile(i,"utf8")));return a.source===n&&a.receiptHash===c$1(e)?a:void 0}catch{return}}a(Ue,"readShaderTimingFile");async function Tt(r,e){return await Ue(r,e,qe,"latest-local-capture")??await Ue(r,e,ze,"committed-capture")}a(Tt,"readShaderTiming");async function Ye(r,e){let t=b.join(r,we);try{if(!await d$1(t))return;let n=await lstat(t);if(n.isSymbolicLink()||!n.isFile()||n.size>1024*1024)return;let i=Se(JSON.parse(await readFile(t,"utf8"))),s=c$2(JSON.parse(Buffer.from(e).toString("utf8"))),a={};if(i.schemaVersion===1){if(i.receiptHash!==c$1(e))return;for(let o of i.scenes)s.scenes[o]!==void 0&&(a[o]={fingerprint:ge(s,o),verifiedAt:i.verifiedAt});}else for(let[o,c]of Object.entries(i.scenes))s.scenes[o]===void 0||c.fingerprint!==ge(s,o)||(a[o]=c);return Object.keys(a).length===0?void 0:{schemaVersion:2,scenes:a}}catch{return}}a(Ye,"readShaderParityEvidence");async function Qe(r,e,t){let n=await ae(r),i=b.join(n,"meta.json"),s=await lstat(i);if(s.isSymbolicLink()||!s.isFile())throw new Error("Shader receipt must be a regular file before timing.");let a=await readFile(i),o=new Date().toISOString(),c=Object.fromEntries(Object.entries(e).sort(([y],[h])=>y.localeCompare(h))),m=ye({schemaVersion:3,receiptHash:c$1(a),measuredAt:o,source:"latest-local-capture",scenes:c});if(await f(b.join(n,qe),`${O(m)}
|
|
12
|
+
`),t===void 0)return {local:m};let p=ye({schemaVersion:3,receiptHash:c$1(a),measuredAt:o,source:"committed-capture",adapter:t.adapter,platform:t.platform,scenes:c});return await f(b.join(n,ze),`${O(p)}
|
|
13
|
+
`),{local:m,committed:p}}a(Qe,"writeShaderTimings");async function Pt(r,e){return (await Qe(r,e)).local}a(Pt,"writeShaderLocalTiming");async function kt(r,e,t){if(e.length===0||e.length>64||e.some(h=>!ie(h)))throw new Error("Shader parity evidence must contain 1...64 valid scene keys.");let n=await ae(r),i=b.join(n,"meta.json"),s=await lstat(i);if(s.isSymbolicLink()||!s.isFile())throw new Error("Shader receipt must be a regular file before parity evidence.");let a=await readFile(i);if(t!==void 0&&c$1(a)!==c$1(t))throw new Error("Shader receipt changed during browser parity verification; completed observations were not attached to the new receipt.");let o=c$2(JSON.parse(a.toString("utf8"))),c=await Ye(n,a),m=new Date().toISOString(),p={...c?.scenes};for(let h of [...new Set(e)].sort())p[h]={fingerprint:ge(o,h),verifiedAt:m};let y=Se({schemaVersion:2,scenes:p});return await f(b.join(n,we),`${O(y)}
|
|
14
|
+
`),y}a(kt,"writeShaderParityEvidence");async function Ct(r,e,t){if(e.length===0||e.length>64||e.some(p=>!ie(p)))throw new Error("Shader parity invalidation must contain 1...64 valid scene keys.");let n=await ae(r),i=await readFile(b.join(n,"meta.json"));if(c$1(i)!==c$1(t))throw new Error("Shader receipt changed before prior parity evidence could be invalidated.");let s=await Ye(n,i);if(s===void 0)return;let a=new Set(e),o=Object.fromEntries(Object.entries(s.scenes).filter(([p])=>!a.has(p))),c=b.join(n,we);if(Object.keys(o).length===0){await unlink(c).catch(p=>{if(!a$2(p)||p.code!=="ENOENT")throw p});return}let m=Se({schemaVersion:2,scenes:o});await f(c,`${O(m)}
|
|
15
|
+
`);}a(Ct,"removeShaderParityEvidence");async function Bt(r,e,t){let n=await Qe(r,e,t);if(n.committed===void 0)throw new Error("Committed shader timing was not written.");return {local:n.local,committed:n.committed}}a(Bt,"writeShaderTimingTwins");async function Ve(r){if(!await d$1(r)){await mkdir(r);return}let e=await lstat(r);if(e.isSymbolicLink()||!e.isDirectory())throw new Error(`Shader artifact path is not a real directory: ${r}.`)}a(Ve,"assertDirectory");async function ae(r){let e=b.resolve(r),t=b.join(e,".three-blocks");await Ve(t);let n=b.join(t,"shaders");return await Ve(n),n}a(ae,"artifactRoot");async function _t(r){let e$2=await ae(r.root),t=r.backends??["webgpu"],n=Object.fromEntries(t.map(l=>[l,x(r.runtime.three,l)])),i$1=b.resolve(r.root),s=b.resolve(i$1,r.publicDirectory??"public");if(!e(i$1,s)||s===i$1)throw new Error("Shader public directory must stay inside the project root.");let a=b.join(s,"three-blocks","shaders");await mkdir(a,{recursive:true}),await i(i$1,a,"Shader static-asset directory");let o={},c=[];for(let l of [...r.scenes].sort((u,g)=>u.key.localeCompare(g.key))){let u=r.inputs.get(l.key);if(u===void 0)throw new Error(`Shader input matrix is missing scene "${l.key}".`);for(let g$1 of e$1(l,t)){let f$1=g(l.key,g$1),w=r.captures.get(f$1);if(w===void 0){let P=r.previousReceipt?.scenes[f$1];if(P===void 0)continue;let J=await readFile(b.join(e$2,P.artifact));if(c$1(J)!==P.artifactHash)throw new Error(`Preserved shader artifact checksum differs for "${f$1}".`);if(P.asset!==void 0&&P.assetHash!==void 0){let K=await readFile(b.join(s,P.asset));if(c$1(K)!==P.assetHash)throw new Error(`Preserved static shader manifest checksum differs for "${f$1}".`)}o[f$1]={...P,backend:g$1,inputs:Object.fromEntries(Object.entries(u).sort(([K],[j])=>K.localeCompare(j)))},c.push(P.artifact),P.asset!==void 0&&c.push(b.relative(i$1,b.join(s,P.asset)).split(b.sep).join("/"));continue}if(w.scene!==l.key||w.backend!==g$1||w.manifest.scene!==l.key)throw new Error(`Capture matrix scene/backend "${f$1}" is inconsistent.`);let v=`${l.key}.${g$1}.ts`,E=jr(w.manifest);await f(b.join(e$2,v),E),c.push(v);let k=`three-blocks/shaders/${l.key}.${g$1}.json`,A=`${O(w.manifest)}
|
|
16
|
+
`;await f(b.join(s,k),A),c.push(b.relative(i$1,b.join(s,k)).split(b.sep).join("/"));let B=w.skipped.filter(P=>P.kind==="render").length,_=w.skipped.length-B;o[f$1]={backend:g$1,artifact:v,artifactHash:c$1(E),asset:k,assetHash:c$1(A),inputs:Object.fromEntries(Object.entries(u).sort(([P],[J])=>P.localeCompare(J))),coverage:w.coverage,bytes:Buffer.byteLength(E),skipped:{render:B,compute:_}};}}let m=[...r.captures.values()].find(l=>l.provenance!==void 0)?.provenance??r.previousReceipt?.runtime.capture,p={schemaVersion:2,runtime:{...r.runtime,...m===void 0?{}:{capture:m}},tool:{name:"@three-blocks/devtools",version:a$3,compatibility:n[t[0]??"webgpu"],compatibilities:n,transform:F,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},scenes:o},y=new Set(c);for(let l of await readdir(e$2,{withFileTypes:true}))if(!(!/\.(?:webgpu|webgl)\.ts$/u.test(l.name)||y.has(l.name))){if(l.isSymbolicLink()||!l.isFile())throw new Error(`Orphan shader artifact is not a regular file: ${l.name}.`);await unlink(b.join(e$2,l.name));}let h=new Set(r.scenes.flatMap(l=>e$1(l,t).map(u=>`${l.key}.${u}.json`))),S=new Set(Object.values(r.previousReceipt?.scenes??{}).map(l=>l.asset===void 0?void 0:b.posix.basename(l.asset)).filter(l=>l!==void 0));try{let l=c$2(JSON.parse(await readFile(b.join(e$2,"meta.json"),"utf8")));for(let u of Object.values(l.scenes))u.asset!==void 0&&S.add(b.posix.basename(u.asset));}catch{}for(let l of await readdir(a,{withFileTypes:true}))if(!(!l.name.endsWith(".json")||h.has(l.name))&&S.has(l.name)){if(l.isSymbolicLink()||!l.isFile())throw new Error(`Orphan shader static asset is not a regular file: ${l.name}.`);await unlink(b.join(a,l.name));}return await f(b.join(e$2,"meta.json"),`${O(p)}
|
|
17
|
+
`),c.push("meta.json"),{directory:e$2,receipt:p,files:c}}a(_t,"writeShaderArtifacts");var be="three-blocks.shader-capture.runtime.v1";var Q;async function W(){Q===void 0&&(Q=(async()=>{let e=createRequire(b.join(process.cwd(),"package.json")).resolve("@three-blocks/devtools/browser/shader-capture"),t=b.resolve(b.dirname(e),"../..");return (await j(t,e,a$1.metadata,"Shader capture browser runtime")).data.toString("utf8")})());let r=Q;try{return await r}catch(e){throw Q===r&&(Q=void 0),e}}a(W,"loadShaderCaptureRuntimeSource");var Xe="virtual:three-blocks-shader-capture-client",Ze="\0three-blocks:shader-capture-client",Re="virtual:three-blocks-shader-capture-runtime",er="\0three-blocks:shader-capture-runtime";async function tr(){let r=await W(),e=r.replace(/\bexport\{[^{}]*\};?\s*$/u,"");if(e===r)throw new Error("Shader capture browser runtime no longer has the expected final ESM export list.");return e}a(tr,"loadShaderCaptureRuntimeScriptSource");function $r(r){let e=r.split("?",1)[0];return e===void 0?false:e.split(b.sep).join("/").endsWith("/build/three.webgpu.js")}a($r,"isThreeWebGPUModule");function nr(r){let e=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u.exec(r);return e?.[1]==="0"&&e[2]==="185"}a(nr,"supportedVersion");function Nr(r,e,t={}){if(!nr(e))throw new Error(`Shader provider transform ${THREE_WEBGPU_R185_COMPATIBILITY} supports Three.js 0.185.x; received "${e}".`);let n=transformThreeWebgpuProviderHooks(r,{threeVersion:e,...t.threeRevision===void 0?{}:{threeRevision:t.threeRevision},id:"three/build/three.webgpu.js"}),i=n.state==="already-applied",s=n.code;return t.instrumentCapture&&(s=transformThreeWebgpuCaptureInstrumentation(s,{...t.captureRuntimeImport===void 0?{}:{runtimeImport:t.captureRuntimeImport},...t.forceWebGL===true?{forceWebGL:true}:{}}).code),{code:s,alreadyPresent:i,captureApplied:t.instrumentCapture===true}}a(Nr,"applyShaderProviderTransform");var Fr=/this\.trackTimestamp\s*=\s*\(\s*parameters\.trackTimestamp\s*===\s*true\s*\);/gu,Hr="Object.defineProperty( this, 'trackTimestamp', { get: () => false, set: () => {} } );";function ir(r,e={}){if(!nr(r))throw new Error(`Shader provider transform ${THREE_WEBGPU_R185_COMPATIBILITY} supports Three.js 0.185.x; received "${r}".`);let t={seen:false,applied:false,alreadyPresent:false};return {plugin:{name:"three-blocks:shader-provider-transform",enforce:"pre",config(){return {optimizeDeps:{exclude:["three","three/webgpu","three/tsl"]},resolve:{dedupe:["three"]}}},resolveId(i){return e.capture&&i===Xe?Ze:e.capture&&i===Re?er:null},async load(i){return e.capture?i===er?W():i===Ze?[`export * from '${Re}';`,`import { configureThreeBlocksShaderCapture } from '${Re}';`,`configureThreeBlocksShaderCapture( ${JSON.stringify({capture:e.capture.capture,backend:e.capture.forceWebGL===true?"webgl":"webgpu",forceLive:e.capture.forceLive,driven:e.capture.driven,settleFrames:e.capture.settleFrames,settleTimeoutMs:e.capture.settleTimeoutMs,visibilityGuard:e.capture.visibilityGuard,captureId:e.capture.captureId,sessionKey:e.capture.sessionKey,token:e.capture.token,readiness:e.capture.readiness??{},transform:F})} );`].join(`
|
|
18
|
+
`):null:null},transform(i,s){if(!$r(s))return null;t.seen=true,t.id=s;try{let a=Nr(i,r,{instrumentCapture:e.capture!==void 0,forceWebGL:e.capture?.forceWebGL===!0,...e.capture!==void 0?{captureRuntimeImport:Xe}:{}}),o=e.disableTimestampQueries===!0?a.code.replace(Fr,Hr):a.code;if(e.disableTimestampQueries===!0&&o===a.code)throw new Error("Three.js timestamp tracking anchor drifted; refusing software WebGPU capture.");return t.applied=!0,t.alreadyPresent=a.alreadyPresent,t.captureApplied=a.captureApplied,o===i?null:{code:o,map:null}}catch(a){throw t.error=a instanceof Error?a.message:String(a),a}}},status:t}}a(ir,"createShaderProviderTransform");function ve(r){if(r.error)throw new Error(r.error);if(!r.seen||!r.applied)throw new Error(`The version-gated shader provider transform was not applied (${r.seen?"module seen":"three/webgpu not seen"}).`)}a(ve,"assertShaderProviderTransform");var ur="/__three-blocks/shaders/capture",ce="/__three-blocks/shaders/telemetry",mr="/__three-blocks/shaders/runtime.js",pr="/__three-blocks/shaders/bootstrap.js",hr="/__three-blocks/shaders/bridge.js",fr=a$1.manifest*2,ke=/^[a-z0-9][a-z0-9_-]{0,63}$/u,yr=64,gr=2e3,zr=[/is not valid JSON/iu,/WebGPU is experimental/iu];async function Yr(){try{return (await import('playwright')).chromium}catch(r){throw new Error('Shader browser work requires the optional "playwright" package. Install it in the project and run `npx playwright install chromium`.',{cause:r})}}a(Yr,"loadChromium");async function Qr(r){let e;try{e=createRequire(b.join(r,"package.json")).resolve("vite");}catch(n){throw new Error("Shader capture requires Vite in the target project.",{cause:n})}let t=await import(pathToFileURL(e).href);if(typeof t.createServer!="function")throw new Error(`The target project's Vite entry does not export createServer(): ${e}`);return t.createServer}a(Qr,"loadProjectCreateServer");var Ce=class{static{a(this,"CaptureInbox");}#e=new Map;#r=new Map;wait(e,t){let n=this.#r.get(e);if(n!==void 0)return this.#r.delete(e),Promise.resolve(n);if(this.#e.has(e))throw new Error(`A shader capture is already waiting for scene "${e}".`);return new Promise((i,s)=>{let a=setTimeout(()=>{this.#e.delete(e),s(new Error(`Shader capture "${e}" timed out after ${t}ms.`));},t);this.#e.set(e,{resolve:i,reject:s,timer:a});})}receive(e){if(!a$2(e)||typeof e.scene!="string"||!ke.test(e.scene))throw new Error("Capture POST has no safe scene key.");if(!this.#r.has(e.scene)&&!this.#e.has(e.scene)&&this.#r.size>=yr)throw new Error("Capture POST exceeds the scene inbox limit.");let t=this.#e.get(e.scene);t?(clearTimeout(t.timer),this.#e.delete(e.scene),t.resolve(e)):this.#r.set(e.scene,e);}cancel(e,t){let n=this.#e.get(e);n&&(clearTimeout(n.timer),this.#e.delete(e),n.reject(t));}rejectAll(e){for(let t of this.#e.values())clearTimeout(t.timer),t.reject(e);this.#e.clear(),this.#r.clear();}};async function Xr(r,e){let t=await Promise.race([e.then(n=>({kind:"capture",value:n})),r.then(()=>({kind:"navigation"}))]);return t.kind==="capture"?t.value:e}a(Xr,"waitForShaderCaptureAcrossNavigation");var Be=class{static{a(this,"TelemetryHub");}#e=new Map;#r=new Map;markFirstRequest(e){ke.test(e)&&!this.#r.has(e)&&this.#r.set(e,Date.now());}firstRequest(e){return this.#r.get(e)}receive(e){if(!a$2(e)||typeof e.scene!="string"||!ke.test(e.scene))throw new Error("Shader telemetry has no bounded scene key.");if(!this.#e.has(e.scene)&&this.#e.size>=yr)throw new Error("Shader telemetry exceeds the scene limit.");this.#e.set(e.scene,e);}read(e){return this.#e.get(e)}clear(e){this.#e.delete(e),this.#r.delete(e);}},Zr=a(async(r,e,t,n,i)=>{let s=0;for(;r.__threeBlocksParityUsesAnimationLoop!==true&&s<e;)await n(),s+=1;if(r.__threeBlocksParityUsesAnimationLoop===true){let a=Number(r.__threeBlocksParityCompletedFrame||0),o=Number(t),c=Number.isSafeInteger(o)&&o>=a?o:a+e;for(r.__threeBlocksParityTargetFrame=c;Number(r.__threeBlocksParityCompletedFrame||0)<c;)await n();}return await i(),Number(r.__threeBlocksParityCompletedFrame||0)},"settleShaderParityFrames");function _e(r,e){return `(() => {
|
|
19
|
+
const root = globalThis;
|
|
20
|
+
const scene = new URL(location.href).searchParams.get('captureId')
|
|
21
|
+
|| 'default';
|
|
22
|
+
const workerCapture = ${JSON.stringify(e??null).replaceAll("<","\\u003c")};
|
|
23
|
+
if (workerCapture) root[Symbol.for('three-blocks.shader-capture.worker-activation.v1')] = { ...workerCapture, scene };
|
|
24
|
+
const randomSeed = (value) => {
|
|
25
|
+
let state = 2166136261;
|
|
26
|
+
for (let index = 0; index < value.length; index++) state = Math.imul(state ^ value.charCodeAt(index), 16777619) >>> 0;
|
|
27
|
+
return state === 0 ? 0x9e3779b9 : state;
|
|
28
|
+
};
|
|
29
|
+
const advanceRandom = (state) => {
|
|
30
|
+
state ^= state << 13;
|
|
31
|
+
state ^= state >>> 17;
|
|
32
|
+
state ^= state << 5;
|
|
33
|
+
return state >>> 0;
|
|
34
|
+
};
|
|
35
|
+
const parityMode = new URL(location.href).searchParams.get('threeBlocksShaderMode');
|
|
36
|
+
if (parityMode === 'live' || parityMode === 'precompiled') {
|
|
37
|
+
root.__threeBlocksParityEpoch = 1700000000000;
|
|
38
|
+
root.__threeBlocksParityTime = 0;
|
|
39
|
+
Date.now = () => root.__threeBlocksParityEpoch + Number(root.__threeBlocksParityTime || 0);
|
|
40
|
+
}
|
|
41
|
+
const randomStreams = new Map();
|
|
42
|
+
Math.random = () => {
|
|
43
|
+
const stackLine = String(new Error().stack || '').split('\\n')[2] || 'unknown';
|
|
44
|
+
const originIndex = stackLine.indexOf(location.origin);
|
|
45
|
+
const callsite = (originIndex >= 0 ? stackLine.slice(0, originIndex) : stackLine).trim() || 'anonymous';
|
|
46
|
+
const next = advanceRandom(randomStreams.get(callsite) ?? randomSeed(scene + '|' + callsite));
|
|
47
|
+
randomStreams.set(callsite, next);
|
|
48
|
+
return next / 4294967296;
|
|
49
|
+
};
|
|
50
|
+
const readiness = { workerReady: false, assetsReady: false, textReady: false, compileEnd: false, firstFrame: false };
|
|
51
|
+
const stats = { buildCalls: 0, renderBuilds: 0, computeBuilds: 0, registeredBuilds: 0, registeredRenderBuilds: 0, registeredComputeBuilds: 0, buildMs: 0, syncBuildMs: 0, asyncBuildElapsedMs: 0, precompiledSetupMs: 0, maxSyncBuildMs: 0, maxPrecompiledSetupMs: 0, hydrationMs: 0, maxHydrationMs: 0, injected: 0, injectedRender: 0, injectedCompute: 0, missed: 0, missedRender: 0, missedCompute: 0, missedKeys: [] };
|
|
52
|
+
const settleParityFrames = ${Zr.toString()};
|
|
53
|
+
const settle = (frames, requestedTarget) => settleParityFrames(
|
|
54
|
+
root,
|
|
55
|
+
frames,
|
|
56
|
+
requestedTarget,
|
|
57
|
+
() => new Promise((resolve) => requestAnimationFrame(resolve)),
|
|
58
|
+
() => new Promise((resolve) => setTimeout(resolve, 100)),
|
|
59
|
+
);
|
|
60
|
+
const bridge = { protocolVersion: 1, compatibility: ${JSON.stringify(r)}, transform: ${F}, readiness, stats, settle };
|
|
61
|
+
root.__threeBlocksShaderTools = bridge;
|
|
62
|
+
requestAnimationFrame(() => requestAnimationFrame(() => { readiness.firstFrame = true; }));
|
|
63
|
+
const poll = async () => {
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch('/__three-blocks/shaders/telemetry?scene=' + encodeURIComponent(scene), { cache: 'no-store' });
|
|
66
|
+
if (response.status !== 204 && response.ok) {
|
|
67
|
+
const payload = await response.json();
|
|
68
|
+
if (payload.protocolVersion !== 1 || payload.compatibility !== bridge.compatibility || payload.transform !== bridge.transform) throw new Error('incompatible shader telemetry');
|
|
69
|
+
Object.assign(stats, payload.stats);
|
|
70
|
+
if (Array.isArray(payload.demands)) bridge.demands = payload.demands;
|
|
71
|
+
if (typeof payload.demandTotal === 'number') bridge.demandTotal = payload.demandTotal;
|
|
72
|
+
readiness.workerReady = true;
|
|
73
|
+
if (payload.settled === true) {
|
|
74
|
+
readiness.assetsReady = true;
|
|
75
|
+
readiness.textReady = true;
|
|
76
|
+
readiness.compileEnd = true;
|
|
77
|
+
}
|
|
78
|
+
const smoke = root.__threeBlocksSmoke && typeof root.__threeBlocksSmoke === 'object' ? root.__threeBlocksSmoke : { protocolVersion: 1, worker: { offscreenCanvas: true, visible: true }, readiness: {} };
|
|
79
|
+
smoke.readiness = { ...(smoke.readiness || {}), ...readiness };
|
|
80
|
+
root.__threeBlocksSmoke = smoke;
|
|
81
|
+
}
|
|
82
|
+
} catch {}
|
|
83
|
+
setTimeout(poll, 40);
|
|
84
|
+
};
|
|
85
|
+
void poll();
|
|
86
|
+
})();`}a(_e,"publicBridgeScript");function wr(r,e,t,n,i=false){let s=new URL(r.url??"/","http://three-blocks.invalid"),a=s.pathname;if(i&&r.method==="GET"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.(?:webgpu|webgl)\.json$/u.test(a))return e.statusCode=204,e.end(),true;if(a===ce&&r.method==="GET"){let h=s.searchParams.get("scene")??"",S=n.read(h);return S===void 0?(e.statusCode=204,e.end()):(e.statusCode=200,e.setHeader("Content-Type","application/json"),e.end(JSON.stringify(S))),true}let o=a===ur,c=a===ce;if(!o&&!c)return false;if(r.method!=="POST")return e.statusCode=405,e.end("POST required"),true;let m=[],p=0,y=false;return r.on("data",h=>{p+=h.byteLength,p>fr?y=true:m.push(h);}),r.on("end",()=>{if(y){e.statusCode=413,e.end("capture payload too large");return}try{let h=JSON.parse(Buffer.concat(m).toString("utf8"));c?n.receive(h):t.receive(h),e.statusCode=204,e.end();}catch(h){e.statusCode=400,e.end(h instanceof Error?h.message:String(h));}}),true}a(wr,"handleCaptureEndpoint");function et(r,e,t,n,i){return {name:"three-blocks:shader-capture-endpoint",transformIndexHtml(){return [{tag:"script",children:_e(n,i),injectTo:"head-prepend"}]},configureServer(s){s.middlewares.use((a,o,c)=>{let p=new URL(a.url??"/","http://three-blocks.invalid").searchParams.get("captureId");p!==null&&e.markFirstRequest(p),!wr(a,o,r,e,t)&&c();});}}}a(et,"captureEndpointPlugin");function sr(r,e,t){let n=new URL(e.url,r);for(let[i,s]of Object.entries(t))n.searchParams.set(i,s);return n.href}a(sr,"browserUrl");function rt(r,e,t){let n=new URL(e.url,r);for(let i of ["capture","precompiled"])n.searchParams.delete(i);return n.searchParams.set("captureId",e.key),n.searchParams.set("threeBlocksShaderCapture","1"),n.searchParams.set("threeBlocksShaderMode","precompiled"),t==="webgl"&&n.searchParams.set("webgl","1"),n.searchParams.set("tbStats","1"),n.href}a(rt,"publishedBrowserUrl");function or(r){return zr.some(e=>e.test(r))}a(or,"knownNoise");async function H(r){let e;try{await Promise.race([r(),new Promise(t=>{e=setTimeout(t,gr);})]);}catch{}finally{e&&clearTimeout(e);}}a(H,"closeBrowserResource");async function de(r){let e;try{return await Promise.race([r().catch(()=>null),new Promise(t=>{e=setTimeout(()=>t(null),gr);})])}finally{e!==void 0&&clearTimeout(e);}}a(de,"readPageDiagnostic");function Te(r){let e=a(()=>{},"resolveFirst"),t=new Promise(a=>{e=a;}),n={console:[],page:[],first:t},i=false,s=a(a=>{i||(i=true,e(new Error(a)));},"report");return r.on("console",a=>{let o=a.type()==="warning"&&/\[three-blocks\/shaders\].*(?:has no entry|manifest miss|hydration)/iu.test(a.text());if(a.type()!=="error"&&!o||or(a.text()))return;let c=a.location().url,m=c.length>0?`${a.text()} (${c})`:a.text();n.console.push(m),s(`Browser console ${o?"warning":"error"}: ${m}`);}),r.on("pageerror",a=>{if(or(a.message))return;let o=a.stack||a.message;n.page.push(o),s(`Browser page error: ${o}`);}),r.on("crash",()=>s("Browser page crashed before shader capture completed.")),r.on("close",()=>s("Browser page closed before shader capture completed.")),n}a(Te,"collectErrors");function X(r,e,t=false){return typeof r[e]=="boolean"?r[e]:t}a(X,"booleanField");function tt(r){if(!a$2(r))throw new Error("Browser shader stats are unavailable.");let e=a((t,n=true)=>{let i=r[t];if(typeof i!="number"||!Number.isFinite(i)||i<0||n&&!Number.isSafeInteger(i))throw new Error(`Browser shader stats.${t} is invalid.`);return i},"read");return {buildCalls:e("buildCalls"),renderBuilds:e("renderBuilds"),computeBuilds:e("computeBuilds"),registeredBuilds:e("registeredBuilds"),registeredRenderBuilds:e("registeredRenderBuilds"),registeredComputeBuilds:e("registeredComputeBuilds"),buildMs:e("buildMs",false),syncBuildMs:e("syncBuildMs",false),asyncBuildElapsedMs:e("asyncBuildElapsedMs",false),precompiledSetupMs:e("precompiledSetupMs",false),maxSyncBuildMs:e("maxSyncBuildMs",false),maxPrecompiledSetupMs:e("maxPrecompiledSetupMs",false),hydrationMs:e("hydrationMs",false),maxHydrationMs:e("maxHydrationMs",false),injected:e("injected"),injectedRender:e("injectedRender"),injectedCompute:e("injectedCompute"),missed:e("missed"),missedRender:e("missedRender"),missedCompute:e("missedCompute"),...Array.isArray(r.missedKeys)&&r.missedKeys.every(t=>typeof t=="string")?{missedKeys:r.missedKeys}:{}}}a(tt,"parseStats");function se(r,e,t,n,i){if(!a$2(r))throw new Error("The page did not expose the public shader devtools bridge.");if(!t&&r.protocolVersion!==1)throw new Error(`Scene "${e.key}" exposed an unsupported shader bridge protocol.`);let s=r.readiness;if(!a$2(s))throw new Error("The shader bridge readiness snapshot is invalid.");let a={workerReady:X(s,"workerReady"),assetsReady:X(s,"assetsReady"),textReady:e.requiresText?X(s,"textReady"):true,compileEnd:X(s,"compileEnd"),firstFrame:X(s,"firstFrame",t)};if(!a.workerReady||!a.assetsReady||!a.textReady||!a.compileEnd)throw new Error(`Scene "${e.key}" did not reach worker/assets/text/compile readiness.`);let o=t?i:r.compatibility,c=t?F:r.transform;if(o!==i||c!==F)throw new Error(`Scene "${e.key}" exposed incompatible shader bridge metadata.`);ve(n);let m=Array.isArray(r.demands)?r.demands.filter(a$2).slice(0,64):void 0;return {compatibility:i,transform:c,readiness:a,stats:tt(r.stats),...m===void 0?{}:{demands:m}}}a(se,"parseBridge");async function oe(r,e){return r.evaluate(t=>{let n=globalThis;if(!t)return n.__threeBlocksShaderTools??null;let i=n.__threeBlocks,s=n.__threeBlocksTslStats;if(!i||typeof i!="object")return null;let a=i;return {readiness:{workerReady:a.workerReady===true,assetsReady:a.loadEnd===true||a.assetsReady===true,textReady:a.textReady===true,compileEnd:a.compileEnd===true,firstFrame:true},stats:s}},e)}a(oe,"readBridge");async function Sr(r,e){let t=await de(()=>r.evaluate(n=>{let i=globalThis,s=a(o=>{let c=i;for(let m of o.split(".")){if(c===null||typeof c!="object"&&typeof c!="function")return;c=Reflect.get(c,m);}return c},"resolveGlobal"),a$1=null;if(n!==null)try{a$1=JSON.stringify(s(`${n}Diagnostics`))??null;}catch{a$1=null;}return JSON.stringify({parityCompletedFrame:Number(i.__threeBlocksParityCompletedFrame??0),diagnostics:a$1})},e??null));return t===null?{alive:false,signature:""}:{alive:true,signature:t}}a(Sr,"probePageProgress");async function Z(r,e,t,n){let i=r.evaluate(async m=>{let y=globalThis.__threeBlocksShaderTools;if(y&&typeof y=="object"){let l=Reflect.get(y,"settle");if(typeof l=="function"){let u=await l(m.frames,m.targetFrame);return typeof u=="number"&&Number.isSafeInteger(u)?u:0}}if(!m.legacy||!m.modulePath)throw new Error("The public shader bridge does not provide deterministic settle().");let h=await import(m.modulePath);if(!h.store||typeof h.store!="object")throw new Error("Legacy deterministic store is unavailable.");let S=h.store;return S.recordFrameCount=0,S.recordFrameRate=60,S.recordTotalFrames=m.frames,S.recording=true,await new Promise((l,u)=>{let g=Date.now(),f=a(()=>{if(S.recording===false)return l();if(Date.now()-g>m.timeoutMs)return u(new Error("Legacy deterministic settle timed out."));setTimeout(f,25);},"poll");f();}),0},{frames:t,targetFrame:n,legacy:e.bridge.legacyLab,modulePath:e.bridge.deterministicModule??null,timeoutMs:e.timeoutMs}),s=V(e),a$1=false,o,c=(async()=>{let m=Date.now(),p=m,y="";for(;;){let h=s-(Date.now()-m);if(h<=0)throw new Error(`Shader parity settle timed out after ${s}ms.`);let S=e.timeoutMs-(Date.now()-p);if(S<=0){let l=await Sr(r,e.readiness.global);if(a$1)throw new Error("Shader parity settle already resolved.");if(l.alive&&l.signature===y)throw new Error(`Shader parity settle timed out after ${e.timeoutMs}ms without progress (hard cap ${s}ms).`);y=l.signature,p=Date.now();continue}if(await new Promise(l=>{o=setTimeout(l,Math.min(S,h,2500));}),a$1)throw new Error("Shader parity settle already resolved.")}})();try{return await Promise.race([i,c])}finally{a$1=true,o!==void 0&&clearTimeout(o),c.catch(()=>{});}}a(Z,"settlePage");async function dr(r,e,t){e.readiness.selector===void 0&&e.readiness.global===void 0||await Promise.race([r.waitForFunction(n=>{let i=globalThis;if(n.selector!==void 0&&i.document?.querySelector(n.selector)==null)return false;if(n.global===void 0)return true;let s=i;for(let c of n.global.split(".")){if((typeof s!="object"||s===null)&&typeof s!="function")return false;s=Reflect.get(s,c);}if(s===true)return true;if(typeof s!="object"||s===null||typeof Reflect.get(s,"then")!="function")return false;let a=i.__threeBlocksReadinessState,o=a instanceof Map?a:new Map;return a instanceof Map||(i.__threeBlocksReadinessState=o),o.has(s)||(o.set(s,false),Promise.resolve(s).then(()=>o.set(s,true),()=>o.set(s,false))),o.get(s)===true},e.readiness,{timeout:V(e)}),t.first.then(n=>Promise.reject(n))]);}a(dr,"waitForConfiguredReadiness");async function cr(r){let e=r.locator("canvas"),n=(await e.evaluateAll(i=>i.map((s,a)=>{let o=s.getBoundingClientRect();return {index:a,area:Math.max(0,o.width)*Math.max(0,o.height)}}))).sort((i,s)=>s.area-i.area)[0];if(n===void 0||n.area<=0)throw new Error("Published page has no visible renderer canvas.");return Buffer.from(await e.nth(n.index).screenshot({type:"png"}))}a(cr,"primaryCanvasScreenshot");async function Pe(r,e,t,n,i,s,a){let o=le(n,i,s),c=await tr(),m=`(() => {
|
|
87
|
+
const runtime = globalThis[Symbol.for(${JSON.stringify(be)})];
|
|
88
|
+
if (!runtime || typeof runtime.configureThreeBlocksShaderCapture !== 'function') {
|
|
89
|
+
throw new Error('@three-blocks/devtools attached shader capture runtime is incompatible.');
|
|
90
|
+
}
|
|
91
|
+
runtime.configureThreeBlocksShaderCapture(${JSON.stringify(o).replaceAll("<","\\u003c")});
|
|
92
|
+
})();`;await r.addInitScript({content:`${c}
|
|
93
|
+
${m}`}),await r.addInitScript({content:_e(a,o)}),await r.route("**/*",async p=>{let y=p.request(),h=new URL(y.url()),S=h.pathname;if(y.method()==="GET"&&n!=="precompiled"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.(?:webgpu|webgl)\.json$/u.test(S)){await p.fulfill({status:204});return}if(S===ce&&y.method()==="GET"){let g=t.read(h.searchParams.get("scene")??"");await p.fulfill(g===void 0?{status:204}:{status:200,contentType:"application/json",body:JSON.stringify(g)});return}let l=S===ur,u=S===ce;if((l||u)&&y.method()==="POST"){let g=y.postDataBuffer()??Buffer.alloc(0);if(g.byteLength>fr){await p.fulfill({status:413,body:"capture payload too large"});return}try{let f=JSON.parse(g.toString("utf8"));u?t.receive(f):e.receive(f),await p.fulfill({status:204});}catch(f){await p.fulfill({status:400,body:f instanceof Error?f.message:String(f)});}return}await p.continue();});}a(Pe,"configureAttachedContext");var nt=Object.freeze({".avif":"image/avif",".css":"text/css; charset=utf-8",".gif":"image/gif",".html":"text/html; charset=utf-8",".ico":"image/x-icon",".jpeg":"image/jpeg",".jpg":"image/jpeg",".js":"text/javascript; charset=utf-8",".json":"application/json; charset=utf-8",".mjs":"text/javascript; charset=utf-8",".mp4":"video/mp4",".png":"image/png",".svg":"image/svg+xml",".wasm":"application/wasm",".webm":"video/webm",".webp":"image/webp",".woff":"font/woff",".woff2":"font/woff2"});function it(r){let e=[`<script src="${hr}"></script>`,`<script type="module" src="${pr}"></script>`].join(""),t=/<head(?:\s[^>]*)?>/iu.exec(r);return t===null?`${e}${r}`:`${r.slice(0,t.index+t[0].length)}${e}${r.slice(t.index+t[0].length)}`}a(it,"injectStaticShaderCaptureHtml");function at(r,e,t){let n=le(r,e,t);return [`import { configureThreeBlocksShaderCapture } from ${JSON.stringify(mr)};`,`configureThreeBlocksShaderCapture( ${JSON.stringify(n).replaceAll("<","\\u003c")} );`].join(`
|
|
94
|
+
`)}a(at,"staticCaptureBootstrap");var st=5e3;function V(r){return Math.max(r.maxTimeoutMs??r.timeoutMs,r.timeoutMs)}a(V,"configuredHardCapMs");function le(r,e,t){return {capture:r==="capture",backend:t,driven:true,forceLive:r!=="precompiled",settleFrames:e.settleFrames,settleTimeoutMs:e.settleTimeoutMs??3e4,...r==="capture"?{deadlineAt:Date.now()+Math.max(1e3,V(e)-st)}:{},readiness:e.readiness,transform:F}}a(le,"shaderCaptureConfiguration");async function ot(r,e){let t=await k(r,e,a=>/\.(?:c|m)?js$/u.test(a),16384),n=false,i=false,s;for(let a of t){let o=(await j(r,a,a$1.texture,"Static application JavaScript")).data.toString("utf8");if(o.includes("nodeBuilderStateProvider")&&(n=true),o.includes("three-blocks.shader-capture.runtime.v1")&&(i=true,s??=a),n&&i)break}if(!n||!i)throw new Error("The static build does not contain the Three.js shader capture transform. Run `shaders capture` without an explicit driver or URL to preview adapter wiring and build automatically, or add the manual adapter from the package README and rebuild.");return {seen:true,applied:true,alreadyPresent:false,captureApplied:true,...s===void 0?{}:{id:s}}}a(ot,"inspectStaticCaptureTransform");async function dt(r,e$1){let t;try{t=decodeURIComponent(e$1);}catch{return}if(t.includes("\0"))return;let n=t.replace(/^\/+/u,""),i=b.resolve(r,n.length===0?"index.html":n);if(!e(r,i)||i===r||(await d$1(i)&&(await lstat(i)).isDirectory()&&(i=b.join(i,"index.html")),!await d$1(i)&&b.extname(i).length===0&&(i=b.join(r,"index.html")),!await d$1(i)))return;let s=await j(r,i,a$1.texture,"Static application asset");return {data:s.data,file:s.path}}a(dt,"staticRequestFile");async function ct(r,e$1,t,n,i,s){let a=await realpath(r.root),o=await realpath(b.resolve(a,r.serve));if(!e(a,o)||o===a)throw new Error("--serve must name a built application directory inside the project root.");let c=await ot(a,o),m=await W(),p=at(e$1,n,t),y=_e(x(r.runtime.three,t),le(e$1,n,t)),h=createServer((l,u)=>{(async()=>{if(wr(l,u,i,s,e$1!=="precompiled"))return;let g=new URL(l.url??"/","http://three-blocks.invalid");if(l.method!=="GET"&&l.method!=="HEAD"){u.statusCode=405,u.end("GET or HEAD required");return}let f=g.pathname===mr?m:g.pathname===pr?p:g.pathname===hr?y:void 0;if(f!==void 0){u.statusCode=200,u.setHeader("Content-Type","text/javascript; charset=utf-8"),u.setHeader("Cache-Control","no-store"),u.end(l.method==="HEAD"?void 0:f);return}let w=await dt(o,g.pathname);if(w===void 0){u.statusCode=404,u.end("Not found");return}let v=b.extname(w.file).toLowerCase(),E=v===".html"?Buffer.from(it(w.data.toString("utf8"))):w.data;u.statusCode=200,u.setHeader("Content-Type",nt[v]??"application/octet-stream"),u.setHeader("Content-Length",String(E.byteLength)),u.setHeader("Cache-Control","no-store"),u.end(l.method==="HEAD"?void 0:E);})().catch(g=>{if(u.headersSent)return u.destroy(g instanceof Error?g:void 0);u.statusCode=500,u.end(g instanceof Error?g.message:String(g));});});await new Promise((l,u)=>{h.once("error",u),h.listen(0,"127.0.0.1",()=>{h.off("error",u),l();});});let S=h.address();if(!S||typeof S=="string")throw new Error("Static capture server did not expose an ephemeral TCP address.");return {server:h,baseUrl:`http://127.0.0.1:${S.port}`,transform:c}}a(ct,"startStaticShaderServer");function lt(r,e,t){return r===e?true:t&&r!==void 0&&r!=="capture"&&e!=="capture"}a(lt,"canReuseShaderBrowserSession");function lr(r){let e=r instanceof Error?r.message:String(r);return e.includes("Execution context was destroyed")&&e.includes("navigation")||/^launch: Timeout \d+ms exceeded\./u.test(e)}a(lr,"isRetryableShaderObservationNavigation");var ee=class{static{a(this,"PlaywrightShaderDriver");}#e;#r=new Ce;#n=new Be;#m;#p;#s;#o;#t;#i;#h;#c;#f;#y;#l=0;#u;constructor(e){this.#e=e;}#d(){return this.#m?.status??this.#p??{seen:false,applied:false,alreadyPresent:false}}async#g(e,t){if(this.#t?.isConnected()===true)return;this.#t=void 0;let n=await Yr();this.#u??=await mkdtemp(b.join(tmpdir(),"three-blocks-shader-cache-")),this.#t=await n.launch({headless:t==="webgl"?this.#e.headed!==true:d(this.#e.headed===true),args:[...t==="webgl"?c():b$1(),`--disk-cache-dir=${this.#u}`],timeout:e.timeoutMs}),this.#l=0;}async#a(e,t,n){let i;try{return await Promise.race([n(),new Promise((s,a)=>{i=setTimeout(()=>a(new Error(`launch: Timeout ${t.timeoutMs}ms exceeded.`)),t.timeoutMs);})])}catch(s){throw this.#t===e&&(this.#t=void 0),await H(()=>e.close()),s}finally{i!==void 0&&clearTimeout(i);}}async#w(e,t,n){let i=this.#s!==void 0||this.#o!==void 0||this.#e.url!==void 0&&this.#i!==void 0,s=this.#f===t&&(this.#o!==void 0?this.#c===e:lt(this.#c,e,n.bridge.legacyLab));if(i&&s){this.#c=e,await this.#g(n,t);return}if(i&&await this.close(),this.#c=e,this.#f=t,this.#e.url!==void 0){let a=new URL(this.#e.url);if(!["http:","https:"].includes(a.protocol)||a.username||a.password||a.hash)throw new Error("Attached shader URL must be an HTTP(S) URL without credentials or a fragment.");this.#i=a.href,this.#p={seen:true,applied:true,alreadyPresent:false,captureApplied:true,id:"attached-application"},await this.#g(n,t);return}if(this.#e.serve!==void 0)try{let a=await ct({root:this.#e.root,runtime:this.#e.runtime,serve:this.#e.serve,...this.#e.headed===void 0?{}:{headed:this.#e.headed}},e,t,n,this.#r,this.#n);this.#o=a.server,this.#p=a.transform,this.#i=a.baseUrl,await this.#g(n,t);return}catch(a){throw await this.close(),a}this.#m=ir(this.#e.runtime.three,{disableTimestampQueries:D.env.THREE_BLOCKS_SOFTWARE_WEBGPU==="1",...n.bridge.legacyLab?{}:{capture:{capture:e==="capture",driven:true,forceLive:e!=="precompiled",forceWebGL:t==="webgl",settleFrames:n.settleFrames,settleTimeoutMs:n.settleTimeoutMs??3e4,readiness:n.readiness}}}),this.#h={THREE_BLOCKS_SHADER_TOOL:D.env.THREE_BLOCKS_SHADER_TOOL,THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER:D.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER},D.env.THREE_BLOCKS_SHADER_TOOL="1",D.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER="1";try{let a=await Qr(this.#e.root);this.#s=await a({root:this.#e.root,logLevel:"error",plugins:[this.#m.plugin,et(this.#r,this.#n,e!=="precompiled",x(this.#e.runtime.three,t),le(e,n,t))],server:{host:"127.0.0.1",port:0}}),await this.#s.listen();let o=this.#s.httpServer?.address();if(!o||typeof o=="string")throw new Error("Vite did not expose an ephemeral TCP address.");this.#i=`http://127.0.0.1:${o.port}`,await this.#g(n,t);}catch(a){throw await this.close(),a}}async capture(e,t,n="webgpu"){let i=Date.now();if(await this.#w("capture",n,t),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let s=this.#t,a$1=await this.#a(s,t,()=>s.newContext({viewport:t.viewport}));this.#e.url!==void 0&&await this.#a(s,t,()=>Pe(a$1,this.#r,this.#n,"capture",t,n,x(this.#e.runtime.three,n)));let o=await this.#a(s,t,()=>a$1.newPage()),c=Te(o);this.#n.clear(e.key);let m=V(t),p=this.#r.wait(e.key,m),y=false;m>t.timeoutMs?(async()=>{let f=Math.min(5e3,Math.max(1e3,Math.round(t.timeoutMs/8))),w=Date.now(),v="",E="";for(;!y;){if(await new Promise(_=>setTimeout(_,f)),y)return;let k=this.#n.read(e.key),A=k===void 0?"":JSON.stringify(k);if(A!==v){v=A,w=Date.now();continue}if(Date.now()-w<t.timeoutMs)continue;let B=await Sr(o,t.readiness.global);if(y)return;if(!B.alive||B.signature!==E){E=B.signature,w=Date.now();continue}this.#r.cancel(e.key,new Error(`Shader capture "${e.key}" timed out after ${t.timeoutMs}ms without progress (hard cap ${m}ms).`));return}})().catch(()=>{}):void 0;let S=Promise.race([p,c.first.then(f=>Promise.reject(f))]),l=a(()=>{},"resolveDisconnected"),u=new Promise(f=>{l=f;}),g=a(()=>l(new Error("Shader capture browser disconnected before posting a manifest.")),"onDisconnected");s.on("disconnected",g);try{let f=o.goto(sr(this.#i,e,{threeBlocksShaderCapture:"1",capture:"1",captureId:e.key,captureFrames:String(Math.max(4,t.settleFrames)),settleFrames:String(t.settleFrames),...n==="webgl"?{webgl:"1"}:{}}),{waitUntil:"domcontentloaded",timeout:t.timeoutMs}),w=await Xr(f,Promise.race([S,u.then(E=>Promise.reject(E))]));ve(this.#d());let v=[...c.page,...c.console];if(v.length>0)throw new Error(`Capture browser errors:
|
|
95
|
+
- ${v.join(`
|
|
96
|
+
- `)}`);return a$2(w)?{...w,timing:{...a$2(w.timing)?w.timing:{},launch:i,...this.#n.firstRequest(e.key)===void 0?{}:{firstRequest:this.#n.firstRequest(e.key)},posted:Date.now()}}:w}catch(f){let w=f instanceof Error?f:new Error(String(f));this.#r.cancel(e.key,w),await p.catch(()=>{});let v=this.#n.read(e.key);if(w.message.includes("timed out")){let E=await de(()=>o.evaluate(B=>{let _=globalThis,P=_.__threeBlocksShaderTools,J=P&&typeof P=="object"?P:void 0,K=_.document,j=Reflect.get(_,Symbol.for("three-blocks.shader-capture.cache-value.v1")),re=_.location,br=re!==null&&typeof re=="object"&&typeof Reflect.get(re,"href")=="string"?String(Reflect.get(re,"href")):"http://three-blocks.invalid/",Er=new URL(br).searchParams.get("captureId")??"default",Me=j!==null&&typeof j=="object"&&typeof Reflect.get(j,"registrations")=="function"?Reflect.apply(Reflect.get(j,"registrations"),j,[Er]):void 0,xe=a(C=>{let I=_;for(let Rr of C.split(".")){if(I===null||typeof I!="object"&&typeof I!="function")return;I=Reflect.get(I,Rr);}return I},"resolveGlobal"),Ae=null,ue=null;if(B!==null){let C=xe(B);Ae=C===true||C===false?C:C===void 0?"absent":C!==null&&typeof C.then=="function"?"promise":typeof C;try{let I=JSON.stringify(xe(`${B}Diagnostics`));ue=typeof I=="string"?I.slice(0,2048):null;}catch{ue=null;}}return {documentReadyState:K?.readyState??null,parityTargetFrame:Number(_.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(_.__threeBlocksParityCompletedFrame??0),readiness:J?.readiness??null,readinessGlobal:Ae,readinessDiagnostics:ue,captureCache:j!==null&&typeof j=="object"?{activeScene:Reflect.get(j,"activeScene")??null,registrations:Array.isArray(Me)?Me.slice(0,16).map(C=>C!==null&&typeof C=="object"?{key:Reflect.get(C,"key")??null,kind:Reflect.get(C,"kind")??null}:null):null}:null,threeRuntimeResources:performance.getEntriesByType("resource").map(C=>C.name).filter(C=>C.includes("three.webgpu"))}},t.readiness.global??null)),k=t.readiness.global!==void 0&&E!==null&&E.readinessGlobal!==true,A=E===null?"Capture page did not answer diagnostics before the deadline; its main thread was blocked or gone. ":k?`Application readiness "${t.readiness.global}" never completed (state: ${JSON.stringify(E.readinessGlobal)}${E.readinessDiagnostics===null?"":`, diagnostics: ${E.readinessDiagnostics}`}). `:"";throw new Error(`${A}${w.message} Last capture state for "${e.key}": ${JSON.stringify({page:E,telemetry:v??null,transform:this.#d()})}`)}throw w}finally{y=true,s.off("disconnected",g),await H(()=>a$1.close()),this.#l++,(!s.isConnected()||this.#l>=(t.browserRelaunchScenes??8))&&(this.#t===s&&(this.#t=void 0),await H(()=>s.close()),this.#l=0);}}async observe(e,t,n,i,s="webgpu"){for(let a=0;a<2;a++)try{return await this.#S(e,s,t,n,i)}catch(o){if(a===0&&lr(o))continue;throw o}throw new Error(`Shader observation retry was exhausted for scene "${e.key}".`)}async#S(e,t,n,i,s){if(await this.#w(n,t,i),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let a=this.#t,o=await this.#a(a,i,()=>a.newContext({viewport:i.viewport}));this.#e.url!==void 0&&await this.#a(a,i,()=>Pe(o,this.#r,this.#n,n,i,t,x(this.#e.runtime.three,t)));let c=await this.#a(a,i,()=>o.newPage()),m=Te(c);this.#n.clear(e.key);try{await c.goto(sr(this.#i,e,{threeBlocksShaderCapture:"1",threeBlocksShaderMode:n,captureId:e.key,...n==="live"?{precompiled:"0"}:{},...t==="webgl"?{webgl:"1"}:{}}),{waitUntil:"domcontentloaded",timeout:i.timeoutMs}),await Promise.race([c.waitForFunction(i.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:V(i)}),m.first.then(u=>Promise.reject(u))]),se(await oe(c,i.bridge.legacyLab),e,i.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t)),await dr(c,i,m),await Promise.race([c.waitForFunction(i.bridge.legacyLab?"true":"globalThis.__threeBlocksShaderTools?.readiness?.firstFrame === true",void 0,{timeout:V(i)}),m.first.then(u=>Promise.reject(u))]),await Z(c,i,1);let p=Buffer.from(await c.screenshot({type:"png"})),y=e.parityFrames??i.parity.frames,h=await Z(c,i,y,s),S=Buffer.from(await c.screenshot({type:"png"}));e.parityFrames!==void 0&&y<i.parity.frames&&await Z(c,i,i.parity.frames-y);let l=se(await oe(c,i.bridge.legacyLab),e,i.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t));return this.#y===void 0&&(this.#y=await c.evaluate(async u=>{if(u==="webgl"){let B=Reflect.get(globalThis,"document").querySelector("canvas")?.getContext("webgl2"),_=B?.getExtension("WEBGL_debug_renderer_info");return {adapter:B&&_?String(B.getParameter(_.UNMASKED_RENDERER_WEBGL)):"WebGL adapter",platform:navigator.platform||navigator.userAgent}}let g=Reflect.get(navigator,"gpu"),f=typeof g=="object"&&g!==null?Reflect.get(g,"requestAdapter"):void 0,w=typeof f=="function"?await Reflect.apply(f,g,[]):void 0,v=typeof w=="object"&&w!==null?Reflect.get(w,"info"):void 0,E=["description","device","architecture","vendor"].flatMap(k=>{let A=typeof v=="object"&&v!==null?Reflect.get(v,k):void 0;return typeof A=="string"&&A.length>0?[A]:[]});return {adapter:[...new Set(E)].join(" \xB7 ")||"WebGPU adapter",platform:navigator.platform||navigator.userAgent}},t)),{scene:e.key,mode:n,...l,frame:h,firstFrameScreenshot:p,screenshot:S,errors:[...m.page,...m.console]}}catch(p){let y=p instanceof Error?p:new Error(String(p));if(/(?:timed?\s*out|timeout)/iu.test(y.message)){let u=this.#n.read(e.key),g=await de(()=>c.evaluate(()=>{let f=globalThis,w=f.__threeBlocksShaderTools,v=w&&typeof w=="object"?w:void 0;return {documentReadyState:f.document?.readyState??null,parityTargetFrame:Number(f.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(f.__threeBlocksParityCompletedFrame??0),readiness:v?.readiness??null,threeRuntimeResources:performance.getEntriesByType("resource").map(k=>k.name).filter(k=>k.includes("three.webgpu"))}}));throw new Error(`${y.message} Last ${n} state for "${e.key}": ${JSON.stringify({page:g,telemetry:u??null})}`)}let h=this.#n.read(e.key),l=(a$2(h)&&Array.isArray(h.demands)&&h.demands.length>0?JSON.stringify(h.demands).slice(0,6e3):void 0)??await de(()=>c.evaluate(u=>{let g=globalThis,f=Reflect.get(g,Symbol.for(u)),w=f!==null&&typeof f=="object"?Reflect.get(f,"readThreeBlocksShaderDemands"):void 0,v=typeof w=="function"?Reflect.apply(w,f,[]):void 0,E=g.__threeBlocksShaderTools,k=Array.isArray(v)&&v.length>0?v:E&&typeof E=="object"?Reflect.get(E,"demands"):void 0;return Array.isArray(k)&&k.length>0?JSON.stringify(k).slice(0,6e3):null},be));throw typeof l=="string"?new Error(`${y.message}
|
|
97
|
+
${n} demands: ${l}`):y}finally{await H(()=>o.close());}}async observePublished(e,t,n="webgpu"){for(let i=0;i<2;i++)try{return await this.#b(e,n,t)}catch(s){if(i===0&&lr(s))continue;throw s}throw new Error(`Published shader observation retry was exhausted for scene "${e.key}".`)}async#b(e,t,n){if(await this.#w("precompiled",t,n),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let i=this.#t,s=await this.#a(i,n,()=>i.newContext({viewport:n.viewport}));this.#e.url!==void 0&&await this.#a(i,n,()=>Pe(s,this.#r,this.#n,"precompiled",n,t,x(this.#e.runtime.three,t)));let a=await this.#a(i,n,()=>s.newPage()),o=Te(a);this.#n.clear(e.key);try{await a.goto(rt(this.#i,e,t),{waitUntil:"domcontentloaded",timeout:n.timeoutMs}),await Promise.race([a.waitForFunction(n.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:V(n)}),o.first.then(h=>Promise.reject(h))]),await dr(a,n,o),se(await oe(a,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t)),await Z(a,n,2);let c=await cr(a),m=await Z(a,n,120),p=await cr(a),y=se(await oe(a,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t));return {scene:e.key,mode:"precompiled",...y,frame:m,firstFrameScreenshot:c,beforeScreenshot:c,screenshot:p,errors:[...o.page,...o.console]}}finally{await H(()=>s.close());}}timingEnvironment(){return this.#y??{adapter:this.#f==="webgl"?"WebGL adapter":"WebGPU adapter",platform:`${D.platform}/${D.arch}`}}async close(){this.#r.rejectAll(new Error("Shader browser driver closed.")),this.#t&&await H(()=>this.#t?.close()??Promise.resolve());let e=this.#s?.httpServer,t=e?Reflect.get(e,"closeAllConnections"):void 0;if(e&&typeof t=="function"&&Reflect.apply(t,e,[]),this.#s&&await H(()=>this.#s?.close()??Promise.resolve()),this.#o){let n=this.#o;n.closeAllConnections(),await H(()=>new Promise(i=>{n.close(()=>i());}));}if(this.#t=void 0,this.#s=void 0,this.#o=void 0,this.#i=void 0,this.#m=void 0,this.#p=void 0,this.#c=void 0,this.#f=void 0,this.#y=void 0,this.#l=0,this.#u!==void 0&&(await rm(this.#u,{recursive:true,force:true}),this.#u=void 0),this.#h){for(let[n,i]of Object.entries(this.#h))i===void 0?delete D.env[n]:D.env[n]=i;this.#h=void 0;}}};function dn(r){return new ee(r)}a(dn,"createPlaywrightShaderDriver");function cn(r){return new ee(r)}a(cn,"createStaticPlaywrightShaderDriver");function ln(r){return new ee(r)}a(ln,"createAttachedPlaywrightShaderDriver");export{x as a,F as b,vt as c,O as d,Tt as e,Pt as f,kt as g,Ct as h,Bt as i,_t as j,Xr as k,Zr as l,_e as m,lt as n,lr as o,dn as p,cn as q,ln as r};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {a}from'./chunk-HOZDD6PW.js';var d=/^[a-f0-9]{64}$/,g=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/,h=/^[a-z0-9][a-z0-9_-]{0,63}$/,f=/^[0-9A-Za-z][0-9A-Za-z._/-]{0,127}$/;function n(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}a(n,"isRecord");function i(e){return typeof e=="string"&&g.test(e)}a(i,"isSafeVersion");function c(e){if(e.length===0||e.length>512||e.includes("\\")||/[\u0000-\u001f\u007f]/.test(e))return false;let o=e.split("/");return !e.startsWith("/")&&o.every(t=>t.length>0&&t!=="."&&t!=="..")}a(c,"isSafeRelativePath");function m(e){if(!n(e)||e.schemaVersion!==2)throw new Error("three-blocks.json must use schemaVersion 2.");if(typeof e.template!="string"||!h.test(e.template))throw new Error("three-blocks.json has an invalid default shader scene key.");if(!Array.isArray(e.layers)||!e.layers.every(o=>typeof o=="string"&&f.test(o))||new Set(e.layers).size!==e.layers.length)throw new Error("three-blocks.json has invalid layers.");if(e.generator!==void 0&&(!n(e.generator)||typeof e.generator.name!="string"||!f.test(e.generator.name)||!i(e.generator.version)))throw new Error("three-blocks.json has invalid generator metadata.");if(!n(e.runtime)||!i(e.runtime.three)||!i(e.runtime.threeBlocks))throw new Error("three-blocks.json has invalid runtime versions.");if(!n(e.features)||typeof e.features.text!="boolean")throw new Error("three-blocks.json has invalid feature metadata.");if(!n(e.protocol)||e.protocol.resultFile!==1)throw new Error("three-blocks.json has an unsupported protocol schema.");if(e.artifacts!==void 0){if(!n(e.artifacts)||typeof e.artifacts.shaders!="string"||!["fresh","pending"].includes(e.artifacts.shaders)||typeof e.artifacts.text!="string"||!["fresh","pending","not-applicable"].includes(e.artifacts.text))throw new Error("three-blocks.json has invalid artifact metadata.");if(e.features.text?e.artifacts.text==="not-applicable":e.artifacts.text!=="not-applicable")throw new Error("three-blocks.json text artifact state does not match the text capability.")}return {schemaVersion:2,template:e.template,layers:e.layers,...e.generator===void 0?{}:{generator:{name:e.generator.name,version:e.generator.version}},runtime:{three:e.runtime.three,threeBlocks:e.runtime.threeBlocks},features:{text:e.features.text},...e.artifacts===void 0?{}:{artifacts:{shaders:e.artifacts.shaders,text:e.artifacts.text}},protocol:{resultFile:1}}}a(m,"parseProjectMetadata");function l(e){if(!n(e))throw new Error("Shader coverage is missing.");for(let o of ["render","vertex","fragment","compute"])if(typeof e[o]!="number"||!Number.isSafeInteger(e[o])||e[o]<0)throw new Error(`Shader coverage.${o} must be a non-negative integer.`);return e}a(l,"parseCoverage");function y(e,o){if(!n(e))throw new Error(`Shader receipt inputs for "${o}" are invalid.`);let t=Object.entries(e);if(t.length===0||t.length>4096)throw new Error(`Shader receipt inputs for "${o}" must contain between 1 and 4096 files.`);for(let[r,a]of t)if(!c(r)||typeof a!="string"||!d.test(a))throw new Error(`Shader receipt input for "${o}" is invalid.`)}a(y,"parseInputs");function b(e){if(!n(e)||e.schemaVersion!==2||!n(e.runtime)||!i(e.runtime.three)||!i(e.runtime.threeBlocks)||typeof e.runtime.threeBlocksShaderClosure!="string"||!d.test(e.runtime.threeBlocksShaderClosure)||!n(e.scenes))throw new Error("Shader meta.json does not match receipt schema 2.");if(e.runtime.capture!==void 0&&(!n(e.runtime.capture)||typeof e.runtime.capture.userAgent!="string"||e.runtime.capture.userAgent.length>1024||typeof e.runtime.capture.adapter!="string"||e.runtime.capture.adapter.length>1024||!Array.isArray(e.runtime.capture.features)||e.runtime.capture.features.length>256||!e.runtime.capture.features.every(t=>typeof t=="string"&&t.length>0&&t.length<=128)))throw new Error("Shader meta.json has invalid browser capture provenance.");let o=Object.entries(e.scenes);if(o.length===0)throw new Error("Shader meta.json contains no scenes.");for(let[t,r]of o){let a=t.endsWith(".webgl")?"webgl":"webgpu",p=a==="webgl"?t.slice(0,-6):t;if(!h.test(p)||!n(r)||r.backend!==void 0&&r.backend!==a||typeof r.artifact!="string"||!c(r.artifact)||!r.artifact.endsWith(`.${a}.ts`)||typeof r.artifactHash!="string"||!d.test(r.artifactHash))throw new Error(`Shader receipt for "${t}" is invalid.`);if(r.asset===void 0!=(r.assetHash===void 0)||r.asset!==void 0&&(typeof r.asset!="string"||!c(r.asset)||!r.asset.endsWith(".json")||typeof r.assetHash!="string"||!d.test(r.assetHash)))throw new Error(`Shader static asset receipt for "${t}" is invalid.`);if(y(r.inputs,t),l(r.coverage),r.bytes!==void 0&&(!Number.isSafeInteger(r.bytes)||Number(r.bytes)<0))throw new Error(`Shader receipt byte count for "${t}" is invalid.`);if(r.skipped!==void 0&&(!n(r.skipped)||!Number.isSafeInteger(r.skipped.render)||Number(r.skipped.render)<0||!Number.isSafeInteger(r.skipped.compute)||Number(r.skipped.compute)<0))throw new Error(`Shader receipt skipped-build counts for "${t}" are invalid.`)}if(e.tool!==void 0&&(!n(e.tool)||e.tool.name!=="@three-blocks/devtools"||!i(e.tool.version)||typeof e.tool.compatibility!="string"||!Number.isSafeInteger(e.tool.transform)||!Number.isSafeInteger(e.tool.address)||!Number.isSafeInteger(e.tool.recipe)||!Number.isSafeInteger(e.tool.hydration)))throw new Error("Shader meta.json has invalid tool compatibility metadata.");if(n(e.tool)&&e.tool.compatibilities!==void 0&&(!n(e.tool.compatibilities)||Object.entries(e.tool.compatibilities).some(([t,r])=>t!=="webgpu"&&t!=="webgl"||typeof r!="string"||r.length===0)))throw new Error("Shader meta.json has invalid backend compatibility metadata.");return e}a(b,"parseShaderReceipt");export{n as a,m as b,b as c};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {a}from'./chunk-EI7MMDWY.js';import {createHash,randomUUID}from'crypto';import {lstat,open,realpath,mkdir,rename,rm,link,readdir,readFile,unlink}from'fs/promises';import p from'path';import {THREE_WEBGL_R185_COMPATIBILITY,THREE_WEBGPU_R185_COMPATIBILITY,THREE_R186DEV_VERSION,THREE_WEBGPU_R186DEV_COMPATIBILITY,parsePrecompiledManifest,SHADER_HYDRATION_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_ADDRESS_SCHEMA_VERSION,PRECOMPILED_MANIFEST_VERSION}from'three-blocks/shaders';import {createRequire}from'module';import {transformThreeWebgpuProviderHooks,transformThreeWebgpuCaptureInstrumentation}from'three-blocks/vite';var V=/^[a-f0-9]{64}$/,rr=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/,xe=/^[a-z0-9][a-z0-9_-]{0,63}$/,Te=/^[0-9A-Za-z][0-9A-Za-z._/-]{0,127}$/;function c(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}a(c,"isRecord");function $(e){return typeof e=="string"&&rr.test(e)}a($,"isSafeVersion");function ne(e){if(e.length===0||e.length>512||e.includes("\\")||/[\u0000-\u001f\u007f]/.test(e))return false;let r=e.split("/");return !e.startsWith("/")&&r.every(t=>t.length>0&&t!=="."&&t!=="..")}a(ne,"isSafeRelativePath");function Ae(e){if(!c(e)||e.schemaVersion!==2)throw new Error("three-blocks.json must use schemaVersion 2.");if(typeof e.template!="string"||!xe.test(e.template))throw new Error("three-blocks.json has an invalid default shader scene key.");if(!Array.isArray(e.layers)||!e.layers.every(r=>typeof r=="string"&&Te.test(r))||new Set(e.layers).size!==e.layers.length)throw new Error("three-blocks.json has invalid layers.");if(e.generator!==void 0&&(!c(e.generator)||typeof e.generator.name!="string"||!Te.test(e.generator.name)||!$(e.generator.version)))throw new Error("three-blocks.json has invalid generator metadata.");if(!c(e.runtime)||!$(e.runtime.three)||!$(e.runtime.threeBlocks))throw new Error("three-blocks.json has invalid runtime versions.");if(!c(e.features)||typeof e.features.text!="boolean")throw new Error("three-blocks.json has invalid feature metadata.");if(!c(e.protocol)||e.protocol.resultFile!==1)throw new Error("three-blocks.json has an unsupported protocol schema.");if(e.artifacts!==void 0){if(!c(e.artifacts)||typeof e.artifacts.shaders!="string"||!["fresh","pending"].includes(e.artifacts.shaders)||typeof e.artifacts.text!="string"||!["fresh","pending","not-applicable"].includes(e.artifacts.text))throw new Error("three-blocks.json has invalid artifact metadata.");if(e.features.text?e.artifacts.text==="not-applicable":e.artifacts.text!=="not-applicable")throw new Error("three-blocks.json text artifact state does not match the text capability.")}return {schemaVersion:2,template:e.template,layers:e.layers,...e.generator===void 0?{}:{generator:{name:e.generator.name,version:e.generator.version}},runtime:{three:e.runtime.three,threeBlocks:e.runtime.threeBlocks},features:{text:e.features.text},...e.artifacts===void 0?{}:{artifacts:{shaders:e.artifacts.shaders,text:e.artifacts.text}},protocol:{resultFile:1}}}a(Ae,"parseProjectMetadata");function tr(e){if(!c(e))throw new Error("Shader coverage is missing.");for(let r of ["render","vertex","fragment","compute"])if(typeof e[r]!="number"||!Number.isSafeInteger(e[r])||e[r]<0)throw new Error(`Shader coverage.${r} must be a non-negative integer.`);return e}a(tr,"parseCoverage");function nr(e,r){if(!c(e))throw new Error(`Shader receipt inputs for "${r}" are invalid.`);let t=Object.entries(e);if(t.length===0||t.length>4096)throw new Error(`Shader receipt inputs for "${r}" must contain between 1 and 4096 files.`);for(let[n,i]of t)if(!ne(n)||typeof i!="string"||!V.test(i))throw new Error(`Shader receipt input for "${r}" is invalid.`)}a(nr,"parseInputs");function H(e){if(!c(e)||e.schemaVersion!==2||!c(e.runtime)||!$(e.runtime.three)||!$(e.runtime.threeBlocks)||typeof e.runtime.threeBlocksShaderClosure!="string"||!V.test(e.runtime.threeBlocksShaderClosure)||!c(e.scenes))throw new Error("Shader meta.json does not match receipt schema 2.");if(e.runtime.capture!==void 0&&(!c(e.runtime.capture)||typeof e.runtime.capture.userAgent!="string"||e.runtime.capture.userAgent.length>1024||typeof e.runtime.capture.adapter!="string"||e.runtime.capture.adapter.length>1024||!Array.isArray(e.runtime.capture.features)||e.runtime.capture.features.length>256||!e.runtime.capture.features.every(t=>typeof t=="string"&&t.length>0&&t.length<=128)))throw new Error("Shader meta.json has invalid browser capture provenance.");let r=Object.entries(e.scenes);if(r.length===0)throw new Error("Shader meta.json contains no scenes.");for(let[t,n]of r){let i=t.endsWith(".webgl")?"webgl":"webgpu",o=i==="webgl"?t.slice(0,-6):t;if(!xe.test(o)||!c(n)||n.backend!==void 0&&n.backend!==i||typeof n.artifact!="string"||!ne(n.artifact)||!n.artifact.endsWith(`.${i}.ts`)||typeof n.artifactHash!="string"||!V.test(n.artifactHash))throw new Error(`Shader receipt for "${t}" is invalid.`);if(n.asset===void 0!=(n.assetHash===void 0)||n.asset!==void 0&&(typeof n.asset!="string"||!ne(n.asset)||!n.asset.endsWith(".json")||typeof n.assetHash!="string"||!V.test(n.assetHash)))throw new Error(`Shader static asset receipt for "${t}" is invalid.`);if(nr(n.inputs,t),tr(n.coverage),n.bytes!==void 0&&(!Number.isSafeInteger(n.bytes)||Number(n.bytes)<0))throw new Error(`Shader receipt byte count for "${t}" is invalid.`);if(n.skipped!==void 0&&(!c(n.skipped)||!Number.isSafeInteger(n.skipped.render)||Number(n.skipped.render)<0||!Number.isSafeInteger(n.skipped.compute)||Number(n.skipped.compute)<0))throw new Error(`Shader receipt skipped-build counts for "${t}" are invalid.`)}if(e.tool!==void 0&&(!c(e.tool)||e.tool.name!=="@three-blocks/devtools"||!$(e.tool.version)||typeof e.tool.compatibility!="string"||!Number.isSafeInteger(e.tool.transform)||!Number.isSafeInteger(e.tool.address)||!Number.isSafeInteger(e.tool.recipe)||!Number.isSafeInteger(e.tool.hydration)))throw new Error("Shader meta.json has invalid tool compatibility metadata.");if(c(e.tool)&&e.tool.compatibilities!==void 0&&(!c(e.tool.compatibilities)||Object.entries(e.tool.compatibilities).some(([t,n])=>t!=="webgpu"&&t!=="webgl"||typeof n!="string"||n.length===0)))throw new Error("Shader meta.json has invalid backend compatibility metadata.");return e}a(H,"parseShaderReceipt");var O=Object.freeze({metadata:1024*1024,receipt:2*1024*1024,manifest:32*1024*1024,semanticInput:8*1024*1024,semanticTotal:64*1024*1024,metrics:8*1024*1024,texture:128*1024*1024,packageJson:1024*1024});function oe(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"?e.code:void 0}a(oe,"errorCode");function E(e){return createHash("sha256").update(e).digest("hex")}a(E,"sha256");async function w(e){try{return await lstat(e),!0}catch(r){if(oe(r)==="ENOENT")return false;throw r}}a(w,"pathExists");function I(e,r){let t=p.relative(e,r);return t===""||!p.isAbsolute(t)&&t!==".."&&!t.startsWith(`..${p.sep}`)}a(I,"isWithin");function B(e){return JSON.stringify(e)}a(B,"displayPath");async function Me(e,r,t){let n=await open(e,"r");try{let[i,o,a]=await Promise.all([lstat(e),n.stat(),realpath(e)]);if(i.isSymbolicLink())throw new Error(`${t} must not be a symbolic link: ${B(e)}.`);if(!o.isFile())throw new Error(`${t} must be a regular file: ${B(e)}.`);if(o.size>r)throw new Error(`${t} exceeds the ${r}-byte inspection limit: ${B(e)}.`);let d=await n.readFile();if(d.byteLength>r)throw new Error(`${t} grew beyond the ${r}-byte inspection limit while being read.`);return {path:a,data:d}}finally{await n.close();}}a(Me,"readBoundedRegularFile");async function C(e,r){let t=p.dirname(e);await mkdir(t,{recursive:true});try{if((await lstat(e)).isSymbolicLink())throw new Error(`Atomic write target must not be a symbolic link: ${B(e)}.`)}catch(o){if(oe(o)!=="ENOENT")throw o}let n=p.join(t,`.${p.basename(e)}.${process.pid}.${randomUUID()}.tmp`),i;try{i=await open(n,"wx",384),await i.writeFile(r),await i.sync(),await i.close(),i=void 0,await rename(n,e);}finally{await i?.close().catch(()=>{}),await rm(n,{force:true});}}a(C,"writeAtomicRegularFile");async function _e(e,r){let t=p.dirname(e);await mkdir(t,{recursive:true});let n=p.join(t,`.${p.basename(e)}.${process.pid}.${randomUUID()}.tmp`),i;try{i=await open(n,"wx",384),await i.writeFile(r),await i.sync(),await i.close(),i=void 0;try{return await link(n,e),!0}catch(o){if(oe(o)==="EEXIST")return !1;throw o}}finally{await i?.close().catch(()=>{}),await rm(n,{force:true});}}a(_e,"writeNewRegularFile");async function Dr(e,r,t){return Me(e,r,t)}a(Dr,"readExternalRegularFile");async function U(e,r,t){let n=p.resolve(e),i=p.resolve(r);if(!I(n,i))throw new Error(`${t} escapes its allowed directory.`);let o=await lstat(i);if(o.isSymbolicLink())throw new Error(`${t} must not be a symbolic link.`);if(!o.isDirectory())throw new Error(`${t} must be a directory.`);let[a,d]=await Promise.all([realpath(n),realpath(i)]);if(!I(a,d))throw new Error(`${t} resolves outside its allowed directory.`);return d}a(U,"canonicalDirectoryWithin");async function N(e,r,t,n){let i=p.resolve(e),o=p.resolve(r);if(!I(i,o)||i===o)throw new Error(`${n} escapes its allowed directory.`);let a=await Me(o,t,n),d=await realpath(i);if(!I(d,a.path)||d===a.path)throw new Error(`${n} resolves outside its allowed directory.`);return a}a(N,"readRegularFileWithin");async function Lr(e,r,t,n=8192){let o=[await U(e,r,"Inspected directory")],a=[],d=0;for(;o.length>0;){let l=o.shift();if(l===void 0)break;let y=(await readdir(l,{withFileTypes:true})).sort((f,h)=>f.name.localeCompare(h.name));for(let f of y){if(d+=1,d>n)throw new Error(`Inspected directory exceeds the ${n}-entry limit.`);let h=p.join(l,f.name);if(f.isSymbolicLink())throw new Error(`Inspected directory contains a symbolic link: ${B(p.relative(e,h))}.`);if(f.isDirectory()){o.push(await U(e,h,"Nested inspected directory"));continue}if(f.isFile()&&t(f.name))a.push(h);else if(t(f.name))throw new Error(`Semantic input is not a regular file: ${B(h)}.`)}}return a.sort()}a(Lr,"listRegularFilesRecursively");var se="three-blocks.shaders.json",Gr=".three-blocks/shaders",zr=".three-blocks/shaders/parity",cr=/^[a-z0-9][a-z0-9_-]{0,63}$/u,ur=/^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$/u,$e=64,Be=64,Ie={schemaVersion:1,backend:"both",scenes:[{key:"default",url:"/"}]};function Jr(e="both"){return e==="both"?["webgpu","webgl"]:[e]}a(Jr,"shaderBackends");function z(e,r){return e.backend===void 0?r:r.filter(t=>t===e.backend)}a(z,"shaderSceneBackends");function Kr(e,r){return r.flatMap(t=>e.filter(n=>z(n,[t]).length>0).map(n=>({scene:n,backend:t,key:de(n.key,t)})))}a(Kr,"shaderScenePairs");function de(e,r){return r==="webgpu"?e:`${e}.webgl`}a(de,"shaderReceiptKey");function Oe(e,r,t){if(e===void 0)return t;if(typeof e!="string"||e.length===0||e.length>512||p.isAbsolute(e)||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${r} must be a bounded project-relative directory.`);let n=p.posix.normalize(e.replaceAll("\\","/")).replace(/\/+$/u,"");if(n==="."||n===".."||n.startsWith("../"))throw new Error(`${r} must stay inside the project.`);return n}a(Oe,"safeProjectDirectory");function lr(e,r){let t=Oe(e,r,"");if(typeof e!="string"||e.endsWith("/"))throw new Error(`${r} must be a project-relative file.`);return t}a(lr,"safeProjectFile");function x(e,r,t,n,i){if(e===void 0)return i;if(!Number.isSafeInteger(e)||Number(e)<t||Number(e)>n)throw new Error(`${r} must be an integer in ${t}...${n}.`);return Number(e)}a(x,"boundedInteger");function Ne(e,r,t){if(e===void 0)return t;if(typeof e!="number"||!Number.isFinite(e)||e<0||e>1)throw new Error(`${r} must be a finite ratio in 0...1.`);return e}a(Ne,"finiteRatio");function De(e,r){if(typeof e!="string"||e.length===0||e.length>2048||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${r} must be a bounded project-relative URL.`);let t;try{t=new URL(e,"http://three-blocks.invalid/");}catch{throw new Error(`${r} is not a valid URL.`)}if(t.origin!=="http://three-blocks.invalid"||t.hash.length>0)throw new Error(`${r} must stay within the project and must not contain a fragment.`);return `${t.pathname}${t.search}`}a(De,"safeBrowserUrl");function pr(e){if(!Array.isArray(e)||e.length===0||e.length>$e)throw new Error(`Shader config scenes must contain 1...${$e} entries.`);let r=new Set;return e.map((t,n)=>{if(!c(t)||typeof t.key!="string"||!cr.test(t.key))throw new Error(`Shader config scene ${n} has an invalid key.`);if(r.has(t.key))throw new Error(`Shader config scene key "${t.key}" is duplicated.`);r.add(t.key);let i=t.parityFrames,o=t.maxDiffRatio;if(t.inputs!==void 0&&(!Array.isArray(t.inputs)||t.inputs.length===0||t.inputs.length>Be))throw new Error(`Shader config scene "${t.key}" inputs must contain 1...${Be} files.`);let a=t.inputs===void 0?void 0:t.inputs.map((d,l)=>lr(d,`Shader config scene "${t.key}" input ${l}`));if(a!==void 0&&new Set(a).size!==a.length)throw new Error(`Shader config scene "${t.key}" inputs must be unique.`);if(t.runtimeMotion!==void 0&&typeof t.runtimeMotion!="boolean")throw new Error(`Shader config scene "${t.key}" runtimeMotion must be a boolean.`);if(t.backend!==void 0&&t.backend!=="webgpu"&&t.backend!=="webgl")throw new Error(`Shader config scene "${t.key}" backend must be "webgpu" or "webgl".`);return {key:t.key,url:De(t.url,`Shader config scene "${t.key}" URL`),...t.backend===void 0?{}:{backend:t.backend},requiresText:t.requiresText===true,...a===void 0?{}:{inputs:a},...i===void 0?{}:{parityFrames:x(i,`Shader config scene "${t.key}" parityFrames`,0,1e4,0)},...o===void 0?{}:{maxDiffRatio:Ne(o,`Shader config scene "${t.key}" maxDiffRatio`,.01)},...t.runtimeMotion===true?{runtimeMotion:true}:{}}})}a(pr,"parseScenes");function G(e){if(!c(e)||e.schemaVersion!==void 0&&e.schemaVersion!==1)throw new Error("Shader config must use schemaVersion 1.");let r=e.viewport;if(r!==void 0&&!c(r))throw new Error("Shader config viewport must be an object.");let t=e.parity;if(t!==void 0&&!c(t))throw new Error("Shader config parity must be an object.");let n=e.bridge;if(n!==void 0&&!c(n))throw new Error("Shader config bridge must be an object.");let i=c(n)?n.deterministicModule:void 0;i!==void 0&&De(i,"Shader deterministic module");let o=e.readiness;if(o!==void 0&&!c(o))throw new Error("Shader config readiness must be an object.");let a=c(o)?o.selector:void 0;if(a!==void 0&&(typeof a!="string"||a.length===0||a.length>512||/[\u0000-\u001f\u007f]/u.test(a)))throw new Error("Shader readiness selector must be a bounded, non-empty CSS selector.");let d=c(o)?o.global:void 0;if(d!==void 0&&(typeof d!="string"||!ur.test(d)))throw new Error("Shader readiness global must be a dot-separated JavaScript property path.");if(e.backend!==void 0&&e.backend!=="webgpu"&&e.backend!=="webgl"&&e.backend!=="both")throw new Error('Shader config backend must be "webgpu", "webgl", or "both".');let l=x(e.timeoutMs,"Shader timeoutMs",1e3,15*6e4,24e4);return {schemaVersion:1,backend:e.backend??"both",scenes:pr(e.scenes),settleFrames:x(e.settleFrames,"Shader settleFrames",0,1e4,60),settleTimeoutMs:x(e.settleTimeoutMs,"Shader settleTimeoutMs",1e3,15*6e4,3e4),browserRelaunchScenes:x(e.browserRelaunchScenes,"Shader browserRelaunchScenes",1,64,8),timeoutMs:l,maxTimeoutMs:Math.max(l,x(e.maxTimeoutMs,"Shader maxTimeoutMs",1e3,15*6e4,l)),viewport:{width:x(c(r)?r.width:void 0,"Shader viewport width",64,8192,1024),height:x(c(r)?r.height:void 0,"Shader viewport height",64,8192,640)},parity:{frames:x(c(t)?t.frames:void 0,"Shader parity frames",0,1e4,90),channelTolerance:x(c(t)?t.channelTolerance:void 0,"Shader parity channelTolerance",0,255,8),maxDiffRatio:Ne(c(t)?t.maxDiffRatio:void 0,"Shader parity maxDiffRatio",.01)},bridge:{legacyLab:c(n)&&n.legacyLab===true,...typeof i=="string"?{deterministicModule:i}:{}},readiness:{...typeof a=="string"?{selector:a}:{},...typeof d=="string"?{global:d}:{}},publicDir:Oe(e.publicDir,"Shader publicDir","public"),allowLiveBuilds:e.allowLiveBuilds!==false}}a(G,"parseShaderToolConfig");async function qr(e=process.cwd()){let r=p.resolve(e);for(;;){if(await w(p.join(r,se))||await w(p.join(r,"three-blocks.json")))return realpath(r);let t=p.join(r,"package.json");if(await w(t)){let i=await N(r,t,O.packageJson,"Project package.json"),o;try{o=JSON.parse(i.data.toString("utf8"));}catch{throw new Error(`Project package.json is not valid JSON: ${t}.`)}if(c(o)&&[o.dependencies,o.devDependencies,o.peerDependencies,o.optionalDependencies].filter(c).some(l=>typeof l.three=="string"||typeof l["three-blocks"]=="string"||typeof l["@three-blocks/devtools"]=="string"))return realpath(r)}let n=p.dirname(r);if(n===r)throw new Error(`No Three Blocks shader project found from ${JSON.stringify(p.resolve(e))}; add Three.js to package.json or pass --root.`);r=n;}}a(qr,"findShaderProjectRoot");async function ae(e){let r=await realpath(e),t=p.join(r,se);if(await w(t)){let i=await N(r,t,O.metadata,"Shader configuration");return G(JSON.parse(i.data.toString("utf8")))}let n=p.join(r,"three-blocks.json");if(await w(n)){let i=Ae(JSON.parse(await readFile(n,"utf8")));return G({schemaVersion:1,backend:"both",scenes:[{key:i.template,url:"/",requiresText:i.features.text}]})}return G(Ie)}a(ae,"loadShaderToolConfig");async function Yr(e){let r=await realpath(e);for(let o of ["vite.config.ts","vite.config.mts","vite.config.js","vite.config.mjs","vite.config.cts","vite.config.cjs"])if(await w(p.join(r,o)))return {driverKind:"vite",reason:`Detected ${o}.`};let t,n=p.join(r,"package.json");if(await w(n)){let o=await N(r,n,O.packageJson,"Project package.json"),a=JSON.parse(o.data.toString("utf8"));c(a)&&(t=a);}let i=a(o=>[t?.dependencies,t?.devDependencies,t?.peerDependencies,t?.optionalDependencies].some(a=>c(a)&&typeof a[o]=="string"),"hasDependency");if(i("vite"))return {driverKind:"vite",reason:"Detected the Vite dependency."};for(let o of ["dist","build","out"])if(await w(p.join(r,o,"index.html")))return {driverKind:"static",serve:o,reason:`Detected the built ${o}/index.html application.`};if(i("next"))throw new Error("Detected Next.js without an attach URL. Run `shaders capture` without an explicit driver or URL to preview the withThreeBlocksNext adapter and start a project-local capture server, or pass --url <local-url> for a server you manage.");if(i("webpack")||i("esbuild")||i("rollup"))throw new Error("Detected a non-Vite bundler but no static index.html. Run `shaders capture` without an explicit driver or URL to preview adapter wiring and build the project, or build it yourself and pass --driver static --serve <directory>.");return {driverKind:"vite",reason:"Using the Vite golden-path driver."}}a(Yr,"inferShaderCaptureTarget");async function Xr(e){let r=await realpath(e),t=p.join(r,se);if(await w(t))return {config:await ae(r),file:t,created:false};let n=p.join(r,"three-blocks.json");if(await w(n))return {config:await ae(r),file:n,created:false};let i=Ie,o=G(i),a=await _e(t,`${JSON.stringify(i,null,2)}
|
|
2
|
+
`);return {config:a?o:await ae(r),file:t,created:a}}a(Xr,"ensureShaderToolConfig");function ce(e,r="webgpu"){if(/^0\.185\./u.test(e))return r==="webgl"?THREE_WEBGL_R185_COMPATIBILITY:THREE_WEBGPU_R185_COMPATIBILITY;if(e===THREE_R186DEV_VERSION&&r==="webgpu")return THREE_WEBGPU_R186DEV_COMPATIBILITY;throw new Error(`Three.js ${e} is outside the supported shader compatibility contracts.`)}a(ce,"shaderCompatibilityForThree");var ue="0.1.0";var he=60,ye="timing.local.json",ge="timing.json",Se="parity.json",J=4096,wr=4096;function pe(e,r,t=8192){if(typeof e!="string"||e.length===0||e.length>t||/[\u0000\u007f]/u.test(e))throw new Error(`${r} must be a bounded non-empty string.`);return e}a(pe,"boundedString");function m(e,r,t=true){if(typeof e!="number"||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e))throw new Error(`${r} must be a non-negative ${t?"integer":"finite number"}.`);return e}a(m,"nonNegativeNumber");function br(e){if(!c(e))throw new Error("Shader capture stats are missing.");let r={buildCalls:m(e.buildCalls,"capture stats.buildCalls"),renderBuilds:m(e.renderBuilds,"capture stats.renderBuilds"),computeBuilds:m(e.computeBuilds,"capture stats.computeBuilds"),registeredBuilds:m(e.registeredBuilds,"capture stats.registeredBuilds"),registeredRenderBuilds:m(e.registeredRenderBuilds,"capture stats.registeredRenderBuilds"),registeredComputeBuilds:m(e.registeredComputeBuilds,"capture stats.registeredComputeBuilds"),buildMs:m(e.buildMs,"capture stats.buildMs",false),syncBuildMs:m(e.syncBuildMs,"capture stats.syncBuildMs",false),asyncBuildElapsedMs:m(e.asyncBuildElapsedMs,"capture stats.asyncBuildElapsedMs",false),precompiledSetupMs:m(e.precompiledSetupMs,"capture stats.precompiledSetupMs",false),maxSyncBuildMs:m(e.maxSyncBuildMs??e.syncBuildMs,"capture stats.maxSyncBuildMs",false),maxPrecompiledSetupMs:m(e.maxPrecompiledSetupMs??e.precompiledSetupMs,"capture stats.maxPrecompiledSetupMs",false),hydrationMs:m(e.hydrationMs??0,"capture stats.hydrationMs",false),maxHydrationMs:m(e.maxHydrationMs??e.hydrationMs??0,"capture stats.maxHydrationMs",false),injected:m(e.injected,"capture stats.injected"),injectedRender:m(e.injectedRender,"capture stats.injectedRender"),injectedCompute:m(e.injectedCompute,"capture stats.injectedCompute"),missed:m(e.missed,"capture stats.missed"),missedRender:m(e.missedRender,"capture stats.missedRender"),missedCompute:m(e.missedCompute,"capture stats.missedCompute"),...Array.isArray(e.missedKeys)&&e.missedKeys.every(t=>typeof t=="string")?{missedKeys:e.missedKeys.slice(0,J)}:{}};if(r.renderBuilds+r.computeBuilds!==r.buildCalls||r.registeredRenderBuilds+r.registeredComputeBuilds!==r.registeredBuilds||r.injectedRender+r.injectedCompute!==r.injected||r.missedRender+r.missedCompute!==r.missed||r.registeredBuilds>r.buildCalls||Math.abs(r.syncBuildMs+r.asyncBuildElapsedMs-r.buildMs)>.001||r.maxSyncBuildMs>r.syncBuildMs+.001||r.maxPrecompiledSetupMs>r.precompiledSetupMs+.001||r.maxHydrationMs>r.hydrationMs+.001)throw new Error("Shader capture stats totals are inconsistent.");return r}a(br,"captureStats");function Er(e){if(!Array.isArray(e)||e.length>J)throw new Error("Shader capture skipped builds are invalid.");return e.map((r,t)=>{if(!c(r)||r.kind!=="render"&&r.kind!=="compute")throw new Error(`Shader capture skipped build ${t} is invalid.`);return {kind:r.kind,name:pe(r.name,`skipped build ${t} name`,512),reason:pe(r.reason,`skipped build ${t} reason`)}})}a(Er,"skippedBuilds");function kr(e){let r=0,t=0,n=0,i=0;for(let o of Object.values(e.entries)){let a=e.states[o];a!==void 0&&((a.vertex!==null||a.fragment!==null)&&r++,a.vertex!==null&&t++,a.fragment!==null&&n++,a.compute!==null&&i++);}return {render:r,vertex:t,fragment:n,compute:i}}a(kr,"shaderCoverage");function ft(e,r){if(!c(e))throw new Error("Shader capture payload must be an object.");if(e.scene!==r.scene)throw new Error(`Shader capture scene does not match "${r.scene}".`);if(e.protocolVersion!==2)throw new Error("Shader capture protocolVersion must be 2.");let t=r.backend??"webgpu",n=ce(r.runtime.three,t);if(e.compatibility!==n)throw new Error(`Shader capture compatibility must be "${n}".`);if(!c(e.entries))throw new Error("Shader capture entries must be an object.");if(typeof e.requiresSetup!="boolean")throw new Error("Shader capture requiresSetup must be boolean.");let i=Object.keys(e.entries).length;if(i>J)throw new Error(`Shader capture must contain at most ${J} entries.`);if(!Array.isArray(e.errors)||e.errors.length>wr)throw new Error("Shader capture errors are invalid.");let o=e.errors.map((R,u)=>pe(R,`capture error ${u}`,64*1024));if(o.length>0)throw new Error(`Shader capture failed:
|
|
3
|
+
- ${o.join(`
|
|
4
|
+
- `)}`);let a=Er(e.skipped);if(i===0&&(t!=="webgl"||a.length===0))throw new Error("Shader capture must contain an entry unless WebGL explicitly skipped every live build.");let d=br(e.stats),l=c(e.timing)?e.timing:void 0,y=l===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(R=>{let u=l[R];if(u===void 0)return [];if(typeof u!="number"||!Number.isFinite(u)||u<0)throw new Error(`Shader capture timing.${R} is invalid.`);return [[R,u]]})),f;if(e.provenance!==void 0){if(!c(e.provenance)||typeof e.provenance.userAgent!="string"||e.provenance.userAgent.length>1024||typeof e.provenance.adapter!="string"||e.provenance.adapter.length>1024||!Array.isArray(e.provenance.features)||e.provenance.features.length>256||!e.provenance.features.every(R=>typeof R=="string"&&R.length<=128))throw new Error("Shader capture provenance is invalid.");f={userAgent:e.provenance.userAgent,adapter:e.provenance.adapter,features:[...new Set(e.provenance.features)].sort()};}let h=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:r.scene,three:r.runtime.three,threeBlocks:r.runtime.threeBlocks,runtime:{id:n,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...e.automatic===void 0?{}:{automatic:e.automatic},requiresSetup:e.requiresSetup,modules:e.modules,nodes:e.nodes,layouts:e.layouts,attributePlans:e.attributePlans,updatePlans:e.updatePlans,requirementPlans:e.requirementPlans,states:e.states,entries:e.entries,...e.fallbacks===void 0?{}:{fallbacks:e.fallbacks}}),k=kr(h);if(d.registeredRenderBuilds<k.render||d.registeredComputeBuilds<k.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:r.scene,backend:t,manifest:h,skipped:a,stats:d,coverage:k,...y===void 0?{}:{timing:y},...f===void 0?{}:{provenance:f}}}a(ft,"validateShaderCapture");function A(e,r=0){let t=" ".repeat(r),n=" ".repeat(r+1);if(Array.isArray(e))return e.length===0?"[]":e.every(o=>o===null||["number","string","boolean"].includes(typeof o))?JSON.stringify(e):`[
|
|
5
|
+
${e.map(o=>`${n}${A(o,r+1)}`).join(`,
|
|
6
|
+
`)}
|
|
7
|
+
${t}]`;if(e!==null&&typeof e=="object"){let o=e,a=Object.keys(o).sort();return a.length===0?"{}":`{
|
|
8
|
+
${a.map(d=>{let l=o[d];return `${n}${JSON.stringify(d)}: ${A(l,r+1)}`}).join(`,
|
|
9
|
+
`)}
|
|
10
|
+
${t}}`}let i=JSON.stringify(e);if(i===void 0)throw new Error("Shader artifact contains a non-serializable value.");return i}a(A,"stableStringify");function Rr(e){return ["// GENERATED FILE \u2014 do not edit by hand.","// Produced by @three-blocks/devtools.","import type { PrecompiledManifest } from 'three-blocks/shaders';","",`export default ${A(e)} satisfies PrecompiledManifest;`,""].join(`
|
|
11
|
+
`)}a(Rr,"serializeShaderManifest");function Fe(e,r){if(typeof e!="string"||e.length===0||e.length>256||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${r} is invalid.`);return e}a(Fe,"timingLabel");function fe(e){if(!c(e)||e.schemaVersion!==3||e.source!=="latest-local-capture"&&e.source!=="committed-capture"||typeof e.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(e.receiptHash)||typeof e.measuredAt!="string"||!Number.isFinite(Date.parse(e.measuredAt))||!c(e.scenes))throw new Error("Shader timing is invalid.");let r={};for(let[n,i]of Object.entries(e.scenes)){if(n.length===0||n.length>128||!c(i))throw new Error("Shader timing scene is invalid.");let o={builds:m(i.builds,`timing ${n}.builds`),setupMeasured:i.setupMeasured===true,liveBuildMs:m(i.liveBuildMs,`timing ${n}.liveBuildMs`,false),precompiledBuildMs:m(i.precompiledBuildMs,`timing ${n}.precompiledBuildMs`,false),avoidedBuildMs:m(i.avoidedBuildMs,`timing ${n}.avoidedBuildMs`,false),runs:m(i.runs,`timing ${n}.runs`),spreadMs:m(i.spreadMs,`timing ${n}.spreadMs`,false)};if(o.runs<1)throw new Error(`Shader timing runs are invalid for scene "${n}".`);if(Math.abs(o.avoidedBuildMs-Math.max(0,o.liveBuildMs-o.precompiledBuildMs))>.001)throw new Error(`Shader timing delta is inconsistent for scene "${n}".`);r[n]=o;}if(Object.keys(r).length===0)throw new Error("Shader timing contains no scenes.");let t={schemaVersion:3,receiptHash:e.receiptHash,measuredAt:e.measuredAt,scenes:r};return e.source==="latest-local-capture"?{...t,source:"latest-local-capture"}:{...t,source:"committed-capture",adapter:Fe(e.adapter,"Shader timing adapter"),platform:Fe(e.platform,"Shader timing platform")}}a(fe,"parseShaderTiming");function K(e){return /^[a-z0-9][a-z0-9_-]{0,63}(?:\.webgl)?$/u.test(e)}a(K,"validParityScene");function Ve(e){return typeof e=="string"&&Number.isFinite(Date.parse(e))}a(Ve,"validParityTimestamp");function we(e){if(!c(e))throw new Error("Shader parity evidence is invalid.");if(e.schemaVersion===1){if(typeof e.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(e.receiptHash)||!Ve(e.verifiedAt)||!Array.isArray(e.scenes)||e.scenes.length===0||e.scenes.length>64||!e.scenes.every(n=>typeof n=="string"&&K(n)))throw new Error("Shader parity evidence is invalid.");return {schemaVersion:1,receiptHash:e.receiptHash,verifiedAt:e.verifiedAt,scenes:[...new Set(e.scenes)].sort()}}if(e.schemaVersion!==2||!c(e.scenes))throw new Error("Shader parity evidence is invalid.");let r=Object.entries(e.scenes);if(r.length===0||r.length>64)throw new Error("Shader parity evidence is invalid.");let t={};for(let[n,i]of r.sort(([o],[a])=>o.localeCompare(a))){if(!K(n)||!c(i)||typeof i.fingerprint!="string"||!/^[a-f0-9]{64}$/u.test(i.fingerprint)||!Ve(i.verifiedAt))throw new Error("Shader parity evidence is invalid.");t[n]={fingerprint:i.fingerprint,verifiedAt:i.verifiedAt};}return {schemaVersion:2,scenes:t}}a(we,"parseShaderParityEvidence");function me(e,r){let t=e.scenes[r];if(t===void 0)throw new Error(`Shader receipt has no scene "${r}" for parity evidence.`);return E(A({runtime:{three:e.runtime.three,threeBlocks:e.runtime.threeBlocks,threeBlocksShaderClosure:e.runtime.threeBlocksShaderClosure},...e.tool===void 0?{}:{tool:e.tool},scene:t}))}a(me,"shaderSceneParityFingerprint");async function q(e,r,t,n){let i=p.join(e,t);try{if(!await w(i))return;let o=await lstat(i);if(o.isSymbolicLink()||!o.isFile()||o.size>1024*1024)return;let a=fe(JSON.parse(await readFile(i,"utf8")));return a.source===n&&a.receiptHash===E(r)?a:void 0}catch{return}}a(q,"readShaderTimingFile");async function mt(e,r){let t=await q(e,r,ye,"latest-local-capture");return t?.source==="latest-local-capture"?t:void 0}a(mt,"readShaderLocalTiming");async function ht(e,r){return await q(e,r,ye,"latest-local-capture")??await q(e,r,ge,"committed-capture")}a(ht,"readShaderTiming");async function ze(e,r){let t=p.join(e,Se);try{if(!await w(t))return;let n=await lstat(t);if(n.isSymbolicLink()||!n.isFile()||n.size>1024*1024)return;let i=we(JSON.parse(await readFile(t,"utf8"))),o=H(JSON.parse(Buffer.from(r).toString("utf8"))),a={};if(i.schemaVersion===1){if(i.receiptHash!==E(r))return;for(let d of i.scenes)o.scenes[d]!==void 0&&(a[d]={fingerprint:me(o,d),verifiedAt:i.verifiedAt});}else for(let[d,l]of Object.entries(i.scenes))o.scenes[d]===void 0||l.fingerprint!==me(o,d)||(a[d]=l);return Object.keys(a).length===0?void 0:{schemaVersion:2,scenes:a}}catch{return}}a(ze,"readShaderParityEvidence");async function yt(e,r){let t=await q(e,r,ge,"committed-capture");return t?.source==="committed-capture"?t:void 0}a(yt,"readShaderCommittedTiming");async function Je(e,r,t){let n=await Y(e),i=p.join(n,"meta.json"),o=await lstat(i);if(o.isSymbolicLink()||!o.isFile())throw new Error("Shader receipt must be a regular file before timing.");let a=await readFile(i),d=new Date().toISOString(),l=Object.fromEntries(Object.entries(r).sort(([h],[k])=>h.localeCompare(k))),y=fe({schemaVersion:3,receiptHash:E(a),measuredAt:d,source:"latest-local-capture",scenes:l});if(await C(p.join(n,ye),`${A(y)}
|
|
12
|
+
`),t===void 0)return {local:y};let f=fe({schemaVersion:3,receiptHash:E(a),measuredAt:d,source:"committed-capture",adapter:t.adapter,platform:t.platform,scenes:l});return await C(p.join(n,ge),`${A(f)}
|
|
13
|
+
`),{local:y,committed:f}}a(Je,"writeShaderTimings");async function gt(e,r){return (await Je(e,r)).local}a(gt,"writeShaderLocalTiming");async function St(e,r,t){if(r.length===0||r.length>64||r.some(k=>!K(k)))throw new Error("Shader parity evidence must contain 1...64 valid scene keys.");let n=await Y(e),i=p.join(n,"meta.json"),o=await lstat(i);if(o.isSymbolicLink()||!o.isFile())throw new Error("Shader receipt must be a regular file before parity evidence.");let a=await readFile(i);if(t!==void 0&&E(a)!==E(t))throw new Error("Shader receipt changed during browser parity verification; completed observations were not attached to the new receipt.");let d=H(JSON.parse(a.toString("utf8"))),l=await ze(n,a),y=new Date().toISOString(),f={...l?.scenes};for(let k of [...new Set(r)].sort())f[k]={fingerprint:me(d,k),verifiedAt:y};let h=we({schemaVersion:2,scenes:f});return await C(p.join(n,Se),`${A(h)}
|
|
14
|
+
`),h}a(St,"writeShaderParityEvidence");async function wt(e,r,t){if(r.length===0||r.length>64||r.some(f=>!K(f)))throw new Error("Shader parity invalidation must contain 1...64 valid scene keys.");let n=await Y(e),i=await readFile(p.join(n,"meta.json"));if(E(i)!==E(t))throw new Error("Shader receipt changed before prior parity evidence could be invalidated.");let o=await ze(n,i);if(o===void 0)return;let a=new Set(r),d=Object.fromEntries(Object.entries(o.scenes).filter(([f])=>!a.has(f))),l=p.join(n,Se);if(Object.keys(d).length===0){await unlink(l).catch(f=>{if(!c(f)||f.code!=="ENOENT")throw f});return}let y=we({schemaVersion:2,scenes:d});await C(l,`${A(y)}
|
|
15
|
+
`);}a(wt,"removeShaderParityEvidence");async function bt(e,r,t){let n=await Je(e,r,t);if(n.committed===void 0)throw new Error("Committed shader timing was not written.");return {local:n.local,committed:n.committed}}a(bt,"writeShaderTimingTwins");async function He(e){if(!await w(e)){await mkdir(e);return}let r=await lstat(e);if(r.isSymbolicLink()||!r.isDirectory())throw new Error(`Shader artifact path is not a real directory: ${e}.`)}a(He,"assertDirectory");async function Y(e){let r=p.resolve(e),t=p.join(r,".three-blocks");await He(t);let n=p.join(t,"shaders");return await He(n),n}a(Y,"artifactRoot");async function Et(e){let r=await Y(e.root),t=e.backends??["webgpu"],n=Object.fromEntries(t.map(u=>[u,ce(e.runtime.three,u)])),i=p.resolve(e.root),o=p.resolve(i,e.publicDirectory??"public");if(!I(i,o)||o===i)throw new Error("Shader public directory must stay inside the project root.");let a=p.join(o,"three-blocks","shaders");await mkdir(a,{recursive:true}),await U(i,a,"Shader static-asset directory");let d={},l=[];for(let u of [...e.scenes].sort((T,j)=>T.key.localeCompare(j.key))){let T=e.inputs.get(u.key);if(T===void 0)throw new Error(`Shader input matrix is missing scene "${u.key}".`);for(let j of z(u,t)){let _=de(u.key,j),P=e.captures.get(_);if(P===void 0){let g=e.previousReceipt?.scenes[_];if(g===void 0)continue;let re=await readFile(p.join(r,g.artifact));if(E(re)!==g.artifactHash)throw new Error(`Preserved shader artifact checksum differs for "${_}".`);if(g.asset!==void 0&&g.assetHash!==void 0){let te=await readFile(p.join(o,g.asset));if(E(te)!==g.assetHash)throw new Error(`Preserved static shader manifest checksum differs for "${_}".`)}d[_]={...g,backend:j,inputs:Object.fromEntries(Object.entries(T).sort(([te],[er])=>te.localeCompare(er)))},l.push(g.artifact),g.asset!==void 0&&l.push(p.relative(i,p.join(o,g.asset)).split(p.sep).join("/"));continue}if(P.scene!==u.key||P.backend!==j||P.manifest.scene!==u.key)throw new Error(`Capture matrix scene/backend "${_}" is inconsistent.`);let Z=`${u.key}.${j}.ts`,Q=Rr(P.manifest);await C(p.join(r,Z),Q),l.push(Z);let ee=`three-blocks/shaders/${u.key}.${j}.json`,ke=`${A(P.manifest)}
|
|
16
|
+
`;await C(p.join(o,ee),ke),l.push(p.relative(i,p.join(o,ee)).split(p.sep).join("/"));let Re=P.skipped.filter(g=>g.kind==="render").length,Qe=P.skipped.length-Re;d[_]={backend:j,artifact:Z,artifactHash:E(Q),asset:ee,assetHash:E(ke),inputs:Object.fromEntries(Object.entries(T).sort(([g],[re])=>g.localeCompare(re))),coverage:P.coverage,bytes:Buffer.byteLength(Q),skipped:{render:Re,compute:Qe}};}}let y=[...e.captures.values()].find(u=>u.provenance!==void 0)?.provenance??e.previousReceipt?.runtime.capture,f={schemaVersion:2,runtime:{...e.runtime,...y===void 0?{}:{capture:y}},tool:{name:"@three-blocks/devtools",version:ue,compatibility:n[t[0]??"webgpu"],compatibilities:n,transform:he,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},scenes:d},h=new Set(l);for(let u of await readdir(r,{withFileTypes:true}))if(!(!/\.(?:webgpu|webgl)\.ts$/u.test(u.name)||h.has(u.name))){if(u.isSymbolicLink()||!u.isFile())throw new Error(`Orphan shader artifact is not a regular file: ${u.name}.`);await unlink(p.join(r,u.name));}let k=new Set(e.scenes.flatMap(u=>z(u,t).map(T=>`${u.key}.${T}.json`))),R=new Set(Object.values(e.previousReceipt?.scenes??{}).map(u=>u.asset===void 0?void 0:p.posix.basename(u.asset)).filter(u=>u!==void 0));try{let u=H(JSON.parse(await readFile(p.join(r,"meta.json"),"utf8")));for(let T of Object.values(u.scenes))T.asset!==void 0&&R.add(p.posix.basename(T.asset));}catch{}for(let u of await readdir(a,{withFileTypes:true}))if(!(!u.name.endsWith(".json")||k.has(u.name))&&R.has(u.name)){if(u.isSymbolicLink()||!u.isFile())throw new Error(`Orphan shader static asset is not a regular file: ${u.name}.`);await unlink(p.join(a,u.name));}return await C(p.join(r,"meta.json"),`${A(f)}
|
|
17
|
+
`),l.push("meta.json"),{directory:r,receipt:f,files:l}}a(Et,"writeShaderArtifacts");var F;async function X(){F===void 0&&(F=(async()=>{let r=createRequire(p.join(process.cwd(),"package.json")).resolve("@three-blocks/devtools/browser/shader-capture"),t=p.resolve(p.dirname(r),"../..");return (await N(t,r,O.metadata,"Shader capture browser runtime")).data.toString("utf8")})());let e=F;try{return await e}catch(r){throw F===e&&(F=void 0),r}}a(X,"loadShaderCaptureRuntimeSource");var Ke="virtual:three-blocks-shader-capture-client",qe="\0three-blocks:shader-capture-client",Ee="virtual:three-blocks-shader-capture-runtime",Ye="\0three-blocks:shader-capture-runtime";async function Ot(){let e=await X(),r=e.replace(/\bexport\{[^{}]*\};?\s*$/u,"");if(r===e)throw new Error("Shader capture browser runtime no longer has the expected final ESM export list.");return r}a(Ot,"loadShaderCaptureRuntimeScriptSource");function jr(e){let r=e.split("?",1)[0];return r===void 0?false:r.split(p.sep).join("/").endsWith("/build/three.webgpu.js")}a(jr,"isThreeWebGPUModule");function Ze(e){let r=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u.exec(e);return r?.[1]==="0"&&r[2]==="185"}a(Ze,"supportedVersion");function Cr(e,r,t={}){if(!Ze(r))throw new Error(`Shader provider transform ${THREE_WEBGPU_R185_COMPATIBILITY} supports Three.js 0.185.x; received "${r}".`);let n=transformThreeWebgpuProviderHooks(e,{threeVersion:r,...t.threeRevision===void 0?{}:{threeRevision:t.threeRevision},id:"three/build/three.webgpu.js"}),i=n.state==="already-applied",o=n.code;return t.instrumentCapture&&(o=transformThreeWebgpuCaptureInstrumentation(o,{...t.captureRuntimeImport===void 0?{}:{runtimeImport:t.captureRuntimeImport},...t.forceWebGL===true?{forceWebGL:true}:{}}).code),{code:o,alreadyPresent:i,captureApplied:t.instrumentCapture===true}}a(Cr,"applyShaderProviderTransform");var Mr=/this\.trackTimestamp\s*=\s*\(\s*parameters\.trackTimestamp\s*===\s*true\s*\);/gu,_r="Object.defineProperty( this, 'trackTimestamp', { get: () => false, set: () => {} } );";function Nt(e,r={}){if(!Ze(e))throw new Error(`Shader provider transform ${THREE_WEBGPU_R185_COMPATIBILITY} supports Three.js 0.185.x; received "${e}".`);let t={seen:false,applied:false,alreadyPresent:false};return {plugin:{name:"three-blocks:shader-provider-transform",enforce:"pre",config(){return {optimizeDeps:{exclude:["three","three/webgpu","three/tsl"]},resolve:{dedupe:["three"]}}},resolveId(i){return r.capture&&i===Ke?qe:r.capture&&i===Ee?Ye:null},async load(i){return r.capture?i===Ye?X():i===qe?[`export * from '${Ee}';`,`import { configureThreeBlocksShaderCapture } from '${Ee}';`,`configureThreeBlocksShaderCapture( ${JSON.stringify({capture:r.capture.capture,backend:r.capture.forceWebGL===true?"webgl":"webgpu",forceLive:r.capture.forceLive,driven:r.capture.driven,settleFrames:r.capture.settleFrames,settleTimeoutMs:r.capture.settleTimeoutMs,visibilityGuard:r.capture.visibilityGuard,captureId:r.capture.captureId,sessionKey:r.capture.sessionKey,token:r.capture.token,readiness:r.capture.readiness??{},transform:he})} );`].join(`
|
|
18
|
+
`):null:null},transform(i,o){if(!jr(o))return null;t.seen=true,t.id=o;try{let a=Cr(i,e,{instrumentCapture:r.capture!==void 0,forceWebGL:r.capture?.forceWebGL===!0,...r.capture!==void 0?{captureRuntimeImport:Ke}:{}}),d=r.disableTimestampQueries===!0?a.code.replace(Mr,_r):a.code;if(r.disableTimestampQueries===!0&&d===a.code)throw new Error("Three.js timestamp tracking anchor drifted; refusing software WebGPU capture.");return t.applied=!0,t.alreadyPresent=a.alreadyPresent,t.captureApplied=a.captureApplied,d===i?null:{code:d,map:null}}catch(a){throw t.error=a instanceof Error?a.message:String(a),a}}},status:t}}a(Nt,"createShaderProviderTransform");function Dt(e){if(e.error)throw new Error(e.error);if(!e.seen||!e.applied)throw new Error(`The version-gated shader provider transform was not applied (${e.seen?"module seen":"three/webgpu not seen"}).`)}a(Dt,"assertShaderProviderTransform");export{ue as A,he as B,ye as C,ge as D,Se as E,kr as F,ft as G,A as H,Rr as I,mt as J,ht as K,ze as L,yt as M,gt as N,St as O,wt as P,bt as Q,Et as R,X as S,Ke as T,Ot as U,jr as V,Cr as W,Nt as X,Dt as Y,c as a,Ae as b,H as c,O as d,oe as e,E as f,w as g,I as h,C as i,Dr as j,U as k,N as l,Lr as m,se as n,Gr as o,zr as p,Jr as q,z as r,Kr as s,de as t,G as u,qr as v,ae as w,Yr as x,Xr as y,ce as z};
|