@three-blocks/devtools 1.0.0-alpha.176.g8ff8a72e6369 → 1.0.0-alpha.190.g3ffe5c0ecc9c

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/LICENSE +1 -2
  3. package/NOTICE +19 -27
  4. package/README.md +89 -144
  5. package/dist/browser/shader-capture.js +2 -2
  6. package/dist/{browser-smoke-76626IZQ.js → browser-smoke-HB7ZXQGR.js} +1 -1
  7. package/dist/chunk-3HTNEAVD.cjs +1 -0
  8. package/dist/chunk-3TQVLKUH.js +14 -0
  9. package/dist/chunk-54BHFG2E.js +76 -0
  10. package/dist/{chunk-ZKK6E42X.js → chunk-77HY5X2T.js} +1 -1
  11. package/dist/chunk-NEWSG5RX.js +3 -0
  12. package/dist/chunk-UQOPSJR6.js +6 -0
  13. package/dist/chunk-WNNN3UJI.js +93 -0
  14. package/dist/chunk-ZKXUYNSG.js +18 -0
  15. package/dist/cli.js +21 -21
  16. package/dist/index.d.ts +14 -10
  17. package/dist/index.js +21 -21
  18. package/dist/shader-browser-6TM4RNUL.js +2 -0
  19. package/dist/shader-browser-ZHG2JISC.js +1 -0
  20. package/dist/shader-capture-server.d.ts +6 -8
  21. package/dist/shader-capture-server.js +15 -15
  22. package/dist/{shader-config-4EXO5DKK.js → shader-config-BYBJUL3C.js} +1 -1
  23. package/dist/{shader-transform-CUkZn5Oa.d.ts → shader-transform-DSFaVrux.d.ts} +2 -0
  24. package/dist/{shader-watch-QHTNTSZE.js → shader-watch-Z3VGP4QB.js} +1 -1
  25. package/dist/shader-workflow-SO7WCR4Y.js +2 -0
  26. package/dist/{status-DV2BYZHR.js → status-CFJSWBDI.js} +1 -1
  27. package/dist/transform.cjs +1 -1
  28. package/dist/transform.d.ts +1 -1
  29. package/dist/transform.js +1 -1
  30. package/dist/webpack-loader.cjs +1 -1
  31. package/dist/webpack-loader.d.ts +1 -1
  32. package/dist/webpack-loader.js +1 -1
  33. package/package.json +3 -3
  34. package/dist/chunk-26FK4CRS.js +0 -6
  35. package/dist/chunk-4EHPYBKA.cjs +0 -1
  36. package/dist/chunk-HRYYNBVC.js +0 -3
  37. package/dist/chunk-INDAJN42.js +0 -94
  38. package/dist/chunk-ME3X2KFY.js +0 -14
  39. package/dist/chunk-SCJNCGMF.js +0 -17
  40. package/dist/chunk-VGJ3V4QQ.js +0 -78
  41. package/dist/shader-browser-65V22LLL.js +0 -1
  42. package/dist/shader-browser-JII6ZFCW.js +0 -2
  43. package/dist/shader-workflow-U4G565EB.js +0 -2
@@ -1,94 +0,0 @@
1
- #!/usr/bin/env node
2
- import {b as b$1,c}from'./chunk-NE7SC2BX.js';import {a as a$3}from'./chunk-ZT6T2W4B.js';import {a as a$2,c as c$2}from'./chunk-ZDNZCQUQ.js';import {a as a$1,c as c$1,d,f,e,i,j,k as k$1}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import k from'process';import {createServer}from'http';import {createRequire}from'module';import {mkdtemp,rm,lstat,readFile,mkdir,readdir,unlink,realpath}from'fs/promises';import g from'path';import {tmpdir}from'os';import {pathToFileURL}from'url';import {THREE_WEBGPU_R185_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';var A=3,xe="timing.local.json",je="timing.json",Oe="parity.json",q=4096,dr=4096;function re(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(re,"boundedString");function b(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(b,"nonNegativeNumber");function cr(r){if(!a$2(r))throw new Error("Shader capture stats are missing.");let e={buildCalls:b(r.buildCalls,"capture stats.buildCalls"),renderBuilds:b(r.renderBuilds,"capture stats.renderBuilds"),computeBuilds:b(r.computeBuilds,"capture stats.computeBuilds"),registeredBuilds:b(r.registeredBuilds,"capture stats.registeredBuilds"),registeredRenderBuilds:b(r.registeredRenderBuilds,"capture stats.registeredRenderBuilds"),registeredComputeBuilds:b(r.registeredComputeBuilds,"capture stats.registeredComputeBuilds"),buildMs:b(r.buildMs,"capture stats.buildMs",false),injected:b(r.injected,"capture stats.injected"),injectedRender:b(r.injectedRender,"capture stats.injectedRender"),injectedCompute:b(r.injectedCompute,"capture stats.injectedCompute"),missed:b(r.missed,"capture stats.missed"),missedRender:b(r.missedRender,"capture stats.missedRender"),missedCompute:b(r.missedCompute,"capture stats.missedCompute"),...Array.isArray(r.missedKeys)&&r.missedKeys.every(t=>typeof t=="string")?{missedKeys:r.missedKeys.slice(0,q)}:{}};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)throw new Error("Shader capture stats totals are inconsistent.");return e}a(cr,"captureStats");function ur(r){if(!Array.isArray(r)||r.length>q)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:re(e.name,`skipped build ${t} name`,512),reason:re(e.reason,`skipped build ${t} reason`)}})}a(ur,"skippedBuilds");function lr(r){let e=0,t=0,n=0,i=0;for(let a of Object.values(r.entries)){let s=r.states[a];s!==void 0&&((s.vertex!==null||s.fragment!==null)&&e++,s.vertex!==null&&t++,s.fragment!==null&&n++,s.compute!==null&&i++);}return {render:e,vertex:t,fragment:n,compute:i}}a(lr,"shaderCoverage");function Xr(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.");if(r.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY)throw new Error(`Shader capture compatibility must be "${THREE_WEBGPU_R185_COMPATIBILITY}".`);if(!a$2(r.entries))throw new Error("Shader capture entries must be an object.");let t=Object.keys(r.entries).length;if(t===0||t>q)throw new Error(`Shader capture must contain 1...${q} entries.`);if(!Array.isArray(r.errors)||r.errors.length>dr)throw new Error("Shader capture errors are invalid.");let n=r.errors.map((h,o)=>re(h,`capture error ${o}`,64*1024));if(n.length>0)throw new Error(`Shader capture failed:
3
- - ${n.join(`
4
- - `)}`);let i=ur(r.skipped),a=cr(r.stats),s=a$2(r.timing)?r.timing:void 0,c=s===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(h=>{let o=s[h];if(o===void 0)return [];if(typeof o!="number"||!Number.isFinite(o)||o<0)throw new Error(`Shader capture timing.${h} is invalid.`);return [[h,o]]})),u;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(h=>typeof h=="string"&&h.length<=128))throw new Error("Shader capture provenance is invalid.");u={userAgent:r.provenance.userAgent,adapter:r.provenance.adapter,features:[...new Set(r.provenance.features)].sort()};}let p=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:e.scene,three:e.runtime.three,threeBlocks:e.runtime.threeBlocks,runtime:{id:THREE_WEBGPU_R185_COMPATIBILITY,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...r.automatic===void 0?{}:{automatic:r.automatic},modules:r.modules,nodes:r.nodes,layouts:r.layouts,attributePlans:r.attributePlans,updatePlans:r.updatePlans,requirementPlans:r.requirementPlans,states:r.states,entries:r.entries}),f=lr(p);if(a.registeredRenderBuilds<f.render||a.registeredComputeBuilds<f.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:e.scene,manifest:p,skipped:i,stats:a,coverage:f,...c===void 0?{}:{timing:c},...u===void 0?{}:{provenance:u}}}a(Xr,"validateShaderCapture");function P(r,e=0){let t=" ".repeat(e),n=" ".repeat(e+1);if(Array.isArray(r))return r.length===0?"[]":r.every(a=>a===null||["number","string","boolean"].includes(typeof a))?JSON.stringify(r):`[
5
- ${r.map(a=>`${n}${P(a,e+1)}`).join(`,
6
- `)}
7
- ${t}]`;if(r!==null&&typeof r=="object"){let a=r,s=Object.keys(a).sort();return s.length===0?"{}":`{
8
- ${s.map(c=>{let u=a[c];return `${n}${JSON.stringify(c)}: ${P(u,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(P,"stableStringify");function mr(r){return ["// GENERATED FILE \u2014 do not edit by hand.","// Produced by @three-blocks/devtools.","import type { PrecompiledManifest } from 'three-blocks/shaders';","",`export default ${P(r)} satisfies PrecompiledManifest;`,""].join(`
11
- `)}a(mr,"serializeShaderManifest");function Re(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(Re,"timingLabel");function te(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 a={builds:b(i.builds,`timing ${n}.builds`),liveBuildMs:b(i.liveBuildMs,`timing ${n}.liveBuildMs`,false),precompiledBuildMs:b(i.precompiledBuildMs,`timing ${n}.precompiledBuildMs`,false),avoidedBuildMs:b(i.avoidedBuildMs,`timing ${n}.avoidedBuildMs`,false),runs:b(i.runs,`timing ${n}.runs`),spreadMs:b(i.spreadMs,`timing ${n}.spreadMs`,false)};if(a.runs<1)throw new Error(`Shader timing runs are invalid for scene "${n}".`);if(Math.abs(a.avoidedBuildMs-Math.max(0,a.liveBuildMs-a.precompiledBuildMs))>.001)throw new Error(`Shader timing delta is inconsistent for scene "${n}".`);e[n]=a;}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:Re(r.adapter,"Shader timing adapter"),platform:Re(r.platform,"Shader timing platform")}}a(te,"parseShaderTiming");function ne(r){return /^[a-z0-9][a-z0-9_-]{0,63}$/u.test(r)}a(ne,"validParityScene");function Te(r){return typeof r=="string"&&Number.isFinite(Date.parse(r))}a(Te,"validParityTimestamp");function Ie(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)||!Te(r.verifiedAt)||!Array.isArray(r.scenes)||r.scenes.length===0||r.scenes.length>64||!r.scenes.every(n=>typeof n=="string"&&ne(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(([a],[s])=>a.localeCompare(s))){if(!ne(n)||!a$2(i)||typeof i.fingerprint!="string"||!/^[a-f0-9]{64}$/u.test(i.fingerprint)||!Te(i.verifiedAt))throw new Error("Shader parity evidence is invalid.");t[n]={fingerprint:i.fingerprint,verifiedAt:i.verifiedAt};}return {schemaVersion:2,scenes:t}}a(Ie,"parseShaderParityEvidence");function ie(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(P({runtime:{three:r.runtime.three,threeBlocks:r.runtime.threeBlocks,threeBlocksShaderClosure:r.runtime.threeBlocksShaderClosure},...r.tool===void 0?{}:{tool:r.tool},scene:t}))}a(ie,"shaderSceneParityFingerprint");async function Pe(r,e,t,n){let i=g.join(r,t);try{if(!await d(i))return;let a=await lstat(i);if(a.isSymbolicLink()||!a.isFile()||a.size>1024*1024)return;let s=te(JSON.parse(await readFile(i,"utf8")));return s.source===n&&s.receiptHash===c$1(e)?s:void 0}catch{return}}a(Pe,"readShaderTimingFile");async function Zr(r,e){return await Pe(r,e,xe,"latest-local-capture")??await Pe(r,e,je,"committed-capture")}a(Zr,"readShaderTiming");async function pr(r,e){let t=g.join(r,Oe);try{if(!await d(t))return;let n=await lstat(t);if(n.isSymbolicLink()||!n.isFile()||n.size>1024*1024)return;let i=Ie(JSON.parse(await readFile(t,"utf8"))),a=c$2(JSON.parse(Buffer.from(e).toString("utf8"))),s={};if(i.schemaVersion===1){if(i.receiptHash!==c$1(e))return;for(let c of i.scenes)a.scenes[c]!==void 0&&(s[c]={fingerprint:ie(a,c),verifiedAt:i.verifiedAt});}else for(let[c,u]of Object.entries(i.scenes))a.scenes[c]===void 0||u.fingerprint!==ie(a,c)||(s[c]=u);return Object.keys(s).length===0?void 0:{schemaVersion:2,scenes:s}}catch{return}}a(pr,"readShaderParityEvidence");async function Me(r,e,t){let n=await ae(r),i=g.join(n,"meta.json"),a=await lstat(i);if(a.isSymbolicLink()||!a.isFile())throw new Error("Shader receipt must be a regular file before timing.");let s=await readFile(i),c=new Date().toISOString(),u=Object.fromEntries(Object.entries(e).sort(([h],[o])=>h.localeCompare(o))),p=te({schemaVersion:3,receiptHash:c$1(s),measuredAt:c,source:"latest-local-capture",scenes:u});if(await f(g.join(n,xe),`${P(p)}
12
- `),t===void 0)return {local:p};let f$1=te({schemaVersion:3,receiptHash:c$1(s),measuredAt:c,source:"committed-capture",adapter:t.adapter,platform:t.platform,scenes:u});return await f(g.join(n,je),`${P(f$1)}
13
- `),{local:p,committed:f$1}}a(Me,"writeShaderTimings");async function et(r,e){return (await Me(r,e)).local}a(et,"writeShaderLocalTiming");async function rt(r,e,t){if(e.length===0||e.length>64||e.some(o=>!ne(o)))throw new Error("Shader parity evidence must contain 1...64 valid scene keys.");let n=await ae(r),i=g.join(n,"meta.json"),a=await lstat(i);if(a.isSymbolicLink()||!a.isFile())throw new Error("Shader receipt must be a regular file before parity evidence.");let s=await readFile(i);if(t!==void 0&&c$1(s)!==c$1(t))throw new Error("Shader receipt changed during browser parity verification; completed observations were not attached to the new receipt.");let c=c$2(JSON.parse(s.toString("utf8"))),u=await pr(n,s),p=new Date().toISOString(),f$1={...u?.scenes};for(let o of [...new Set(e)].sort())f$1[o]={fingerprint:ie(c,o),verifiedAt:p};let h=Ie({schemaVersion:2,scenes:f$1});return await f(g.join(n,Oe),`${P(h)}
14
- `),h}a(rt,"writeShaderParityEvidence");async function tt(r,e,t){let n=await Me(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(tt,"writeShaderTimingTwins");async function ke(r){if(!await d(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(ke,"assertDirectory");async function ae(r){let e=g.resolve(r),t=g.join(e,".three-blocks");await ke(t);let n=g.join(t,"shaders");return await ke(n),n}a(ae,"artifactRoot");async function nt(r){let e$1=await ae(r.root),t=g.resolve(r.root),n=g.resolve(t,r.publicDirectory??"public");if(!e(t,n)||n===t)throw new Error("Shader public directory must stay inside the project root.");let i$1=g.join(n,"three-blocks","shaders");await mkdir(i$1,{recursive:true}),await i(t,i$1,"Shader static-asset directory");let a={},s=[];for(let o of [...r.scenes].sort((m,l)=>m.key.localeCompare(l.key))){let m=r.captures.get(o.key),l=r.inputs.get(o.key);if(l===void 0)throw new Error(`Shader input matrix is missing scene "${o.key}".`);if(m===void 0){let S=r.previousReceipt?.scenes[o.key];if(S===void 0)throw new Error(`Capture matrix is missing scene "${o.key}".`);let C=await readFile(g.join(e$1,S.artifact));if(c$1(C)!==S.artifactHash)throw new Error(`Preserved shader artifact checksum differs for scene "${o.key}".`);if(S.asset!==void 0&&S.assetHash!==void 0){let D=await readFile(g.join(n,S.asset));if(c$1(D)!==S.assetHash)throw new Error(`Preserved static shader manifest checksum differs for scene "${o.key}".`)}a[o.key]={...S,inputs:Object.fromEntries(Object.entries(l).sort(([D],[Z])=>D.localeCompare(Z)))},s.push(S.artifact),S.asset!==void 0&&s.push(g.relative(t,g.join(n,S.asset)).split(g.sep).join("/"));continue}if(m.scene!==o.key||m.manifest.scene!==o.key)throw new Error(`Capture matrix scene "${o.key}" is inconsistent.`);let y=`${o.key}.webgpu.ts`,E=mr(m.manifest);await f(g.join(e$1,y),E),s.push(y);let v=`three-blocks/shaders/${o.key}.json`,R=`${P(m.manifest)}
15
- `;await f(g.join(n,v),R),s.push(g.relative(t,g.join(n,v)).split(g.sep).join("/"));let j=m.skipped.filter(S=>S.kind==="render").length,X=m.skipped.length-j;a[o.key]={artifact:y,artifactHash:c$1(E),asset:v,assetHash:c$1(R),inputs:Object.fromEntries(Object.entries(l).sort(([S],[C])=>S.localeCompare(C))),coverage:m.coverage,bytes:Buffer.byteLength(E),skipped:{render:j,compute:X}};}let c=[...r.captures.values()].find(o=>o.provenance!==void 0)?.provenance??r.previousReceipt?.runtime.capture,u={schemaVersion:2,runtime:{...r.runtime,...c===void 0?{}:{capture:c}},tool:{name:"@three-blocks/devtools",version:a$3,compatibility:THREE_WEBGPU_R185_COMPATIBILITY,transform:A,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},scenes:a},p=new Set(s);for(let o of await readdir(e$1,{withFileTypes:true}))if(!(!o.name.endsWith(".webgpu.ts")||p.has(o.name))){if(o.isSymbolicLink()||!o.isFile())throw new Error(`Orphan shader artifact is not a regular file: ${o.name}.`);await unlink(g.join(e$1,o.name));}let f$1=new Set(r.scenes.map(o=>`${o.key}.json`)),h=new Set(Object.values(r.previousReceipt?.scenes??{}).map(o=>o.asset===void 0?void 0:g.posix.basename(o.asset)).filter(o=>o!==void 0));try{let o=c$2(JSON.parse(await readFile(g.join(e$1,"meta.json"),"utf8")));for(let m of Object.values(o.scenes))m.asset!==void 0&&h.add(g.posix.basename(m.asset));}catch{}for(let o of await readdir(i$1,{withFileTypes:true}))if(!(!o.name.endsWith(".json")||f$1.has(o.name))&&h.has(o.name)){if(o.isSymbolicLink()||!o.isFile())throw new Error(`Orphan shader static asset is not a regular file: ${o.name}.`);await unlink(g.join(i$1,o.name));}return await f(g.join(e$1,"meta.json"),`${P(u)}
16
- `),s.push("meta.json"),{directory:e$1,receipt:u,files:s}}a(nt,"writeShaderArtifacts");var Le="three-blocks.shader-capture.runtime.v1";var H;async function L(){H===void 0&&(H=(async()=>{let e=createRequire(g.join(process.cwd(),"package.json")).resolve("@three-blocks/devtools/browser/shader-capture"),t=g.resolve(g.dirname(e),"../..");return (await j(t,e,a$1.metadata,"Shader capture browser runtime")).data.toString("utf8")})());let r=H;try{return await r}catch(e){throw H===r&&(H=void 0),e}}a(L,"loadShaderCaptureRuntimeSource");var De="virtual:three-blocks-shader-capture-client",$e="\0three-blocks:shader-capture-client",oe="virtual:three-blocks-shader-capture-runtime",Fe="\0three-blocks:shader-capture-runtime";async function He(){let r=await L(),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(He,"loadShaderCaptureRuntimeScriptSource");function Sr(r){let e=r.split("?",1)[0];return e===void 0?false:e.split(g.sep).join("/").endsWith("/build/three.webgpu.js")}a(Sr,"isThreeWebGPUModule");function Ue(r){let e=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u.exec(r);return e?.[1]==="0"&&e[2]==="185"}a(Ue,"supportedVersion");function wr(r,e,t={}){if(!Ue(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,id:"three/build/three.webgpu.js"}),i=n.state==="already-applied",a=n.code;return t.instrumentCapture&&(a=transformThreeWebgpuCaptureInstrumentation(a,{...t.captureRuntimeImport===void 0?{}:{runtimeImport:t.captureRuntimeImport}}).code),{code:a,alreadyPresent:i,captureApplied:t.instrumentCapture===true}}a(wr,"applyShaderProviderTransform");var br=/this\.trackTimestamp\s*=\s*\(\s*parameters\.trackTimestamp\s*===\s*true\s*\);/gu,vr="Object.defineProperty( this, 'trackTimestamp', { get: () => false, set: () => {} } );";function Ve(r,e={}){if(!Ue(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===De?$e:e.capture&&i===oe?Fe:null},async load(i){return e.capture?i===Fe?L():i===$e?[`export * from '${oe}';`,`import { configureThreeBlocksShaderCapture } from '${oe}';`,`configureThreeBlocksShaderCapture( ${JSON.stringify({capture:e.capture.capture,forceLive:e.capture.forceLive,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:A})} );`].join(`
17
- `):null:null},transform(i,a){if(!Sr(a))return null;t.seen=true,t.id=a;try{let s=wr(i,r,{instrumentCapture:e.capture!==void 0,...e.capture!==void 0?{captureRuntimeImport:De}:{}}),c=e.disableTimestampQueries===!0?s.code.replace(br,vr):s.code;if(e.disableTimestampQueries===!0&&c===s.code)throw new Error("Three.js timestamp tracking anchor drifted; refusing software WebGPU capture.");return t.applied=!0,t.alreadyPresent=s.alreadyPresent,t.captureApplied=s.captureApplied,c===i?null:{code:c,map:null}}catch(s){throw t.error=s instanceof Error?s.message:String(s),s}}},status:t}}a(Ve,"createShaderProviderTransform");function de(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(de,"assertShaderProviderTransform");var Qe="/__three-blocks/shaders/capture",Q="/__three-blocks/shaders/telemetry",Xe="/__three-blocks/shaders/runtime.js",Ze="/__three-blocks/shaders/bootstrap.js",er="/__three-blocks/shaders/bridge.js",rr=a$1.manifest*2,me=/^[a-z0-9][a-z0-9_-]{0,63}$/u,tr=64,nr=2e3,Br=[/is not valid JSON/iu,/WebGPU is experimental/iu];async function Ar(){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(Ar,"loadChromium");async function xr(r){let e;try{e=createRequire(g.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(xr,"loadProjectCreateServer");var pe=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,a)=>{let s=setTimeout(()=>{this.#e.delete(e),a(new Error(`Shader capture "${e}" timed out after ${t}ms.`));},t);this.#e.set(e,{resolve:i,reject:a,timer:s});})}receive(e){if(!a$2(e)||typeof e.scene!="string"||!me.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>=tr)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 jr(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(jr,"waitForShaderCaptureAcrossNavigation");var he=class{static{a(this,"TelemetryHub");}#e=new Map;#r=new Map;markFirstRequest(e){me.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"||!me.test(e.scene))throw new Error("Shader telemetry has no bounded scene key.");if(!this.#e.has(e.scene)&&this.#e.size>=tr)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);}},Or=a(async(r,e,t,n,i)=>{let a=0;for(;r.__threeBlocksParityUsesAnimationLoop!==true&&a<e;)await n(),a+=1;if(r.__threeBlocksParityUsesAnimationLoop===true){let s=Number(r.__threeBlocksParityCompletedFrame||0),c=Number(t),u=Number.isSafeInteger(c)&&c>=s?c:s+e;for(r.__threeBlocksParityTargetFrame=u;Number(r.__threeBlocksParityCompletedFrame||0)<u;)await n();}return await i(),Number(r.__threeBlocksParityCompletedFrame||0)},"settleShaderParityFrames");function fe(){return `(() => {
18
- const root = globalThis;
19
- const scene = new URL(location.href).searchParams.get('captureId')
20
- || 'default';
21
- // Keep the wall clock native so shader build durations and loader deadlines stay
22
- // truthful. Deterministic application time is supplied by renderer/Timer capture hooks.
23
- const randomSeed = (value) => {
24
- let state = 2166136261;
25
- for (let index = 0; index < value.length; index++) state = Math.imul(state ^ value.charCodeAt(index), 16777619) >>> 0;
26
- return state === 0 ? 0x9e3779b9 : state;
27
- };
28
- const advanceRandom = (state) => {
29
- state ^= state << 13;
30
- state ^= state >>> 17;
31
- state ^= state << 5;
32
- return state >>> 0;
33
- };
34
- const parityMode = new URL(location.href).searchParams.get('threeBlocksShaderMode');
35
- const randomStreams = new Map();
36
- let randomState = randomSeed(scene);
37
- Math.random = () => {
38
- if (parityMode === 'live' || parityMode === 'precompiled') {
39
- const stackLine = String(new Error().stack || '').split('\\n')[2] || 'unknown';
40
- const originIndex = stackLine.indexOf(location.origin);
41
- const callsite = (originIndex >= 0 ? stackLine.slice(0, originIndex) : stackLine).trim() || 'anonymous';
42
- const next = advanceRandom(randomStreams.get(callsite) ?? randomSeed(scene + '|' + callsite));
43
- randomStreams.set(callsite, next);
44
- return next / 4294967296;
45
- }
46
- randomState = advanceRandom(randomState);
47
- return randomState / 4294967296;
48
- };
49
- const readiness = { workerReady: false, assetsReady: false, textReady: false, compileEnd: false, firstFrame: false };
50
- const stats = { buildCalls: 0, renderBuilds: 0, computeBuilds: 0, registeredBuilds: 0, registeredRenderBuilds: 0, registeredComputeBuilds: 0, buildMs: 0, injected: 0, injectedRender: 0, injectedCompute: 0, missed: 0, missedRender: 0, missedCompute: 0, missedKeys: [] };
51
- const settleParityFrames = ${Or.toString()};
52
- const settle = (frames, requestedTarget) => settleParityFrames(
53
- root,
54
- frames,
55
- requestedTarget,
56
- () => new Promise((resolve) => requestAnimationFrame(resolve)),
57
- () => new Promise((resolve) => setTimeout(resolve, 100)),
58
- );
59
- const bridge = { protocolVersion: 1, compatibility: ${JSON.stringify(THREE_WEBGPU_R185_COMPATIBILITY)}, transform: ${A}, readiness, stats, settle };
60
- root.__threeBlocksShaderTools = bridge;
61
- requestAnimationFrame(() => requestAnimationFrame(() => { readiness.firstFrame = true; }));
62
- const poll = async () => {
63
- try {
64
- const response = await fetch('/__three-blocks/shaders/telemetry?scene=' + encodeURIComponent(scene), { cache: 'no-store' });
65
- if (response.status !== 204 && response.ok) {
66
- const payload = await response.json();
67
- if (payload.protocolVersion !== 1 || payload.compatibility !== bridge.compatibility || payload.transform !== bridge.transform) throw new Error('incompatible shader telemetry');
68
- Object.assign(stats, payload.stats);
69
- readiness.workerReady = true;
70
- if (payload.settled === true) {
71
- readiness.assetsReady = true;
72
- readiness.textReady = true;
73
- readiness.compileEnd = true;
74
- }
75
- const smoke = root.__threeBlocksSmoke && typeof root.__threeBlocksSmoke === 'object' ? root.__threeBlocksSmoke : { protocolVersion: 1, worker: { offscreenCanvas: true, visible: true }, readiness: {} };
76
- smoke.readiness = { ...(smoke.readiness || {}), ...readiness };
77
- root.__threeBlocksSmoke = smoke;
78
- }
79
- } catch {}
80
- setTimeout(poll, 40);
81
- };
82
- void poll();
83
- })();`}a(fe,"publicBridgeScript");function ir(r,e,t,n,i=false){let a=new URL(r.url??"/","http://three-blocks.invalid"),s=a.pathname;if(i&&r.method==="GET"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.json$/u.test(s))return e.statusCode=204,e.end(),true;if(s===Q&&r.method==="GET"){let o=a.searchParams.get("scene")??"",m=n.read(o);return m===void 0?(e.statusCode=204,e.end()):(e.statusCode=200,e.setHeader("Content-Type","application/json"),e.end(JSON.stringify(m))),true}let c=s===Qe,u=s===Q;if(!c&&!u)return false;if(r.method!=="POST")return e.statusCode=405,e.end("POST required"),true;let p=[],f=0,h=false;return r.on("data",o=>{f+=o.byteLength,f>rr?h=true:p.push(o);}),r.on("end",()=>{if(h){e.statusCode=413,e.end("capture payload too large");return}try{let o=JSON.parse(Buffer.concat(p).toString("utf8"));u?n.receive(o):t.receive(o),e.statusCode=204,e.end();}catch(o){e.statusCode=400,e.end(o instanceof Error?o.message:String(o));}}),true}a(ir,"handleCaptureEndpoint");function Ir(r,e,t){return {name:"three-blocks:shader-capture-endpoint",transformIndexHtml(){return [{tag:"script",children:fe(),injectTo:"head-prepend"}]},configureServer(n){n.middlewares.use((i,a,s)=>{let u=new URL(i.url??"/","http://three-blocks.invalid").searchParams.get("captureId");u!==null&&e.markFirstRequest(u),!ir(i,a,r,e,t)&&s();});}}}a(Ir,"captureEndpointPlugin");function We(r,e,t){let n=new URL(e.url,r);for(let[i,a]of Object.entries(t))n.searchParams.set(i,a);return n.href}a(We,"browserUrl");function Mr(r,e){let t=new URL(e.url,r);for(let n of ["capture","precompiled"])t.searchParams.delete(n);return t.searchParams.set("captureId",e.key),t.searchParams.set("threeBlocksShaderMode","precompiled"),t.searchParams.set("tbStats","1"),t.href}a(Mr,"publishedBrowserUrl");function Ke(r){return Br.some(e=>e.test(r))}a(Ke,"knownNoise");async function U(r){let e;try{await Promise.race([r(),new Promise(t=>{e=setTimeout(t,nr);})]);}catch{}finally{e&&clearTimeout(e);}}a(U,"closeBrowserResource");async function qe(r){let e;try{return await Promise.race([r().catch(()=>null),new Promise(t=>{e=setTimeout(()=>t(null),nr);})])}finally{e!==void 0&&clearTimeout(e);}}a(qe,"readPageDiagnostic");function ce(r){let e=a(()=>{},"resolveFirst"),t=new Promise(s=>{e=s;}),n={console:[],page:[],first:t},i=false,a$1=a(s=>{i||(i=true,e(new Error(s)));},"report");return r.on("console",s=>{let c=s.type()==="warning"&&/\[three-blocks\/shaders\].*(?:has no entry|manifest miss|hydration)/iu.test(s.text());if(s.type()!=="error"&&!c||Ke(s.text()))return;let u=s.location().url,p=u.length>0?`${s.text()} (${u})`:s.text();n.console.push(p),a$1(`Browser console ${c?"warning":"error"}: ${p}`);}),r.on("pageerror",s=>{if(Ke(s.message))return;let c=s.stack||s.message;n.page.push(c),a$1(`Browser page error: ${c}`);}),r.on("crash",()=>a$1("Browser page crashed before shader capture completed.")),r.on("close",()=>a$1("Browser page closed before shader capture completed.")),n}a(ce,"collectErrors");function V(r,e,t=false){return typeof r[e]=="boolean"?r[e]:t}a(V,"booleanField");function Lr(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),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(Lr,"parseStats");function J(r,e,t,n){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 i=r.readiness;if(!a$2(i))throw new Error("The shader bridge readiness snapshot is invalid.");let a={workerReady:V(i,"workerReady"),assetsReady:V(i,"assetsReady"),textReady:e.requiresText?V(i,"textReady"):true,compileEnd:V(i,"compileEnd"),firstFrame:V(i,"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 s=t?THREE_WEBGPU_R185_COMPATIBILITY:r.compatibility,c=t?A:r.transform;if(s!==THREE_WEBGPU_R185_COMPATIBILITY||c!==A)throw new Error(`Scene "${e.key}" exposed incompatible shader bridge metadata.`);return de(n),{compatibility:s,transform:c,readiness:a,stats:Lr(r.stats)}}a(J,"parseBridge");async function z(r,e){return r.evaluate(t=>{let n=globalThis;if(!t)return n.__threeBlocksShaderTools??null;let i=n.__threeBlocks,a=n.__threeBlocksTslStats;if(!i||typeof i!="object")return null;let s=i;return {readiness:{workerReady:s.workerReady===true,assetsReady:s.loadEnd===true||s.assetsReady===true,textReady:s.textReady===true,compileEnd:s.compileEnd===true,firstFrame:true},stats:a}},e)}a(z,"readBridge");async function Y(r,e,t,n){return r.evaluate(async i=>{let s=globalThis.__threeBlocksShaderTools;if(s&&typeof s=="object"){let p=Reflect.get(s,"settle");if(typeof p=="function"){let f=await p(i.frames,i.targetFrame);return typeof f=="number"&&Number.isSafeInteger(f)?f:0}}if(!i.legacy||!i.modulePath)throw new Error("The public shader bridge does not provide deterministic settle().");let c=await import(i.modulePath);if(!c.store||typeof c.store!="object")throw new Error("Legacy deterministic store is unavailable.");let u=c.store;return u.recordFrameCount=0,u.recordFrameRate=60,u.recordTotalFrames=i.frames,u.recording=true,await new Promise((p,f)=>{let h=Date.now(),o=a(()=>{if(u.recording===false)return p();if(Date.now()-h>i.timeoutMs)return f(new Error("Legacy deterministic settle timed out."));setTimeout(o,25);},"poll");o();}),0},{frames:t,targetFrame:n,legacy:e.bridge.legacyLab,modulePath:e.bridge.deterministicModule??null,timeoutMs:e.timeoutMs})}a(Y,"settlePage");async function Je(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 a=i;for(let u of n.global.split(".")){if((typeof a!="object"||a===null)&&typeof a!="function")return false;a=Reflect.get(a,u);}if(a===true)return true;if(typeof a!="object"||a===null||typeof Reflect.get(a,"then")!="function")return false;let s=i.__threeBlocksReadinessState,c=s instanceof Map?s:new Map;return s instanceof Map||(i.__threeBlocksReadinessState=c),c.has(a)||(c.set(a,false),Promise.resolve(a).then(()=>c.set(a,true),()=>c.set(a,false))),c.get(a)===true},e.readiness,{timeout:e.timeoutMs}),t.first.then(n=>Promise.reject(n))]);}a(Je,"waitForConfiguredReadiness");async function ze(r){let e=r.locator("canvas"),n=(await e.evaluateAll(i=>i.map((a,s)=>{let c=a.getBoundingClientRect();return {index:s,area:Math.max(0,c.width)*Math.max(0,c.height)}}))).sort((i,a)=>a.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(ze,"primaryCanvasScreenshot");async function ue(r,e,t,n,i){let a=ar(n,i),s=await He(),c=`(() => {
84
- const runtime = globalThis[Symbol.for(${JSON.stringify(Le)})];
85
- if (!runtime || typeof runtime.configureThreeBlocksShaderCapture !== 'function') {
86
- throw new Error('@three-blocks/devtools attached shader capture runtime is incompatible.');
87
- }
88
- runtime.configureThreeBlocksShaderCapture(${JSON.stringify(a).replaceAll("<","\\u003c")});
89
- })();`;await r.addInitScript({content:`${s}
90
- ${c}`}),await r.addInitScript({content:fe()}),await r.route("**/*",async u=>{let p=u.request(),f=new URL(p.url()),h=f.pathname;if(p.method()==="GET"&&n!=="precompiled"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.json$/u.test(h)){await u.fulfill({status:204});return}if(h===Q&&p.method()==="GET"){let l=t.read(f.searchParams.get("scene")??"");await u.fulfill(l===void 0?{status:204}:{status:200,contentType:"application/json",body:JSON.stringify(l)});return}let o=h===Qe,m=h===Q;if((o||m)&&p.method()==="POST"){let l=p.postDataBuffer()??Buffer.alloc(0);if(l.byteLength>rr){await u.fulfill({status:413,body:"capture payload too large"});return}try{let y=JSON.parse(l.toString("utf8"));m?t.receive(y):e.receive(y),await u.fulfill({status:204});}catch(y){await u.fulfill({status:400,body:y instanceof Error?y.message:String(y)});}return}await u.continue();});}a(ue,"configureAttachedContext");var Dr=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 $r(r){let e=[`<script src="${er}"></script>`,`<script type="module" src="${Ze}"></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($r,"injectStaticShaderCaptureHtml");function Fr(r,e){let t=ar(r,e);return [`import { configureThreeBlocksShaderCapture } from ${JSON.stringify(Xe)};`,`configureThreeBlocksShaderCapture( ${JSON.stringify(t).replaceAll("<","\\u003c")} );`].join(`
91
- `)}a(Fr,"staticCaptureBootstrap");function ar(r,e){return {capture:r==="capture",forceLive:r!=="precompiled",settleFrames:e.settleFrames,settleTimeoutMs:e.settleTimeoutMs??3e4,readiness:e.readiness,transform:A}}a(ar,"shaderCaptureConfiguration");async function Nr(r,e){let t=await k$1(r,e,s=>/\.(?:c|m)?js$/u.test(s),16384),n=false,i=false,a;for(let s of t){let c=(await j(r,s,a$1.texture,"Static application JavaScript")).data.toString("utf8");if(c.includes("nodeBuilderStateProvider")&&(n=true),c.includes("three-blocks.shader-capture.runtime.v1")&&(i=true,a??=s),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,...a===void 0?{}:{id:a}}}a(Nr,"inspectStaticCaptureTransform");async function Hr(r,e$1){let t;try{t=decodeURIComponent(e$1);}catch{return}if(t.includes("\0"))return;let n=t.replace(/^\/+/u,""),i=g.resolve(r,n.length===0?"index.html":n);if(!e(r,i)||i===r||(await d(i)&&(await lstat(i)).isDirectory()&&(i=g.join(i,"index.html")),!await d(i)&&g.extname(i).length===0&&(i=g.join(r,"index.html")),!await d(i)))return;let a=await j(r,i,a$1.texture,"Static application asset");return {data:a.data,file:a.path}}a(Hr,"staticRequestFile");async function Ur(r,e$1,t,n,i){let a=await realpath(r.root),s=await realpath(g.resolve(a,r.serve));if(!e(a,s)||s===a)throw new Error("--serve must name a built application directory inside the project root.");let c=await Nr(a,s),u=await L(),p=Fr(e$1,t),f=fe(),h=createServer((m,l)=>{(async()=>{if(ir(m,l,n,i,e$1!=="precompiled"))return;let y=new URL(m.url??"/","http://three-blocks.invalid");if(m.method!=="GET"&&m.method!=="HEAD"){l.statusCode=405,l.end("GET or HEAD required");return}let E=y.pathname===Xe?u:y.pathname===Ze?p:y.pathname===er?f:void 0;if(E!==void 0){l.statusCode=200,l.setHeader("Content-Type","text/javascript; charset=utf-8"),l.setHeader("Cache-Control","no-store"),l.end(m.method==="HEAD"?void 0:E);return}let v=await Hr(s,y.pathname);if(v===void 0){l.statusCode=404,l.end("Not found");return}let R=g.extname(v.file).toLowerCase(),j=R===".html"?Buffer.from($r(v.data.toString("utf8"))):v.data;l.statusCode=200,l.setHeader("Content-Type",Dr[R]??"application/octet-stream"),l.setHeader("Content-Length",String(j.byteLength)),l.setHeader("Cache-Control","no-store"),l.end(m.method==="HEAD"?void 0:j);})().catch(y=>{if(l.headersSent)return l.destroy(y instanceof Error?y:void 0);l.statusCode=500,l.end(y instanceof Error?y.message:String(y));});});await new Promise((m,l)=>{h.once("error",l),h.listen(0,"127.0.0.1",()=>{h.off("error",l),m();});});let o=h.address();if(!o||typeof o=="string")throw new Error("Static capture server did not expose an ephemeral TCP address.");return {server:h,baseUrl:`http://127.0.0.1:${o.port}`,transform:c}}a(Ur,"startStaticShaderServer");function Vr(r,e,t){return r===e?true:t&&r!==void 0&&r!=="capture"&&e!=="capture"}a(Vr,"canReuseShaderBrowserSession");function Ye(r){let e=r instanceof Error?r.message:String(r);return e.includes("Execution context was destroyed")&&e.includes("navigation")}a(Ye,"isRetryableShaderObservationNavigation");var G=class{static{a(this,"PlaywrightShaderDriver");}#e;#r=new pe;#n=new he;#l;#m;#a;#s;#t;#i;#p;#d;#h;#c=0;#u;constructor(e){this.#e=e;}#o(){return this.#l?.status??this.#m??{seen:false,applied:false,alreadyPresent:false}}async#f(e){if(this.#t?.isConnected()===true)return;this.#t=void 0;let t=await Ar();this.#u??=await mkdtemp(g.join(tmpdir(),"three-blocks-shader-cache-")),this.#t=await t.launch({headless:c(this.#e.headed===true),args:[...b$1(),`--disk-cache-dir=${this.#u}`],timeout:e.timeoutMs}),this.#c=0;}async#y(e,t){let n=this.#a!==void 0||this.#s!==void 0||this.#e.url!==void 0&&this.#i!==void 0,i=this.#s!==void 0?this.#d===e:Vr(this.#d,e,t.bridge.legacyLab);if(n&&i){this.#d=e,await this.#f(t);return}if(n&&await this.close(),this.#d=e,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.#m={seen:true,applied:true,alreadyPresent:false,captureApplied:true,id:"attached-application"},await this.#f(t);return}if(this.#e.serve!==void 0)try{let a=await Ur({root:this.#e.root,runtime:this.#e.runtime,serve:this.#e.serve,...this.#e.headed===void 0?{}:{headed:this.#e.headed}},e,t,this.#r,this.#n);this.#s=a.server,this.#m=a.transform,this.#i=a.baseUrl,await this.#f(t);return}catch(a){throw await this.close(),a}this.#l=Ve(this.#e.runtime.three,{disableTimestampQueries:k.env.THREE_BLOCKS_SOFTWARE_WEBGPU==="1",...t.bridge.legacyLab?{}:{capture:{capture:e==="capture",forceLive:e!=="precompiled",settleFrames:t.settleFrames,settleTimeoutMs:t.settleTimeoutMs??3e4,readiness:t.readiness}}}),this.#p={THREE_BLOCKS_SHADER_TOOL:k.env.THREE_BLOCKS_SHADER_TOOL,THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER:k.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER},k.env.THREE_BLOCKS_SHADER_TOOL="1",k.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER="1";try{let a=await xr(this.#e.root);this.#a=await a({root:this.#e.root,logLevel:"error",plugins:[this.#l.plugin,Ir(this.#r,this.#n,e!=="precompiled")],server:{host:"127.0.0.1",port:0}}),await this.#a.listen();let s=this.#a.httpServer?.address();if(!s||typeof s=="string")throw new Error("Vite did not expose an ephemeral TCP address.");this.#i=`http://127.0.0.1:${s.port}`,await this.#f(t);}catch(a){throw await this.close(),a}}async capture(e,t){let n=Date.now();if(await this.#y("capture",t),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let i=this.#t,a$1=await i.newContext({viewport:t.viewport});this.#e.url!==void 0&&await ue(a$1,this.#r,this.#n,"capture",t);let s=await a$1.newPage(),c=ce(s);this.#n.clear(e.key);let u=this.#r.wait(e.key,t.timeoutMs),p=Promise.race([u,c.first.then(m=>Promise.reject(m))]),f=a(()=>{},"resolveDisconnected"),h=new Promise(m=>{f=m;}),o=a(()=>f(new Error("Shader capture browser disconnected before posting a manifest.")),"onDisconnected");i.on("disconnected",o);try{let m=s.goto(We(this.#i,e,{threeBlocksShaderCapture:"1",capture:"1",captureId:e.key,captureFrames:String(Math.max(4,t.settleFrames)),settleFrames:String(t.settleFrames)}),{waitUntil:"domcontentloaded",timeout:t.timeoutMs}),l=await jr(m,Promise.race([p,h.then(E=>Promise.reject(E))]));de(this.#o());let y=[...c.page,...c.console];if(y.length>0)throw new Error(`Capture browser errors:
92
- - ${y.join(`
93
- - `)}`);return a$2(l)?{...l,timing:{...a$2(l.timing)?l.timing:{},launch:n,...this.#n.firstRequest(e.key)===void 0?{}:{firstRequest:this.#n.firstRequest(e.key)},posted:Date.now()}}:l}catch(m){let l=m instanceof Error?m:new Error(String(m));this.#r.cancel(e.key,l),await u.catch(()=>{});let y=this.#n.read(e.key);if(l.message.includes("timed out")){let E=await qe(()=>s.evaluate(()=>{let v=globalThis,R=v.__threeBlocksShaderTools,j=R&&typeof R=="object"?R:void 0,X=v.document,S=Reflect.get(v,Symbol.for("three-blocks.shader-capture.cache-value.v1")),C=v.location,D=C!==null&&typeof C=="object"&&typeof Reflect.get(C,"href")=="string"?String(Reflect.get(C,"href")):"http://three-blocks.invalid/",Z=new URL(D).searchParams.get("captureId")??"default",ye=S!==null&&typeof S=="object"&&typeof Reflect.get(S,"registrations")=="function"?Reflect.apply(Reflect.get(S,"registrations"),S,[Z]):void 0;return {documentReadyState:X?.readyState??null,parityTargetFrame:Number(v.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(v.__threeBlocksParityCompletedFrame??0),readiness:j?.readiness??null,captureCache:S!==null&&typeof S=="object"?{activeScene:Reflect.get(S,"activeScene")??null,registrations:Array.isArray(ye)?ye.slice(0,16).map(_=>_!==null&&typeof _=="object"?{key:Reflect.get(_,"key")??null,kind:Reflect.get(_,"kind")??null}:null):null}:null,threeRuntimeResources:performance.getEntriesByType("resource").map(_=>_.name).filter(_=>_.includes("three.webgpu"))}}));throw new Error(`${l.message} Last capture state for "${e.key}": ${JSON.stringify({page:E,telemetry:y??null,transform:this.#o()})}`)}throw l}finally{i.off("disconnected",o),await U(()=>a$1.close()),this.#c++,(!i.isConnected()||this.#c>=(t.browserRelaunchScenes??8))&&(this.#t===i&&(this.#t=void 0),await U(()=>i.close()),this.#c=0);}}async observe(e,t,n,i){for(let a=0;a<2;a++)try{return await this.#g(e,t,n,i)}catch(s){if(a===0&&Ye(s))continue;throw s}throw new Error(`Shader observation retry was exhausted for scene "${e.key}".`)}async#g(e,t,n,i){if(await this.#y(t,n),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let a=await this.#t.newContext({viewport:n.viewport});this.#e.url!==void 0&&await ue(a,this.#r,this.#n,t,n);let s=await a.newPage(),c=ce(s);this.#n.clear(e.key);try{await s.goto(We(this.#i,e,{threeBlocksShaderCapture:"1",threeBlocksShaderMode:t,captureId:e.key,...t==="live"?{precompiled:"0"}:{}}),{waitUntil:"domcontentloaded",timeout:n.timeoutMs}),await Promise.race([s.waitForFunction(n.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:n.timeoutMs}),c.first.then(o=>Promise.reject(o))]),J(await z(s,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#o()),await Je(s,n,c);let u=e.parityFrames??n.parity.frames,p=await Y(s,n,u,i),f=Buffer.from(await s.screenshot({type:"png"}));e.parityFrames!==void 0&&u<n.parity.frames&&await Y(s,n,n.parity.frames-u);let h=J(await z(s,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#o());return this.#h===void 0&&(this.#h=await s.evaluate(async()=>{let o=Reflect.get(navigator,"gpu"),m=typeof o=="object"&&o!==null?Reflect.get(o,"requestAdapter"):void 0,l=typeof m=="function"?await Reflect.apply(m,o,[]):void 0,y=typeof l=="object"&&l!==null?Reflect.get(l,"info"):void 0,E=["description","device","architecture","vendor"].flatMap(v=>{let R=typeof y=="object"&&y!==null?Reflect.get(y,v):void 0;return typeof R=="string"&&R.length>0?[R]:[]});return {adapter:[...new Set(E)].join(" \xB7 ")||"WebGPU adapter",platform:navigator.platform||navigator.userAgent}})),{scene:e.key,mode:t,...h,frame:p,screenshot:f,errors:[...c.page,...c.console]}}catch(u){let p=u instanceof Error?u:new Error(String(u));if(/(?:timed?\s*out|timeout)/iu.test(p.message)){let f=this.#n.read(e.key),h=await qe(()=>s.evaluate(()=>{let o=globalThis,m=o.__threeBlocksShaderTools,l=m&&typeof m=="object"?m:void 0;return {documentReadyState:o.document?.readyState??null,parityTargetFrame:Number(o.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(o.__threeBlocksParityCompletedFrame??0),readiness:l?.readiness??null,threeRuntimeResources:performance.getEntriesByType("resource").map(E=>E.name).filter(E=>E.includes("three.webgpu"))}}));throw new Error(`${p.message} Last ${t} state for "${e.key}": ${JSON.stringify({page:h,telemetry:f??null})}`)}throw p}finally{await a.close();}}async observePublished(e,t){for(let n=0;n<2;n++)try{return await this.#S(e,t)}catch(i){if(n===0&&Ye(i))continue;throw i}throw new Error(`Published shader observation retry was exhausted for scene "${e.key}".`)}async#S(e,t){if(await this.#y("precompiled",t),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let n=await this.#t.newContext({viewport:t.viewport});this.#e.url!==void 0&&await ue(n,this.#r,this.#n,"precompiled",t);let i=await n.newPage(),a=ce(i);this.#n.clear(e.key);try{await i.goto(Mr(this.#i,e),{waitUntil:"domcontentloaded",timeout:t.timeoutMs}),await Promise.race([i.waitForFunction(t.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:t.timeoutMs}),a.first.then(f=>Promise.reject(f))]),await Je(i,t,a),J(await z(i,t.bridge.legacyLab),e,t.bridge.legacyLab,this.#o()),await Y(i,t,2);let s=await ze(i),c=await Y(i,t,120),u=await ze(i),p=J(await z(i,t.bridge.legacyLab),e,t.bridge.legacyLab,this.#o());return {scene:e.key,mode:"precompiled",...p,frame:c,beforeScreenshot:s,screenshot:u,errors:[...a.page,...a.console]}}finally{await n.close();}}timingEnvironment(){return this.#h??{adapter:"WebGPU adapter",platform:`${k.platform}/${k.arch}`}}async close(){this.#r.rejectAll(new Error("Shader browser driver closed.")),this.#t&&await U(()=>this.#t?.close()??Promise.resolve());let e=this.#a?.httpServer,t=e?Reflect.get(e,"closeAllConnections"):void 0;if(e&&typeof t=="function"&&Reflect.apply(t,e,[]),this.#a&&await U(()=>this.#a?.close()??Promise.resolve()),this.#s){let n=this.#s;n.closeAllConnections(),await U(()=>new Promise(i=>{n.close(()=>i());}));}if(this.#t=void 0,this.#a=void 0,this.#s=void 0,this.#i=void 0,this.#l=void 0,this.#m=void 0,this.#d=void 0,this.#h=void 0,this.#c=0,this.#u!==void 0&&(await rm(this.#u,{recursive:true,force:true}),this.#u=void 0),this.#p){for(let[n,i]of Object.entries(this.#p))i===void 0?delete k.env[n]:k.env[n]=i;this.#p=void 0;}}};function Mt(r){return new G(r)}a(Mt,"createPlaywrightShaderDriver");function Lt(r){return new G(r)}a(Lt,"createStaticPlaywrightShaderDriver");function Dt(r){return new G(r)}a(Dt,"createAttachedPlaywrightShaderDriver");
94
- export{A as a,Xr as b,P as c,Zr as d,et as e,rt as f,tt as g,nt as h,jr as i,Or as j,Vr as k,Ye as l,Mt as m,Lt as n,Dt as o};
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env node
2
- import {a as a$3,d as d$1,c as c$2,b as b$1,h as h$2,e as e$2,g as g$1,f as f$2}from'./chunk-INDAJN42.js';import {a as a$4}from'./chunk-ZT6T2W4B.js';import {e as e$1,f,b,h as h$1,g,c as c$3}from'./chunk-HRYYNBVC.js';import {a as a$2,c as c$1}from'./chunk-ZDNZCQUQ.js';import {j,a as a$1,c,d,k,h,e,i,f as f$1}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {realpath,readdir,readFile,lstat,mkdir,writeFile}from'fs/promises';import rr from'os';import I from'path';import {THREE_WEBGPU_R185_COMPATIBILITY,SHADER_ADDRESS_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_HYDRATION_SCHEMA_VERSION}from'three-blocks/shaders';import {createRequire}from'module';var $e=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".wgsl",".glsl",".vert",".frag",".json",".css"],Me=new Set($e),xe=/^(?:three-blocks\.shaders\.json|(?:precompile|three-blocks\.shaders)\.config\.(?:cjs|cts|js|mjs|mts|ts))$/u,ur=/(?:^|\/)scene\.(?:cjs|cts|js|jsx|mjs|mts|ts|tsx)$/u,fr=/\b(?:export\s+)?(?:async\s+)?function\s+createScene\b|\bcreateScene\s*=\s*(?:async\s*)?\(/u,hr=/\b(?:[A-Za-z_$][\w$]*\.)*(?:shaders|shaderCache|sceneShaders)\s*\.\s*(?:material|pipeline|compute|container)\s*\(/u,mr=/\b(import|export)(?!\s*\()\s*(type\b\s*)?(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']/gu,pr=/\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,gr=/\b(?:import|export)(?!\s*\()\s*(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']|\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,Sr=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/u,Pe=4096,yr="./shaders";function Ke(e,r){let t=I.relative(e,r).split(I.sep).join("/");if(t.length===0||/[\u0000-\u001f\u007f]/u.test(t))throw new Error("Semantic input has an unsafe relative path.");return t}a(Ke,"portableRelativePath");function Ie(e,r){try{return new TextDecoder("utf-8",{fatal:!0}).decode(e)}catch{throw new Error(`Shader-relevant source ${JSON.stringify(r)} is not valid UTF-8.`)}}a(Ie,"sourceText");function Be(e,r){let t="",n="code";for(let s=0;s<e.length;s++){let i=e[s]??"",d=e[s+1]??"";if(n==="code"){if(i==="/"&&d==="/"){t+=" ",n="line-comment",s++;continue}if(i==="/"&&d==="*"){t+=" ",n="block-comment",s++;continue}if(i==="'"||i==='"'||i==="`"){n=i==="'"?"single":i==='"'?"double":"template",t+=r?i:" ";continue}t+=i;continue}if(n==="line-comment"){i===`
3
- `?(t+=`
4
- `,n="code"):t+=" ";continue}if(n==="block-comment"){i==="*"&&d==="/"?(t+=" ",n="code",s++):t+=i===`
5
- `?`
6
- `:" ";continue}let a=n==="single"?"'":n==="double"?'"':"`";if(i==="\\"&&d.length>0){t+=r?`${i}${d}`:" ",s++;continue}t+=r?i:i===`
7
- `?`
8
- `:" ",i===a&&(n="code");}return t}a(Be,"lexicalSource");function wr(e){let r=new Set,t=Be(e,true);for(let n of t.matchAll(mr))n[2]===void 0&&n[3]!==void 0&&r.add(n[3]);for(let n of t.matchAll(pr))n[1]!==void 0&&r.add(n[1]);return [...r].sort()}a(wr,"importSpecifiers");function vr(e){let r=new Set;for(let t of Be(e,true).matchAll(gr)){let n=t[1]??t[2];n!==void 0&&r.add(n);}return [...r].sort()}a(vr,"runtimeSpecifiers");function ze(e){return (e.split(/[?#]/u,1)[0]??e).replaceAll("\\","/")}a(ze,"cleanSpecifier");function br(e,r,t){let n=ze(r),s;if(n.startsWith("./")||n.startsWith("../"))s=I.posix.normalize(I.posix.join(I.posix.dirname(e),n));else if(n.startsWith("@/"))s=`src/${n.slice(2)}`;else if(n.startsWith("/src/"))s=n.slice(1);else return;if(s===".three-blocks"||s.startsWith(".three-blocks/"))return;let i=I.posix.extname(s).toLowerCase(),d=new Set([s]);if(i.length===0||!Me.has(i)){for(let a of $e)d.add(`${s}${a}`);for(let a of $e)d.add(`${s}/index${a}`);}else if([".js",".mjs",".cjs",".jsx"].includes(i)){let a=s.slice(0,-i.length);for(let f of [".ts",".tsx",".mts",".cts"])d.add(`${a}${f}`);}return [...d].find(a=>t.has(a))}a(br,"resolveProjectImport");function Er(e,r){let t=Be(r,false);return ur.test(e)||fr.test(t)||hr.test(t)}a(Er,"isShaderRoot");async function fe(e,r){let t=await realpath(e);if(r!==void 0){let c$1={},m=0;for(let h of r){let y=await j(t,I.join(t,h),a$1.semanticInput,"Declared shader semantic input");if(m+=y.data.byteLength,m>a$1.semanticTotal)throw new Error("Declared shader semantic inputs exceed the total inspection size limit.");c$1[h]=c(y.data);}return c$1}let n=new Map,s=I.join(t,"src");if(await d(s))for(let c of await k(t,s,m=>Me.has(I.extname(m).toLowerCase()))){let m=await j(t,c,a$1.semanticInput,"Shader semantic input");n.set(Ke(t,c),m.data);}for(let c of await readdir(t,{withFileTypes:true})){if(!c.isFile()||!xe.test(c.name)&&!Me.has(I.extname(c.name).toLowerCase()))continue;let m=await j(t,I.join(t,c.name),a$1.semanticInput,xe.test(c.name)?"Shader configuration input":"Shader semantic input");n.set(c.name,m.data);}if(n.size>Pe)throw new Error(`Shader input discovery exceeds the ${Pe}-file limit.`);let i=new Set,d$1=new Map;for(let[c,m]of n){if(!c.includes("/")&&xe.test(c)&&i.add(c),!c.startsWith("src/"))continue;let h=Ie(m,c);d$1.set(c,h),Er(c,h)&&i.add(c);}if(i.size===0)throw new Error("No shader registration or scene source root was found.");let a=new Set,f=[...i].sort();for(;f.length>0;){let c=f.shift();if(c===void 0||a.has(c))continue;let m=n.get(c);if(m===void 0)continue;a.add(c);let h=d$1.get(c)??Ie(m,c);for(let y of wr(h)){let k=br(c,y,n);k!==void 0&&!a.has(k)&&f.push(k);}f.sort();}let l=0,b={};for(let c$1 of [...a].sort()){let m=n.get(c$1);if(m===void 0)throw new Error(`Shader input ${JSON.stringify(c$1)} disappeared during inspection.`);if(l+=m.byteLength,l>a$1.semanticTotal)throw new Error("Semantic shader inputs exceed the total inspection size limit.");b[c$1]=c(m);}return b}a(fe,"snapshotShaderInputs");function Oe(e){if(typeof e=="string")return e;if(a$2(e))return Oe(e.import)??Oe(e.default)}a(Oe,"conditionalImportTarget");async function He(e,r){let t=e;for(;;){let n=I.join(t,"node_modules",...r.split("/"),"package.json");if(await d(n)){let i=await h(n,a$1.packageJson,`${r} package.json`),d=JSON.parse(i.data.toString("utf8"));if(!a$2(d)||d.name!==r||typeof d.version!="string"||!Sr.test(d.version))throw new Error(`Installed ${r} package metadata is invalid.`);return {root:I.dirname(i.path),manifest:d}}let s=I.dirname(t);if(s===t)break;t=s;}throw new Error(`Cannot verify the installed ${r} package.`)}a(He,"findInstalledPackage");async function Rr(e$1,r){if(!a$2(r.exports))throw new Error("Installed three-blocks package has no public exports map.");let t=Oe(r.exports[yr]);if(t===void 0||!t.startsWith("./"))throw new Error("Installed three-blocks shader export has no import target.");let n=await realpath(e$1),s=[I.resolve(n,t)],i=new Map,d=0;for(;s.length>0;){let f=s.shift();if(f===void 0)break;let l=await h(f,a$1.semanticInput,"Three Blocks shader runtime module");if(!e(n,l.path)||l.path===n)throw new Error("Three Blocks shader runtime closure escapes its package.");let b=Ke(n,l.path);if(i.has(b))continue;if(d+=l.data.byteLength,d>a$1.semanticTotal)throw new Error("Three Blocks shader runtime closure exceeds the inspection limit.");i.set(b,c(l.data));let c$1=Ie(l.data,b);for(let m of vr(c$1)){let h=ze(m);if(!h.startsWith("./")&&!h.startsWith("../"))continue;let y=I.resolve(I.dirname(l.path),h);if(!e(n,y))throw new Error("Three Blocks shader runtime import escapes its package.");s.push(y);}if(s.sort(),i.size+s.length>Pe)throw new Error("Three Blocks shader runtime closure exceeds the file limit.")}let a=[...i].sort((f,l)=>f[0].localeCompare(l[0])).map(([f,l])=>`${f}\0${l}`).join(`
9
- `);return c(a)}a(Rr,"shaderRuntimeClosure");async function ie(e){let[r,t]=await Promise.all([He(e,"three"),He(e,"three-blocks")]);return {three:String(r.manifest.version),threeBlocks:String(t.manifest.version),threeBlocksShaderClosure:await Rr(t.root,t.manifest)}}a(ie,"readInstalledShaderRuntime");var Ue=4096,Tr=createRequire(import.meta.url),qe,R=new Proxy({},{get(e,r){return qe??=Tr("typescript"),Reflect.get(qe,r)}});function K(e){let r=e;for(;R.isParenthesizedExpression(r)||R.isAsExpression(r)||R.isSatisfiesExpression(r)||R.isNonNullExpression(r);)r=r.expression;return r}a(K,"unwrap");function xr(e){if(R.isIdentifier(e)||R.isStringLiteral(e)||R.isNumericLiteral(e))return e.text}a(xr,"propertyName");function he(e,r){let t=new Map;for(let n of e.properties){if(!R.isPropertyAssignment(n))throw new Error(`${r} may contain only static property assignments.`);let s=xr(n.name);if(s===void 0||t.has(s))throw new Error(`${r} contains a computed or duplicate property.`);t.set(s,n.initializer);}return t}a(he,"properties");function me(e,r){if(e===void 0)throw new Error(`${r} is missing.`);let t=K(e);if(!R.isObjectLiteralExpression(t))throw new Error(`${r} must be a static object literal.`);return t}a(me,"objectLiteral");function pe(e,r){if(e===void 0)throw new Error(`${r} is missing.`);let t=K(e);if(!R.isStringLiteral(t)&&!R.isNoSubstitutionTemplateLiteral(t))throw new Error(`${r} must be a string literal.`);return t.text}a(pe,"stringLiteral");function ge(e,r){if(e===void 0)throw new Error(`${r} is missing.`);let t=K(e);if(!R.isNumericLiteral(t))throw new Error(`${r} must be a numeric literal.`);return Number(t.text)}a(ge,"numericLiteral");function Ge(e,r){if(e===void 0)throw new Error(`${r} is missing.`);let t=K(e);if(!R.isArrayLiteralExpression(t))throw new Error(`${r} must be a static array literal.`);return t.elements}a(Ge,"arrayLiteral");function $r(e,r){if(e===void 0)throw new Error(`${r} is missing.`);let t=K(e);if(t.kind===R.SyntaxKind.NullKeyword)return null;if(!R.isNumericLiteral(t))throw new Error(`${r} must be null or a numeric literal.`);return Number(t.text)}a($r,"numericOrNullLiteral");function Mr(e){return e.parseDiagnostics??[]}a(Mr,"parseDiagnostics");function Ye(e,r,t,n){let s=R.createSourceFile(r,e,R.ScriptTarget.Latest,true,R.ScriptKind.TS),i=Mr(s);if(i.length>0)throw new Error(`Shader manifest is not valid TypeScript: ${R.flattenDiagnosticMessageText(i[0]?.messageText??"parse error"," ")}`);let d=s.statements.filter(R.isExportAssignment).filter(h=>!h.isExportEquals);if(d.length!==1)throw new Error("Shader manifest must contain exactly one default export.");let a$1=he(me(d[0]?.expression,"Shader manifest default export"),"Shader manifest"),f=a$1.get("version");if(f===void 0||!R.isNumericLiteral(K(f))||Number(K(f).getText(s))!==3)throw new Error("Shader manifest version must be the numeric literal 3.");if(pe(a$1.get("scene"),"Shader manifest scene")!==t)throw new Error(`Shader manifest scene does not match "${t}".`);if(n){if(pe(a$1.get("three"),"Shader manifest Three.js version")!==n.three||pe(a$1.get("threeBlocks"),"Shader manifest Three Blocks version")!==n.threeBlocks)throw new Error("Shader manifest runtime versions do not match its receipt.");let h=he(me(a$1.get("runtime"),"Shader manifest runtime"),"Shader manifest runtime");if(pe(h.get("id"),"Shader manifest runtime id")!==n.compatibility||ge(h.get("address"),"Shader manifest address schema")!==n.address||ge(h.get("recipe"),"Shader manifest recipe schema")!==n.recipe||ge(h.get("hydration"),"Shader manifest hydration schema")!==n.hydration)throw new Error("Shader manifest runtime compatibility schemas do not match its receipt.")}let l=he(me(a$1.get("entries"),"Shader manifest entries"),"Shader manifest entries");if(l.size===0||l.size>Ue)throw new Error(`Shader manifest must contain between 1 and ${Ue} entries.`);let b=Ge(a$1.get("modules"),"Shader manifest modules").map((h,y)=>{let k=K(h);if(!R.isStringLiteral(k)&&!R.isNoSubstitutionTemplateLiteral(k))throw new Error(`Shader manifest module ${y} must be a WGSL string literal.`);if(k.text.length===0)throw new Error(`Shader manifest module ${y} is empty.`);return k.text}),c=Ge(a$1.get("states"),"Shader manifest states").map((h,y)=>{let k=he(me(h,`Shader manifest state ${y}`),`Shader manifest state ${y}`),E=a((B,p)=>{let T=$r(k.get(B),`Shader manifest state ${y} ${B}`);if(T===null)return false;let x=b[T];if(x===void 0||!x.includes(p))throw new Error(`Shader manifest state ${y} ${B} does not reference a ${p} module.`);return true},"moduleAt"),O=E("vertex","@vertex"),M=E("fragment","@fragment"),A=E("compute","@compute");if(A&&(O||M))throw new Error(`Shader manifest state ${y} mixes render and compute stages.`);if(!A&&!O&&!M)throw new Error(`Shader manifest state ${y} contains no shader stage.`);return {vertex:O,fragment:M,compute:A}}),m={render:0,vertex:0,fragment:0,compute:0};for(let[h,y]of l){if(h.length===0||/[\u0000-\u001f\u007f]/.test(h))throw new Error("Shader manifest contains an invalid entry key.");let k=ge(y,`Shader manifest entry "${h}"`),E=c[k];if(E===void 0)throw new Error(`Shader manifest entry "${h}" references an absent state.`);(E.vertex||E.fragment)&&(m.render+=1),E.vertex&&(m.vertex+=1),E.fragment&&(m.fragment+=1),E.compute&&(m.compute+=1);}return m}a(Ye,"inspectPrecompiledManifest");function Pr(e,r){return e.render===r.render&&e.vertex===r.vertex&&e.fragment===r.fragment&&e.compute===r.compute}a(Pr,"sameCoverage");function Ir(e){let r=e.some(n=>n.state==="invalid")?"invalid":e.some(n=>n.state==="missing")?"missing":e.some(n=>n.state==="stale")?"stale":"fresh",t=e.filter(n=>n.state===r);return {state:r,reason:r==="fresh"?`${e.length} configured shader scene${e.length===1?" is":"s are"} fresh.`:t.map(n=>`${n.scene}: ${n.reason}`).join("; ")}}a(Ir,"classifyMatrix");function Or(e){let r=e.tool;if(!r)return "Shader receipt has no public tool compatibility metadata.";if(r.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY)return "Shader receipt targets a different runtime compatibility contract.";if(r.transform!==a$3)return "Shader receipt uses a different provider transform version.";if(r.address!==SHADER_ADDRESS_SCHEMA_VERSION||r.recipe!==SHADER_RECIPE_SCHEMA_VERSION||r.hydration!==SHADER_HYDRATION_SCHEMA_VERSION)return "Shader receipt uses incompatible address, recipe, or hydration schemas."}a(Or,"exactToolCompatibility");function Br(e,r){let t=Object.keys(r).filter(i=>Object.hasOwn(e,i)&&e[i]!==r[i]),n=Object.keys(r).filter(i=>!Object.hasOwn(e,i)),s=Object.keys(e).filter(i=>!Object.hasOwn(r,i));return {...t.length>0?{changedInputs:t}:{},...n.length>0?{addedInputs:n}:{},...s.length>0?{removedInputs:s}:{}}}a(Br,"inputChanges");async function Se(e=process.cwd()){let r=await e$1(e),t=await f(r),n=I.join(r,b),s=a(()=>({schemaVersion:1,root:r,state:"missing",reason:`${b}/meta.json is absent.`,scenes:t.scenes.map(i=>({scene:i.key,state:"missing",reason:"No committed shader receipt."}))}),"missing");if(!await d(n)||!await d(I.join(n,"meta.json")))return s();try{let i$1=await i(r,n,"Shader artifact directory"),d=await j(i$1,I.join(i$1,"meta.json"),a$1.receipt,"Shader receipt"),a=c$1(JSON.parse(d.data.toString("utf8"))),f=await d$1(i$1,d.data),l=await ie(r),b=new Set(t.scenes.map(p=>p.key)),m=Object.keys(a.scenes).filter(p=>!b.has(p));if(m.length>0)throw new Error(`Shader receipt contains unconfigured scenes: ${m.join(", ")}.`);let h=Or(a);if(h)throw new Error(h);if(!/^0\.185\./u.test(l.three))throw new Error(`Installed Three.js ${l.three} is outside the r185 capture contract.`);let y=a.runtime.three!==l.three||a.runtime.threeBlocks!==l.threeBlocks,k=a.runtime.threeBlocksShaderClosure!==l.threeBlocksShaderClosure,E=a.tool?.version!==a$4,O=I.join(r,t.publicDir??"public"),M=[];for(let p of t.scenes){let T=a.scenes[p.key];if(!T){M.push({scene:p.key,state:"missing",reason:"Scene is absent from the complete receipt matrix."});continue}let x=await j(i$1,I.join(i$1,T.artifact),a$1.manifest,"Shader manifest");if(c(x.data)!==T.artifactHash)throw new Error(`Shader artifact checksum differs for scene "${p.key}".`);if(T.asset!==void 0&&T.assetHash!==void 0){let L=await j(O,I.join(O,T.asset),a$1.manifest,"Static shader manifest");if(c(L.data)!==T.assetHash)throw new Error(`Static shader manifest checksum differs for scene "${p.key}".`)}if(T.bytes!==void 0&&T.bytes!==x.data.byteLength)throw new Error(`Shader artifact byte count differs for scene "${p.key}".`);let u=Ye(x.data.toString("utf8"),x.path,p.key,{three:a.runtime.three,threeBlocks:a.runtime.threeBlocks,compatibility:THREE_WEBGPU_R185_COMPATIBILITY,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION});if(!Pr(u,T.coverage))throw new Error(`Shader coverage differs for scene "${p.key}".`);if(!t.allowLiveBuilds&&T.skipped&&T.skipped.render+T.skipped.compute>0)throw new Error(`Scene "${p.key}" contains skipped live builds but allowLiveBuilds is false.`);let C=await fe(r,p.inputs),w=Br(T.inputs,C),v=(w.changedInputs?.length??0)+(w.addedInputs?.length??0)+(w.removedInputs?.length??0),$=y||k||E||v>0,g=f?.scenes[p.key],S=g===void 0||f===void 0?void 0:{...g,schemaVersion:f.schemaVersion,measuredAt:f.measuredAt,source:f.source,...f.source==="committed-capture"?{adapter:f.adapter,platform:f.platform}:{}};M.push({scene:p.key,state:$?"stale":"fresh",reason:y?"Installed runtime versions differ from the receipt.":k?"Installed three-blocks/shaders runtime closure differs from the receipt.":E?`Receipt was generated by @three-blocks/devtools ${a.tool?.version??"unknown"}.`:v>0?`${v} semantic shader input${v===1?"":"s"} changed.`:"Manifest, runtime, schemas, transform, and semantic inputs match.",coverage:u,...!$&&S!==void 0&&S.builds===u.render+u.compute?{timing:S}:{},...w});}let A=Ir(M),B=A.state==="fresh"&&f!==void 0&&M.every(p=>p.timing!==void 0)?f:void 0;return {schemaVersion:1,root:r,...A,scenes:M,runtime:l,receipt:a,...B===void 0?{}:{timing:B}}}catch(i){let d=i instanceof Error?i.message:String(i);return {schemaVersion:1,root:r,state:"invalid",reason:d,scenes:t.scenes.map(a=>({scene:a.key,state:"invalid",reason:d}))}}}a(Se,"inspectShaderMatrix");var ir=".three-blocks/shaders/pending-capture";function _r(e){return (e instanceof Error?`${e.name}: ${e.message}`:String(e)).includes("ShaderHydrationError:")}a(_r,"isShaderHydrationFailure");async function Dr(e,r,t){if(r.length===0)return;let n=I.join(e,b,"meta.json"),s=await readFile(n);if(c(s)!==c(t))throw new Error("Shader receipt changed before failed scenes could be marked for recapture.");let i=c$1(JSON.parse(s.toString("utf8"))),d=c(t),a=new Set(r),f=c$1({...i,scenes:Object.fromEntries(Object.entries(i.scenes).map(([l,b])=>[l,a.has(l)?{...b,inputs:{...b.inputs,[ir]:d}}:b]))});await f$1(n,`${c$2(f)}
10
- `);}a(Dr,"markShaderScenesForRecapture");function Lr(e,r){return c$2(e)===c$2(r)}a(Lr,"equalSnapshot");async function vt(e={}){let r=e.root?await realpath(e.root):await e$1(e.start),t=e.config===void 0?await h$1(r):void 0,n=e.config??t?.config??await f(r),s=n.scenes,i,d={},a$1;if(e.ifStale){let w=await Se(r);if(w.state==="fresh")return {schemaVersion:1,root:r,skipped:true,reason:w.reason,scenes:[]};if(w.state!=="invalid"&&w.receipt!==void 0){s=n.scenes.filter(v=>w.scenes.find($=>$.scene===v.key)?.state!=="fresh"),i=w.receipt;for(let v of w.scenes){if(v.state!=="fresh"||v.timing===void 0)continue;let{builds:$,liveBuildMs:g,precompiledBuildMs:S,avoidedBuildMs:L,runs:N,spreadMs:z}=v.timing;d[v.scene]={builds:$,liveBuildMs:g,precompiledBuildMs:S,avoidedBuildMs:L,runs:N,spreadMs:z},v.timing.source==="committed-capture"&&v.timing.adapter!==void 0&&v.timing.platform!==void 0&&(a$1={adapter:v.timing.adapter,platform:v.timing.platform});}}}let f$1=performance.now(),l=await ie(r),b=i!==void 0&&(i.runtime.three!==l.three||i.runtime.threeBlocks!==l.threeBlocks||i.runtime.threeBlocksShaderClosure!==l.threeBlocksShaderClosure||i.tool?.version!==a$4)?c(c$2({runtime:i.runtime,tool:i.tool})):void 0,c$1=a(async()=>new Map(await Promise.all(n.scenes.map(async w=>[w.key,await fe(r,w.inputs)]))),"snapshotInputs"),m=await c$1(),h=a(async()=>{let w=await c$1();for(let v of n.scenes){let $=m.get(v.key),g=w.get(v.key);if($===void 0||g===void 0||!Lr($,g))throw new Error(`Semantic shader inputs changed during capture for scene "${v.key}"; the current scene was not committed.`)}},"assertInputsUnchanged"),y=e.driver===void 0,k=e.driver===void 0&&e.driverKind===void 0&&e.serve===void 0&&e.url===void 0?await g(r):void 0,E=e.serve??k?.serve,O=e.driverKind??k?.driverKind??(E===void 0?"vite":"static");if(e.url!==void 0&&(e.serve!==void 0||e.driverKind!==void 0))throw new Error("--url cannot be combined with --driver or --serve.");if(O==="vite"&&E!==void 0)throw new Error("--serve requires the static shader driver.");if(O==="static"&&E===void 0&&e.driver===void 0)throw new Error("The static shader driver requires --serve <built-directory>.");let M=e.driver===void 0?await import('./shader-browser-JII6ZFCW.js'):void 0,A=e.driver??(e.url!==void 0?M.createAttachedPlaywrightShaderDriver({root:r,runtime:l,url:e.url,...e.headed!==void 0?{headed:e.headed}:{}}):O==="static"?M.createStaticPlaywrightShaderDriver({root:r,runtime:l,serve:E,...e.headed!==void 0?{headed:e.headed}:{}}):M.createPlaywrightShaderDriver({root:r,runtime:l,...e.headed!==void 0?{headed:e.headed}:{}})),B=new Map,p=[],T=i!==void 0&&n.scenes.every(w=>i?.scenes[w.key]!==void 0),x=i,u,C=e.attempts??2;if(!Number.isSafeInteger(C)||C<1||C>5)throw new Error("Shader capture attempts must be an integer in 1...5.");try{for(let[$,g]of s.entries()){e.onSceneStart?.(g.key,$,s.length);let S,L,N=0;for(;N<C;N++)try{if(S=b$1(await A.capture(g,n),{scene:g.key,runtime:l}),S.skipped.length>0&&!n.allowLiveBuilds)throw new Error(`Scene "${g.key}" contains ${S.skipped.length} unregistered live shader build${S.skipped.length===1?"":"s"} while allowLiveBuilds is false.`);break}catch(z){L=z,S=void 0,N+1<C&&e.onSceneRetry?.(g.key,N+2,C,n.timeoutMs,z);}if(!S)throw new Error(`Shader capture "${g.key}" failed after ${C} attempts: ${L instanceof Error?L.message:String(L)}`);if(B.set(g.key,S),p.push({scene:g.key,attempts:N+1,coverage:S.coverage,skipped:S.skipped.length,startupBuilds:S.stats.registeredBuilds,startupBuildMs:S.stats.buildMs,...S.timing===void 0?{}:{timing:S.timing}}),T&&x!==void 0){await h();let z=new Map(n.scenes.map(H=>{let re=H.key===g.key?m.get(H.key):x?.scenes[H.key]?.inputs;if(re===void 0)throw new Error(`Shader checkpoint is missing scene "${H.key}".`);return b!==void 0&&!B.has(H.key)&&(re={...re,[ir]:b}),[H.key,re]}));u=await h$2({root:r,scenes:n.scenes,captures:new Map([[g.key,S]]),runtime:l,inputs:z,previousReceipt:x,publicDirectory:n.publicDir??"public"}),x=u.receipt;}}await h(),u??=await h$2({root:r,scenes:n.scenes,captures:B,runtime:l,inputs:m,...i===void 0?{}:{previousReceipt:i},publicDirectory:n.publicDir??"public"}),Object.keys(d).length>0&&(a$1===void 0?await e$2(r,d):await g$1(r,d,a$1));let w=await readFile(I.join(u.directory,"meta.json")),v=await d$1(u.directory,w);return {schemaVersion:1,root:r,skipped:!1,reason:`Wrote ${p.length} shader scene${p.length===1?"":"s"}.`,durationMs:performance.now()-f$1,scenes:p,measurement:{beforeBuilds:p.reduce(($,g)=>$+g.startupBuilds,0),afterBuilds:0,firstFrameDeltaMs:-p.reduce(($,g)=>$+g.startupBuildMs,0),source:"capture-build-phase"},...t===void 0?{}:{configuration:{created:t.created,file:t.file}},written:u,...v===void 0?{}:{timing:v}}}finally{y&&await A.close();}}a(vt,"captureShaders");var sr=1e4,Nr=2e3;function Vr(e){let r=Math.min(e.timeoutMs,sr),t=Math.min(Nr,Math.floor(r/2)),n=Math.max(1,r-t);return {...e,timeoutMs:n,settleTimeoutMs:Math.min(e.settleTimeoutMs??n,n)}}a(Vr,"browserObservationConfig");function Fr(e){return ["workerReady","assetsReady",...e.requiresText?["textReady"]:[],"compileEnd","firstFrame"]}a(Fr,"requiredReadiness");async function Ce(e,r,t,n){let s=Math.min(n,sr),i;try{let d=new Promise((a,f)=>{i=setTimeout(()=>f(new Error(`Scene "${r.key}" ${t} observation returned no result within ${s}ms. Readiness could not be inspected; check ${JSON.stringify(r.url)} for an early page/console error or a missing capture readiness signal.`)),s);});return await Promise.race([e(),d])}finally{i!==void 0&&clearTimeout(i);}}a(Ce,"boundedObservation");function tr(e){if(e.length===0)throw new Error("Cannot take the median of an empty shader timing capture.");let r=[...e].sort((i,d)=>i-d),t=Math.floor(r.length/2),n=r[t];if(n===void 0)throw new Error("Shader timing median is unavailable.");if(r.length%2===1)return n;let s=r[t-1];if(s===void 0)throw new Error("Shader timing median pair is unavailable.");return (s+n)/2}a(tr,"median");function je(e,r,t){if(e.scene!==r.key||e.mode!==t)throw new Error(`Browser observation identity differs for scene "${r.key}".`);if(e.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY||e.transform!==a$3)throw new Error(`Browser observation compatibility differs for scene "${r.key}".`);let n=Fr(r).filter(s=>e.readiness[s]!==true);if(n.length>0)throw new Error(`Scene "${r.key}" ${t} observation is missing readiness bits: ${n.join(", ")}.`);if(e.errors.length>0)throw new Error(`Scene "${r.key}" ${t} browser errors:
11
- - ${e.errors.join(`
12
- - `)}`)}a(je,"assertObservation");function Hr(e,r,t,n){if(r.render>0&&(e.allowPipelineReuse?t.stats.registeredRenderBuilds===0:t.stats.registeredRenderBuilds<r.render))throw new Error(`Scene "${e.key}" live baseline built ${t.stats.registeredRenderBuilds}/${r.render} registered render pipelines${e.allowPipelineReuse?" on a pipeline-reuse route":""}.`);if(r.compute>0&&(e.allowPipelineReuse?t.stats.registeredComputeBuilds===0:t.stats.registeredComputeBuilds<r.compute))throw new Error(`Scene "${e.key}" live baseline built ${t.stats.registeredComputeBuilds}/${r.compute} registered compute kernels${e.allowPipelineReuse?" on a pipeline-reuse route":""}.`);ar(e,r,n);}a(Hr,"assertZeroBuild");function ar(e,r,t){if(t.stats.registeredRenderBuilds!==0||t.stats.registeredComputeBuilds!==0){let n=t.stats.missedKeys??[];throw new Error(`Scene "${e.key}" injected path performed ${t.stats.registeredRenderBuilds} render and ${t.stats.registeredComputeBuilds} compute registered live builds.`+(n.length>0?` Missed keys: ${n.join(", ")}.`:""))}if(e.allowPipelineReuse){if(r.render>0&&t.stats.injectedRender===0)throw new Error(`Scene "${e.key}" injected no render entries.`);if(r.compute>0&&t.stats.injectedCompute===0)throw new Error(`Scene "${e.key}" injected no compute entries.`)}else {if(t.stats.injectedRender<r.render)throw new Error(`Scene "${e.key}" injected ${t.stats.injectedRender}/${r.render} render entries.`);if(t.stats.injectedCompute<r.compute)throw new Error(`Scene "${e.key}" injected ${t.stats.injectedCompute}/${r.compute} compute entries.`)}if(t.stats.missed!==0||t.stats.missedRender!==0||t.stats.missedCompute!==0)throw new Error(`Scene "${e.key}" injected path reported shader manifest misses.`)}a(ar,"assertPrecompiledZeroBuild");async function Wr(e,r,t,n,s){let i=I.join(e,c$3);if(await d(i)){let a=await lstat(i);if(a.isSymbolicLink()||!a.isDirectory())throw new Error("Shader parity artifact directory is not a real directory.")}else await mkdir(i,{recursive:true});let d$1=[`${r}.live.png`,`${r}.precompiled.png`,`${r}.diff.png`];return await Promise.all([t,n,s].map(async(a,f)=>{let l=d$1[f];if(l===void 0)throw new Error("Parity artifact mapping failed.");let b=I.join(i,l);if(await d(b)){let c=await lstat(b);if(c.isSymbolicLink()||!c.isFile())throw new Error(`Shader parity target is not a regular file: ${l}.`)}await writeFile(b,a,{mode:384});})),d$1.map(a=>`${c$3}/${a}`)}a(Wr,"writeParityFailure");async function bt(e={}){let r=e.root?await realpath(e.root):await e$1(e.start),t=await Se(r);if(t.state!=="fresh")throw new Error(`Shader no-GPU validation is ${t.state}: ${t.reason}`);if(e.skipBrowser)return {schemaVersion:1,root:r,noGpu:t,browser:"skipped",scenes:[]};if(e.parityOnly===true&&e.commitTiming===true)throw new Error("Parity-only shader verification cannot commit timing.");let n=e.runs??5;if(!Number.isSafeInteger(n)||n<1||n>100)throw new Error("Shader timing runs must be an integer in 1...100.");let s=e.config??await f(r),i=Vr(s),d=await readFile(I.join(r,b,"meta.json")),a$1=c$1(JSON.parse(d.toString("utf8")));if(t.receipt===void 0||c$2(a$1)!==c$2(t.receipt))throw new Error("Shader receipt changed after no-GPU validation; restart browser parity verification.");let f$1=t.runtime??await ie(r),l=e.driver===void 0,b$1=e.driver===void 0&&e.driverKind===void 0&&e.serve===void 0&&e.url===void 0?await g(r):void 0,c=e.serve??b$1?.serve,m=e.driverKind??b$1?.driverKind??(c===void 0?"vite":"static");if(e.url!==void 0&&(e.serve!==void 0||e.driverKind!==void 0))throw new Error("--url cannot be combined with --driver or --serve.");if(m==="vite"&&c!==void 0)throw new Error("--serve requires the static shader driver.");if(m==="static"&&c===void 0&&e.driver===void 0)throw new Error("The static shader driver requires --serve <built-directory>.");let h=e.driver===void 0?await import('./shader-browser-JII6ZFCW.js'):void 0,{compareShaderScreenshots:y}=await import('./shader-parity-XPKQQK26.js'),k=a(()=>e.url!==void 0?h.createAttachedPlaywrightShaderDriver({root:r,runtime:f$1,url:e.url,...e.headed!==void 0?{headed:e.headed}:{}}):m==="static"?h.createStaticPlaywrightShaderDriver({root:r,runtime:f$1,serve:c,...e.headed!==void 0?{headed:e.headed}:{}}):h.createPlaywrightShaderDriver({root:r,runtime:f$1,...e.headed!==void 0?{headed:e.headed}:{}}),"createDriver"),E=e.driver??k(),O=e.driver??k(),M=[],A={},B=[],p=new Set;try{for(let[x,u]of s.scenes.entries()){e.onSceneStart?.(u.key,x,s.scenes.length);let C=t.scenes.find(P=>P.scene===u.key);if(!C?.coverage)throw new Error(`Fresh receipt has no coverage for scene "${u.key}".`);let w=C.coverage,v=a(async P=>{let Y=P?"live":"precompiled",U=P?"precompiled":"live",ae=P?E:O,oe=P?O:E,q=await Ce(()=>ae.observe(u,Y,i),u,Y,s.timeoutMs),j=await Ce(()=>oe.observe(u,U,i,q.frame),u,U,s.timeoutMs),J=q.mode==="live"?q:j,X=q.mode==="precompiled"?q:j;je(J,u,"live"),je(X,u,"precompiled"),Hr(u,w,J,X);let V=y(J.screenshot,X.screenshot,s.parity.channelTolerance,u.maxDiffRatio??s.parity.maxDiffRatio);if(!V.matches){let dr=await Wr(r,u.key,J.screenshot,X.screenshot,V.diff),cr=V.nonBlack?`${V.differentPixels}/${V.totalPixels} pixels differ (${(V.diffRatio*100).toFixed(3)}%).`:`rendered output is black (live=${V.baselineLuminance.toFixed(4)}, precompiled=${V.precompiledLuminance.toFixed(4)}).`;throw new Error(`Shader parity failed for scene "${u.key}" at completed frames live=${J.frame}, precompiled=${X.frame}: ${cr} Artifacts: ${dr.join(", ")}`)}return {live:J,precompiled:X,parity:V}},"observePair"),$,g,S;if(e.parityOnly===!0)try{$=await v(!0);}catch(P){_r(P)&&p.add(u.key),B.push({scene:u.key,error:P}),e.onSceneError?.(u.key,P);continue}else {await v(!0);let P=[];for(let j=0;j<n;j++)P.push(await v(j%2===0));let Y=P[P.length-1];if(Y===void 0)throw new Error(`Shader timing produced no runs for scene "${u.key}".`);if($=Y,g=await Ce(()=>O.observePublished(u,i),u,"published",s.timeoutMs),je(g,u,"precompiled"),ar(u,w,g),S=u.runtimeMotion?y(g.beforeScreenshot,g.screenshot,s.parity.channelTolerance,1):void 0,S&&S.diffRatio<1e-4)throw new Error(`Published scene "${u.key}" stopped animating during its normal 120-frame soak (changed ${S.differentPixels}/${S.totalPixels} canvas pixels).`);let U=tr(P.map(j=>j.live.stats.buildMs)),ae=tr(P.map(j=>j.precompiled.stats.buildMs)),oe=Math.max(0,U-ae),q=P.map(j=>Math.max(0,j.live.stats.buildMs-j.precompiled.stats.buildMs));A[u.key]={builds:w.render+w.compute,liveBuildMs:U,precompiledBuildMs:ae,avoidedBuildMs:oe,runs:n,spreadMs:Math.max(...q.map(j=>Math.abs(j-oe)))};}let{diff:L,...N}=$.parity,{screenshot:z,...H}=$.live,{screenshot:re,...or}=$.precompiled,ye;if(g!==void 0){let{beforeScreenshot:P,screenshot:Y,...U}=g;ye=U;}M.push({scene:u.key,coverage:w,live:H,precompiled:or,...ye===void 0?{}:{published:ye},parity:N,...S===void 0?{}:{runtimeMotion:{differentPixels:S.differentPixels,totalPixels:S.totalPixels,diffRatio:S.diffRatio}}}),await f$2(r,[u.key],d);}if(e.parityOnly===!0){if(await Dr(r,[...p],d),B.length>0)throw new Error(`Shader parity failed for ${B.length}/${s.scenes.length} scene(s):
13
- `+B.map(x=>{let u=x.error instanceof Error?x.error.message:String(x.error);return ` - ${x.scene}: ${u}`}).join(`
14
- `));return {schemaVersion:1,root:r,noGpu:t,browser:"passed",scenes:M}}if(e.commitTiming===!0){let x={adapter:"WebGPU adapter",platform:`${rr.platform()}/${rr.arch()}`},u=await(E.timingEnvironment?.()??x),C=await g$1(r,A,u);return {schemaVersion:1,root:r,noGpu:t,browser:"passed",scenes:M,timing:C.local,committedTiming:C.committed}}let T=await e$2(r,A);return {schemaVersion:1,root:r,noGpu:t,browser:"passed",scenes:M,timing:T}}finally{l&&(await O.close(),await E.close());}}a(bt,"testShaders");export{Ye as a,fe as b,ie as c,Se as d,vt as e,bt as f};
@@ -1,17 +0,0 @@
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 l from'path';import {THREE_WEBGPU_R185_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 D=/^[a-f0-9]{64}$/,Ke=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/,ye=/^[a-z0-9][a-z0-9_-]{0,63}$/,he=/^[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 x(e){return typeof e=="string"&&Ke.test(e)}a(x,"isSafeVersion");function Y(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(Y,"isSafeRelativePath");function ge(e){if(!c(e)||e.schemaVersion!==2)throw new Error("three-blocks.json must use schemaVersion 2.");if(typeof e.template!="string"||!ye.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"&&he.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"||!he.test(e.generator.name)||!x(e.generator.version)))throw new Error("three-blocks.json has invalid generator metadata.");if(!c(e.runtime)||!x(e.runtime.three)||!x(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(ge,"parseProjectMetadata");function qe(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(qe,"parseCoverage");function Xe(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(!Y(n)||typeof i!="string"||!D.test(i))throw new Error(`Shader receipt input for "${r}" is invalid.`)}a(Xe,"parseInputs");function B(e){if(!c(e)||e.schemaVersion!==2||!c(e.runtime)||!x(e.runtime.three)||!x(e.runtime.threeBlocks)||typeof e.runtime.threeBlocksShaderClosure!="string"||!D.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){if(!ye.test(t)||!c(n)||typeof n.artifact!="string"||!Y(n.artifact)||!n.artifact.endsWith(".webgpu.ts")||typeof n.artifactHash!="string"||!D.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"||!Y(n.asset)||!n.asset.endsWith(".json")||typeof n.assetHash!="string"||!D.test(n.assetHash)))throw new Error(`Shader static asset receipt for "${t}" is invalid.`);if(Xe(n.inputs,t),qe(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"||!x(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.");return e}a(B,"parseShaderReceipt");var $=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 Q(e){return typeof e=="object"&&e!==null&&"code"in e&&typeof e.code=="string"?e.code:void 0}a(Q,"errorCode");function R(e){return createHash("sha256").update(e).digest("hex")}a(R,"sha256");async function S(e){try{return await lstat(e),!0}catch(r){if(Q(r)==="ENOENT")return false;throw r}}a(S,"pathExists");function C(e,r){let t=l.relative(e,r);return t===""||!l.isAbsolute(t)&&t!==".."&&!t.startsWith(`..${l.sep}`)}a(C,"isWithin");function P(e){return JSON.stringify(e)}a(P,"displayPath");async function Ee(e,r,t){let n=await open(e,"r");try{let[i,o,s]=await Promise.all([lstat(e),n.stat(),realpath(e)]);if(i.isSymbolicLink())throw new Error(`${t} must not be a symbolic link: ${P(e)}.`);if(!o.isFile())throw new Error(`${t} must be a regular file: ${P(e)}.`);if(o.size>r)throw new Error(`${t} exceeds the ${r}-byte inspection limit: ${P(e)}.`);let u=await n.readFile();if(u.byteLength>r)throw new Error(`${t} grew beyond the ${r}-byte inspection limit while being read.`);return {path:s,data:u}}finally{await n.close();}}a(Ee,"readBoundedRegularFile");async function A(e,r){let t=l.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: ${P(e)}.`)}catch(o){if(Q(o)!=="ENOENT")throw o}let n=l.join(t,`.${l.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(A,"writeAtomicRegularFile");async function Re(e,r){let t=l.dirname(e);await mkdir(t,{recursive:true});let n=l.join(t,`.${l.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(Q(o)==="EEXIST")return !1;throw o}}finally{await i?.close().catch(()=>{}),await rm(n,{force:true});}}a(Re,"writeNewRegularFile");async function xr(e,r,t){return Ee(e,r,t)}a(xr,"readExternalRegularFile");async function L(e,r,t){let n=l.resolve(e),i=l.resolve(r);if(!C(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[s,u]=await Promise.all([realpath(n),realpath(i)]);if(!C(s,u))throw new Error(`${t} resolves outside its allowed directory.`);return u}a(L,"canonicalDirectoryWithin");async function _(e,r,t,n){let i=l.resolve(e),o=l.resolve(r);if(!C(i,o)||i===o)throw new Error(`${n} escapes its allowed directory.`);let s=await Ee(o,t,n),u=await realpath(i);if(!C(u,s.path)||u===s.path)throw new Error(`${n} resolves outside its allowed directory.`);return s}a(_,"readRegularFileWithin");async function Pr(e,r,t,n=8192){let o=[await L(e,r,"Inspected directory")],s=[],u=0;for(;o.length>0;){let p=o.shift();if(p===void 0)break;let E=(await readdir(p,{withFileTypes:true})).sort((m,f)=>m.name.localeCompare(f.name));for(let m of E){if(u+=1,u>n)throw new Error(`Inspected directory exceeds the ${n}-entry limit.`);let f=l.join(p,m.name);if(m.isSymbolicLink())throw new Error(`Inspected directory contains a symbolic link: ${P(l.relative(e,f))}.`);if(m.isDirectory()){o.push(await L(e,f,"Nested inspected directory"));continue}if(m.isFile()&&t(m.name))s.push(f);else if(t(m.name))throw new Error(`Semantic input is not a regular file: ${P(f)}.`)}}return s.sort()}a(Pr,"listRegularFilesRecursively");var re="three-blocks.shaders.json",Or=".three-blocks/shaders",Dr=".three-blocks/shaders/parity",tr=/^[a-z0-9][a-z0-9_-]{0,63}$/u,nr=/^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$/u,ke=64,Te=64,Ae={schemaVersion:1,scenes:[{key:"default",url:"/"}]};function je(e,r,t){if(e===void 0)return t;if(typeof e!="string"||e.length===0||e.length>512||l.isAbsolute(e)||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${r} must be a bounded project-relative directory.`);let n=l.posix.normalize(e.replaceAll("\\","/")).replace(/\/+$/u,"");if(n==="."||n===".."||n.startsWith("../"))throw new Error(`${r} must stay inside the project.`);return n}a(je,"safeProjectDirectory");function ir(e,r){let t=je(e,r,"");if(typeof e!="string"||e.endsWith("/"))throw new Error(`${r} must be a project-relative file.`);return t}a(ir,"safeProjectFile");function k(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(k,"boundedInteger");function xe(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(xe,"finiteRatio");function Pe(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(Pe,"safeBrowserUrl");function or(e){if(!Array.isArray(e)||e.length===0||e.length>ke)throw new Error(`Shader config scenes must contain 1...${ke} entries.`);let r=new Set;return e.map((t,n)=>{if(!c(t)||typeof t.key!="string"||!tr.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>Te))throw new Error(`Shader config scene "${t.key}" inputs must contain 1...${Te} files.`);let s=t.inputs===void 0?void 0:t.inputs.map((u,p)=>ir(u,`Shader config scene "${t.key}" input ${p}`));if(s!==void 0&&new Set(s).size!==s.length)throw new Error(`Shader config scene "${t.key}" inputs must be unique.`);if(t.allowPipelineReuse!==void 0&&typeof t.allowPipelineReuse!="boolean")throw new Error(`Shader config scene "${t.key}" allowPipelineReuse must be a boolean.`);if(t.runtimeMotion!==void 0&&typeof t.runtimeMotion!="boolean")throw new Error(`Shader config scene "${t.key}" runtimeMotion must be a boolean.`);return {key:t.key,url:Pe(t.url,`Shader config scene "${t.key}" URL`),requiresText:t.requiresText===true,...s===void 0?{}:{inputs:s},...i===void 0?{}:{parityFrames:k(i,`Shader config scene "${t.key}" parityFrames`,0,1e4,0)},...o===void 0?{}:{maxDiffRatio:xe(o,`Shader config scene "${t.key}" maxDiffRatio`,.01)},...t.allowPipelineReuse===true?{allowPipelineReuse:true}:{},...t.runtimeMotion===true?{runtimeMotion:true}:{}}})}a(or,"parseScenes");function v(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&&Pe(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 s=c(o)?o.selector:void 0;if(s!==void 0&&(typeof s!="string"||s.length===0||s.length>512||/[\u0000-\u001f\u007f]/u.test(s)))throw new Error("Shader readiness selector must be a bounded, non-empty CSS selector.");let u=c(o)?o.global:void 0;if(u!==void 0&&(typeof u!="string"||!nr.test(u)))throw new Error("Shader readiness global must be a dot-separated JavaScript property path.");return {schemaVersion:1,scenes:or(e.scenes),settleFrames:k(e.settleFrames,"Shader settleFrames",0,1e4,60),settleTimeoutMs:k(e.settleTimeoutMs,"Shader settleTimeoutMs",1e3,15*6e4,3e4),browserRelaunchScenes:k(e.browserRelaunchScenes,"Shader browserRelaunchScenes",1,64,8),timeoutMs:k(e.timeoutMs,"Shader timeoutMs",1e3,15*6e4,24e4),viewport:{width:k(c(r)?r.width:void 0,"Shader viewport width",64,8192,1024),height:k(c(r)?r.height:void 0,"Shader viewport height",64,8192,640)},parity:{frames:k(c(t)?t.frames:void 0,"Shader parity frames",0,1e4,90),channelTolerance:k(c(t)?t.channelTolerance:void 0,"Shader parity channelTolerance",0,255,8),maxDiffRatio:xe(c(t)?t.maxDiffRatio:void 0,"Shader parity maxDiffRatio",.01)},bridge:{legacyLab:c(n)&&n.legacyLab===true,...typeof i=="string"?{deterministicModule:i}:{}},readiness:{...typeof s=="string"?{selector:s}:{},...typeof u=="string"?{global:u}:{}},publicDir:je(e.publicDir,"Shader publicDir","public"),allowLiveBuilds:e.allowLiveBuilds!==false}}a(v,"parseShaderToolConfig");async function Br(e=process.cwd()){let r=l.resolve(e);for(;;){if(await S(l.join(r,re))||await S(l.join(r,"three-blocks.json")))return realpath(r);let t=l.join(r,"package.json");if(await S(t)){let i=await _(r,t,$.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(p=>typeof p.three=="string"||typeof p["three-blocks"]=="string"||typeof p["@three-blocks/devtools"]=="string"))return realpath(r)}let n=l.dirname(r);if(n===r)throw new Error(`No Three Blocks shader project found from ${JSON.stringify(l.resolve(e))}; add Three.js to package.json or pass --root.`);r=n;}}a(Br,"findShaderProjectRoot");async function ee(e){let r=await realpath(e),t=l.join(r,re);if(await S(t)){let i=await _(r,t,$.metadata,"Shader configuration");return v(JSON.parse(i.data.toString("utf8")))}let n=l.join(r,"three-blocks.json");if(await S(n)){let i=ge(JSON.parse(await readFile(n,"utf8")));return v({schemaVersion:1,scenes:[{key:i.template,url:"/",requiresText:i.features.text}]})}return v(Ae)}a(ee,"loadShaderToolConfig");async function Fr(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 S(l.join(r,o)))return {driverKind:"vite",reason:`Detected ${o}.`};let t,n=l.join(r,"package.json");if(await S(n)){let o=await _(r,n,$.packageJson,"Project package.json"),s=JSON.parse(o.data.toString("utf8"));c(s)&&(t=s);}let i=a(o=>[t?.dependencies,t?.devDependencies,t?.peerDependencies,t?.optionalDependencies].some(s=>c(s)&&typeof s[o]=="string"),"hasDependency");if(i("vite"))return {driverKind:"vite",reason:"Detected the Vite dependency."};for(let o of ["dist","build","out"])if(await S(l.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(Fr,"inferShaderCaptureTarget");async function Lr(e){let r=await realpath(e),t=l.join(r,re);if(await S(t))return {config:await ee(r),file:t,created:false};let n=l.join(r,"three-blocks.json");if(await S(n))return {config:await ee(r),file:n,created:false};let i=Ae,o=v(i),s=await Re(t,`${JSON.stringify(i,null,2)}
2
- `);return {config:s?o:await ee(r),file:t,created:s}}a(Lr,"ensureShaderToolConfig");var te="0.1.0";var ae=3,de="timing.local.json",ce="timing.json",Fe="parity.json",U=4096,dr=4096;function ne(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(ne,"boundedString");function h(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(h,"nonNegativeNumber");function cr(e){if(!c(e))throw new Error("Shader capture stats are missing.");let r={buildCalls:h(e.buildCalls,"capture stats.buildCalls"),renderBuilds:h(e.renderBuilds,"capture stats.renderBuilds"),computeBuilds:h(e.computeBuilds,"capture stats.computeBuilds"),registeredBuilds:h(e.registeredBuilds,"capture stats.registeredBuilds"),registeredRenderBuilds:h(e.registeredRenderBuilds,"capture stats.registeredRenderBuilds"),registeredComputeBuilds:h(e.registeredComputeBuilds,"capture stats.registeredComputeBuilds"),buildMs:h(e.buildMs,"capture stats.buildMs",false),injected:h(e.injected,"capture stats.injected"),injectedRender:h(e.injectedRender,"capture stats.injectedRender"),injectedCompute:h(e.injectedCompute,"capture stats.injectedCompute"),missed:h(e.missed,"capture stats.missed"),missedRender:h(e.missedRender,"capture stats.missedRender"),missedCompute:h(e.missedCompute,"capture stats.missedCompute"),...Array.isArray(e.missedKeys)&&e.missedKeys.every(t=>typeof t=="string")?{missedKeys:e.missedKeys.slice(0,U)}:{}};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)throw new Error("Shader capture stats totals are inconsistent.");return r}a(cr,"captureStats");function ur(e){if(!Array.isArray(e)||e.length>U)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:ne(r.name,`skipped build ${t} name`,512),reason:ne(r.reason,`skipped build ${t} reason`)}})}a(ur,"skippedBuilds");function lr(e){let r=0,t=0,n=0,i=0;for(let o of Object.values(e.entries)){let s=e.states[o];s!==void 0&&((s.vertex!==null||s.fragment!==null)&&r++,s.vertex!==null&&t++,s.fragment!==null&&n++,s.compute!==null&&i++);}return {render:r,vertex:t,fragment:n,compute:i}}a(lr,"shaderCoverage");function Yr(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.");if(e.compatibility!==THREE_WEBGPU_R185_COMPATIBILITY)throw new Error(`Shader capture compatibility must be "${THREE_WEBGPU_R185_COMPATIBILITY}".`);if(!c(e.entries))throw new Error("Shader capture entries must be an object.");let t=Object.keys(e.entries).length;if(t===0||t>U)throw new Error(`Shader capture must contain 1...${U} entries.`);if(!Array.isArray(e.errors)||e.errors.length>dr)throw new Error("Shader capture errors are invalid.");let n=e.errors.map((f,d)=>ne(f,`capture error ${d}`,64*1024));if(n.length>0)throw new Error(`Shader capture failed:
3
- - ${n.join(`
4
- - `)}`);let i=ur(e.skipped),o=cr(e.stats),s=c(e.timing)?e.timing:void 0,u=s===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(f=>{let d=s[f];if(d===void 0)return [];if(typeof d!="number"||!Number.isFinite(d)||d<0)throw new Error(`Shader capture timing.${f} is invalid.`);return [[f,d]]})),p;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(f=>typeof f=="string"&&f.length<=128))throw new Error("Shader capture provenance is invalid.");p={userAgent:e.provenance.userAgent,adapter:e.provenance.adapter,features:[...new Set(e.provenance.features)].sort()};}let E=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:r.scene,three:r.runtime.three,threeBlocks:r.runtime.threeBlocks,runtime:{id:THREE_WEBGPU_R185_COMPATIBILITY,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...e.automatic===void 0?{}:{automatic:e.automatic},modules:e.modules,nodes:e.nodes,layouts:e.layouts,attributePlans:e.attributePlans,updatePlans:e.updatePlans,requirementPlans:e.requirementPlans,states:e.states,entries:e.entries}),m=lr(E);if(o.registeredRenderBuilds<m.render||o.registeredComputeBuilds<m.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:r.scene,manifest:E,skipped:i,stats:o,coverage:m,...u===void 0?{}:{timing:u},...p===void 0?{}:{provenance:p}}}a(Yr,"validateShaderCapture");function T(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}${T(o,r+1)}`).join(`,
6
- `)}
7
- ${t}]`;if(e!==null&&typeof e=="object"){let o=e,s=Object.keys(o).sort();return s.length===0?"{}":`{
8
- ${s.map(u=>{let p=o[u];return `${n}${JSON.stringify(u)}: ${T(p,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(T,"stableStringify");function pr(e){return ["// GENERATED FILE \u2014 do not edit by hand.","// Produced by @three-blocks/devtools.","import type { PrecompiledManifest } from 'three-blocks/shaders';","",`export default ${T(e)} satisfies PrecompiledManifest;`,""].join(`
11
- `)}a(pr,"serializeShaderManifest");function _e(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(_e,"timingLabel");function ie(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:h(i.builds,`timing ${n}.builds`),liveBuildMs:h(i.liveBuildMs,`timing ${n}.liveBuildMs`,false),precompiledBuildMs:h(i.precompiledBuildMs,`timing ${n}.precompiledBuildMs`,false),avoidedBuildMs:h(i.avoidedBuildMs,`timing ${n}.avoidedBuildMs`,false),runs:h(i.runs,`timing ${n}.runs`),spreadMs:h(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:_e(e.adapter,"Shader timing adapter"),platform:_e(e.platform,"Shader timing platform")}}a(ie,"parseShaderTiming");function oe(e){return /^[a-z0-9][a-z0-9_-]{0,63}$/u.test(e)}a(oe,"validParityScene");function Ie(e){return typeof e=="string"&&Number.isFinite(Date.parse(e))}a(Ie,"validParityTimestamp");function Le(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)||!Ie(e.verifiedAt)||!Array.isArray(e.scenes)||e.scenes.length===0||e.scenes.length>64||!e.scenes.every(n=>typeof n=="string"&&oe(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],[s])=>o.localeCompare(s))){if(!oe(n)||!c(i)||typeof i.fingerprint!="string"||!/^[a-f0-9]{64}$/u.test(i.fingerprint)||!Ie(i.verifiedAt))throw new Error("Shader parity evidence is invalid.");t[n]={fingerprint:i.fingerprint,verifiedAt:i.verifiedAt};}return {schemaVersion:2,scenes:t}}a(Le,"parseShaderParityEvidence");function se(e,r){let t=e.scenes[r];if(t===void 0)throw new Error(`Shader receipt has no scene "${r}" for parity evidence.`);return R(T({runtime:{three:e.runtime.three,threeBlocks:e.runtime.threeBlocks,threeBlocksShaderClosure:e.runtime.threeBlocksShaderClosure},...e.tool===void 0?{}:{tool:e.tool},scene:t}))}a(se,"shaderSceneParityFingerprint");async function z(e,r,t,n){let i=l.join(e,t);try{if(!await S(i))return;let o=await lstat(i);if(o.isSymbolicLink()||!o.isFile()||o.size>1024*1024)return;let s=ie(JSON.parse(await readFile(i,"utf8")));return s.source===n&&s.receiptHash===R(r)?s:void 0}catch{return}}a(z,"readShaderTimingFile");async function Zr(e,r){let t=await z(e,r,de,"latest-local-capture");return t?.source==="latest-local-capture"?t:void 0}a(Zr,"readShaderLocalTiming");async function Qr(e,r){return await z(e,r,de,"latest-local-capture")??await z(e,r,ce,"committed-capture")}a(Qr,"readShaderTiming");async function fr(e,r){let t=l.join(e,Fe);try{if(!await S(t))return;let n=await lstat(t);if(n.isSymbolicLink()||!n.isFile()||n.size>1024*1024)return;let i=Le(JSON.parse(await readFile(t,"utf8"))),o=B(JSON.parse(Buffer.from(r).toString("utf8"))),s={};if(i.schemaVersion===1){if(i.receiptHash!==R(r))return;for(let u of i.scenes)o.scenes[u]!==void 0&&(s[u]={fingerprint:se(o,u),verifiedAt:i.verifiedAt});}else for(let[u,p]of Object.entries(i.scenes))o.scenes[u]===void 0||p.fingerprint!==se(o,u)||(s[u]=p);return Object.keys(s).length===0?void 0:{schemaVersion:2,scenes:s}}catch{return}}a(fr,"readShaderParityEvidence");async function et(e,r){let t=await z(e,r,ce,"committed-capture");return t?.source==="committed-capture"?t:void 0}a(et,"readShaderCommittedTiming");async function Ve(e,r,t){let n=await ue(e),i=l.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 s=await readFile(i),u=new Date().toISOString(),p=Object.fromEntries(Object.entries(r).sort(([f],[d])=>f.localeCompare(d))),E=ie({schemaVersion:3,receiptHash:R(s),measuredAt:u,source:"latest-local-capture",scenes:p});if(await A(l.join(n,de),`${T(E)}
12
- `),t===void 0)return {local:E};let m=ie({schemaVersion:3,receiptHash:R(s),measuredAt:u,source:"committed-capture",adapter:t.adapter,platform:t.platform,scenes:p});return await A(l.join(n,ce),`${T(m)}
13
- `),{local:E,committed:m}}a(Ve,"writeShaderTimings");async function rt(e,r){return (await Ve(e,r)).local}a(rt,"writeShaderLocalTiming");async function tt(e,r,t){if(r.length===0||r.length>64||r.some(d=>!oe(d)))throw new Error("Shader parity evidence must contain 1...64 valid scene keys.");let n=await ue(e),i=l.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 s=await readFile(i);if(t!==void 0&&R(s)!==R(t))throw new Error("Shader receipt changed during browser parity verification; completed observations were not attached to the new receipt.");let u=B(JSON.parse(s.toString("utf8"))),p=await fr(n,s),E=new Date().toISOString(),m={...p?.scenes};for(let d of [...new Set(r)].sort())m[d]={fingerprint:se(u,d),verifiedAt:E};let f=Le({schemaVersion:2,scenes:m});return await A(l.join(n,Fe),`${T(f)}
14
- `),f}a(tt,"writeShaderParityEvidence");async function nt(e,r,t){let n=await Ve(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(nt,"writeShaderTimingTwins");async function Me(e){if(!await S(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(Me,"assertDirectory");async function ue(e){let r=l.resolve(e),t=l.join(r,".three-blocks");await Me(t);let n=l.join(t,"shaders");return await Me(n),n}a(ue,"artifactRoot");async function it(e){let r=await ue(e.root),t=l.resolve(e.root),n=l.resolve(t,e.publicDirectory??"public");if(!C(t,n)||n===t)throw new Error("Shader public directory must stay inside the project root.");let i=l.join(n,"three-blocks","shaders");await mkdir(i,{recursive:true}),await L(t,i,"Shader static-asset directory");let o={},s=[];for(let d of [...e.scenes].sort((b,I)=>b.key.localeCompare(I.key))){let b=e.captures.get(d.key),I=e.inputs.get(d.key);if(I===void 0)throw new Error(`Shader input matrix is missing scene "${d.key}".`);if(b===void 0){let y=e.previousReceipt?.scenes[d.key];if(y===void 0)throw new Error(`Capture matrix is missing scene "${d.key}".`);let q=await readFile(l.join(r,y.artifact));if(R(q)!==y.artifactHash)throw new Error(`Preserved shader artifact checksum differs for scene "${d.key}".`);if(y.asset!==void 0&&y.assetHash!==void 0){let X=await readFile(l.join(n,y.asset));if(R(X)!==y.assetHash)throw new Error(`Preserved static shader manifest checksum differs for scene "${d.key}".`)}o[d.key]={...y,inputs:Object.fromEntries(Object.entries(I).sort(([X],[Je])=>X.localeCompare(Je)))},s.push(y.artifact),y.asset!==void 0&&s.push(l.relative(t,l.join(n,y.asset)).split(l.sep).join("/"));continue}if(b.scene!==d.key||b.manifest.scene!==d.key)throw new Error(`Capture matrix scene "${d.key}" is inconsistent.`);let G=`${d.key}.webgpu.ts`,J=pr(b.manifest);await A(l.join(r,G),J),s.push(G);let K=`three-blocks/shaders/${d.key}.json`,fe=`${T(b.manifest)}
15
- `;await A(l.join(n,K),fe),s.push(l.relative(t,l.join(n,K)).split(l.sep).join("/"));let me=b.skipped.filter(y=>y.kind==="render").length,Ge=b.skipped.length-me;o[d.key]={artifact:G,artifactHash:R(J),asset:K,assetHash:R(fe),inputs:Object.fromEntries(Object.entries(I).sort(([y],[q])=>y.localeCompare(q))),coverage:b.coverage,bytes:Buffer.byteLength(J),skipped:{render:me,compute:Ge}};}let u=[...e.captures.values()].find(d=>d.provenance!==void 0)?.provenance??e.previousReceipt?.runtime.capture,p={schemaVersion:2,runtime:{...e.runtime,...u===void 0?{}:{capture:u}},tool:{name:"@three-blocks/devtools",version:te,compatibility:THREE_WEBGPU_R185_COMPATIBILITY,transform:ae,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},scenes:o},E=new Set(s);for(let d of await readdir(r,{withFileTypes:true}))if(!(!d.name.endsWith(".webgpu.ts")||E.has(d.name))){if(d.isSymbolicLink()||!d.isFile())throw new Error(`Orphan shader artifact is not a regular file: ${d.name}.`);await unlink(l.join(r,d.name));}let m=new Set(e.scenes.map(d=>`${d.key}.json`)),f=new Set(Object.values(e.previousReceipt?.scenes??{}).map(d=>d.asset===void 0?void 0:l.posix.basename(d.asset)).filter(d=>d!==void 0));try{let d=B(JSON.parse(await readFile(l.join(r,"meta.json"),"utf8")));for(let b of Object.values(d.scenes))b.asset!==void 0&&f.add(l.posix.basename(b.asset));}catch{}for(let d of await readdir(i,{withFileTypes:true}))if(!(!d.name.endsWith(".json")||m.has(d.name))&&f.has(d.name)){if(d.isSymbolicLink()||!d.isFile())throw new Error(`Orphan shader static asset is not a regular file: ${d.name}.`);await unlink(l.join(i,d.name));}return await A(l.join(r,"meta.json"),`${T(p)}
16
- `),s.push("meta.json"),{directory:r,receipt:p,files:s}}a(it,"writeShaderArtifacts");var O;async function W(){O===void 0&&(O=(async()=>{let r=createRequire(l.join(process.cwd(),"package.json")).resolve("@three-blocks/devtools/browser/shader-capture"),t=l.resolve(l.dirname(r),"../..");return (await _(t,r,$.metadata,"Shader capture browser runtime")).data.toString("utf8")})());let e=O;try{return await e}catch(r){throw O===e&&(O=void 0),r}}a(W,"loadShaderCaptureRuntimeSource");var ve="virtual:three-blocks-shader-capture-client",He="\0three-blocks:shader-capture-client",pe="virtual:three-blocks-shader-capture-runtime",Ue="\0three-blocks:shader-capture-runtime";async function St(){let e=await W(),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(St,"loadShaderCaptureRuntimeScriptSource");function Sr(e){let r=e.split("?",1)[0];return r===void 0?false:r.split(l.sep).join("/").endsWith("/build/three.webgpu.js")}a(Sr,"isThreeWebGPUModule");function We(e){let r=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u.exec(e);return r?.[1]==="0"&&r[2]==="185"}a(We,"supportedVersion");function wr(e,r,t={}){if(!We(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,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}}).code),{code:o,alreadyPresent:i,captureApplied:t.instrumentCapture===true}}a(wr,"applyShaderProviderTransform");var br=/this\.trackTimestamp\s*=\s*\(\s*parameters\.trackTimestamp\s*===\s*true\s*\);/gu,Er="Object.defineProperty( this, 'trackTimestamp', { get: () => false, set: () => {} } );";function wt(e,r={}){if(!We(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===ve?He:r.capture&&i===pe?Ue:null},async load(i){return r.capture?i===Ue?W():i===He?[`export * from '${pe}';`,`import { configureThreeBlocksShaderCapture } from '${pe}';`,`configureThreeBlocksShaderCapture( ${JSON.stringify({capture:r.capture.capture,forceLive:r.capture.forceLive,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:ae})} );`].join(`
17
- `):null:null},transform(i,o){if(!Sr(o))return null;t.seen=true,t.id=o;try{let s=wr(i,e,{instrumentCapture:r.capture!==void 0,...r.capture!==void 0?{captureRuntimeImport:ve}:{}}),u=r.disableTimestampQueries===!0?s.code.replace(br,Er):s.code;if(r.disableTimestampQueries===!0&&u===s.code)throw new Error("Three.js timestamp tracking anchor drifted; refusing software WebGPU capture.");return t.applied=!0,t.alreadyPresent=s.alreadyPresent,t.captureApplied=s.captureApplied,u===i?null:{code:u,map:null}}catch(s){throw t.error=s instanceof Error?s.message:String(s),s}}},status:t}}a(wt,"createShaderProviderTransform");function bt(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(bt,"assertShaderProviderTransform");export{lr as A,Yr as B,T as C,pr as D,Zr as E,Qr as F,fr as G,et as H,rt as I,tt as J,nt as K,it as L,W as M,ve as N,St as O,Sr as P,wr as Q,wt as R,bt as S,c as a,ge as b,B as c,$ as d,Q as e,R as f,S as g,C as h,A as i,xr as j,L as k,_ as l,Pr as m,re as n,Or as o,Dr as p,v as q,Br as r,ee as s,Fr as t,Lr as u,te as v,ae as w,de as x,ce as y,Fe as z};
@@ -1,78 +0,0 @@
1
- import {d,a as a$1,R,S,w,O,m,l,h,g,M}from'./chunk-SCJNCGMF.js';import {a}from'./chunk-EI7MMDWY.js';import b from'process';import {createServer}from'http';import {createRequire}from'module';import {mkdtemp,rm,lstat,realpath}from'fs/promises';import E from'path';import {tmpdir}from'os';import {pathToFileURL}from'url';import {THREE_WEBGPU_R185_COMPATIBILITY}from'three-blocks/shaders';var ve=Object.freeze([{id:"three-inspector-invalid-json",pattern:/is not valid JSON/iu},{id:"chromium-webgpu-experimental",pattern:/WebGPU is experimental/iu}]);function We(r){return ve.some(e=>e.pattern.test(r))}a(We,"isDocumentedBrowserNoise");function Z(r=b.env,e=b.platform){let t=r.THREE_BLOCKS_WEBGPU_BROWSER_ARGS?.split(/\s+/u).filter(Boolean);if(t&&t.length>0)return t;let n=["--enable-unsafe-webgpu"];return e==="darwin"&&n.push("--enable-gpu","--use-angle=metal"),e==="linux"&&n.push("--enable-features=Vulkan","--disable-vulkan-surface","--ignore-gpu-blocklist","--disable-gpu-driver-bug-workarounds","--disable-gpu-watchdog"),n}a(Z,"webgpuBrowserArgs");function ee(r=false,e=b.env){return r!==true&&e.THREE_BLOCKS_SOFTWARE_WEBGPU!=="1"}a(ee,"webgpuBrowserHeadless");var te="three-blocks.shader-capture.runtime.v1";var ce="/__three-blocks/shaders/capture",D="/__three-blocks/shaders/telemetry",le="/__three-blocks/shaders/runtime.js",ue="/__three-blocks/shaders/bootstrap.js",he="/__three-blocks/shaders/bridge.js",me=d.manifest*2,K=/^[a-z0-9][a-z0-9_-]{0,63}$/u,fe=64,pe=2e3,Be=[/is not valid JSON/iu,/WebGPU is experimental/iu];async function xe(){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(xe,"loadChromium");async function Oe(r){let e;try{e=createRequire(E.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(Oe,"loadProjectCreateServer");var W=class{static{a(this,"CaptureInbox");}#e=new Map;#t=new Map;wait(e,t){let n=this.#t.get(e);if(n!==void 0)return this.#t.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((a,o)=>{let s=setTimeout(()=>{this.#e.delete(e),o(new Error(`Shader capture "${e}" timed out after ${t}ms.`));},t);this.#e.set(e,{resolve:a,reject:o,timer:s});})}receive(e){if(!a$1(e)||typeof e.scene!="string"||!K.test(e.scene))throw new Error("Capture POST has no safe scene key.");if(!this.#t.has(e.scene)&&!this.#e.has(e.scene)&&this.#t.size>=fe)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.#t.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.#t.clear();}};async function je(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(je,"waitForShaderCaptureAcrossNavigation");var G=class{static{a(this,"TelemetryHub");}#e=new Map;#t=new Map;markFirstRequest(e){K.test(e)&&!this.#t.has(e)&&this.#t.set(e,Date.now());}firstRequest(e){return this.#t.get(e)}receive(e){if(!a$1(e)||typeof e.scene!="string"||!K.test(e.scene))throw new Error("Shader telemetry has no bounded scene key.");if(!this.#e.has(e.scene)&&this.#e.size>=fe)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.#t.delete(e);}},Le=a(async(r,e,t,n,a)=>{let o=0;for(;r.__threeBlocksParityUsesAnimationLoop!==true&&o<e;)await n(),o+=1;if(r.__threeBlocksParityUsesAnimationLoop===true){let s=Number(r.__threeBlocksParityCompletedFrame||0),i=Number(t),l=Number.isSafeInteger(i)&&i>=s?i:s+e;for(r.__threeBlocksParityTargetFrame=l;Number(r.__threeBlocksParityCompletedFrame||0)<l;)await n();}return await a(),Number(r.__threeBlocksParityCompletedFrame||0)},"settleShaderParityFrames");function q(){return `(() => {
2
- const root = globalThis;
3
- const scene = new URL(location.href).searchParams.get('captureId')
4
- || 'default';
5
- // Keep the wall clock native so shader build durations and loader deadlines stay
6
- // truthful. Deterministic application time is supplied by renderer/Timer capture hooks.
7
- const randomSeed = (value) => {
8
- let state = 2166136261;
9
- for (let index = 0; index < value.length; index++) state = Math.imul(state ^ value.charCodeAt(index), 16777619) >>> 0;
10
- return state === 0 ? 0x9e3779b9 : state;
11
- };
12
- const advanceRandom = (state) => {
13
- state ^= state << 13;
14
- state ^= state >>> 17;
15
- state ^= state << 5;
16
- return state >>> 0;
17
- };
18
- const parityMode = new URL(location.href).searchParams.get('threeBlocksShaderMode');
19
- const randomStreams = new Map();
20
- let randomState = randomSeed(scene);
21
- Math.random = () => {
22
- if (parityMode === 'live' || parityMode === 'precompiled') {
23
- const stackLine = String(new Error().stack || '').split('\\n')[2] || 'unknown';
24
- const originIndex = stackLine.indexOf(location.origin);
25
- const callsite = (originIndex >= 0 ? stackLine.slice(0, originIndex) : stackLine).trim() || 'anonymous';
26
- const next = advanceRandom(randomStreams.get(callsite) ?? randomSeed(scene + '|' + callsite));
27
- randomStreams.set(callsite, next);
28
- return next / 4294967296;
29
- }
30
- randomState = advanceRandom(randomState);
31
- return randomState / 4294967296;
32
- };
33
- const readiness = { workerReady: false, assetsReady: false, textReady: false, compileEnd: false, firstFrame: false };
34
- const stats = { buildCalls: 0, renderBuilds: 0, computeBuilds: 0, registeredBuilds: 0, registeredRenderBuilds: 0, registeredComputeBuilds: 0, buildMs: 0, injected: 0, injectedRender: 0, injectedCompute: 0, missed: 0, missedRender: 0, missedCompute: 0, missedKeys: [] };
35
- const settleParityFrames = ${Le.toString()};
36
- const settle = (frames, requestedTarget) => settleParityFrames(
37
- root,
38
- frames,
39
- requestedTarget,
40
- () => new Promise((resolve) => requestAnimationFrame(resolve)),
41
- () => new Promise((resolve) => setTimeout(resolve, 100)),
42
- );
43
- const bridge = { protocolVersion: 1, compatibility: ${JSON.stringify(THREE_WEBGPU_R185_COMPATIBILITY)}, transform: ${w}, readiness, stats, settle };
44
- root.__threeBlocksShaderTools = bridge;
45
- requestAnimationFrame(() => requestAnimationFrame(() => { readiness.firstFrame = true; }));
46
- const poll = async () => {
47
- try {
48
- const response = await fetch('/__three-blocks/shaders/telemetry?scene=' + encodeURIComponent(scene), { cache: 'no-store' });
49
- if (response.status !== 204 && response.ok) {
50
- const payload = await response.json();
51
- if (payload.protocolVersion !== 1 || payload.compatibility !== bridge.compatibility || payload.transform !== bridge.transform) throw new Error('incompatible shader telemetry');
52
- Object.assign(stats, payload.stats);
53
- readiness.workerReady = true;
54
- if (payload.settled === true) {
55
- readiness.assetsReady = true;
56
- readiness.textReady = true;
57
- readiness.compileEnd = true;
58
- }
59
- const smoke = root.__threeBlocksSmoke && typeof root.__threeBlocksSmoke === 'object' ? root.__threeBlocksSmoke : { protocolVersion: 1, worker: { offscreenCanvas: true, visible: true }, readiness: {} };
60
- smoke.readiness = { ...(smoke.readiness || {}), ...readiness };
61
- root.__threeBlocksSmoke = smoke;
62
- }
63
- } catch {}
64
- setTimeout(poll, 40);
65
- };
66
- void poll();
67
- })();`}a(q,"publicBridgeScript");function we(r,e,t,n,a=false){let o=new URL(r.url??"/","http://three-blocks.invalid"),s=o.pathname;if(a&&r.method==="GET"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.json$/u.test(s))return e.statusCode=204,e.end(),true;if(s===D&&r.method==="GET"){let u=o.searchParams.get("scene")??"",h=n.read(u);return h===void 0?(e.statusCode=204,e.end()):(e.statusCode=200,e.setHeader("Content-Type","application/json"),e.end(JSON.stringify(h))),true}let i=s===ce,l=s===D;if(!i&&!l)return false;if(r.method!=="POST")return e.statusCode=405,e.end("POST required"),true;let m=[],p=0,w=false;return r.on("data",u=>{p+=u.byteLength,p>me?w=true:m.push(u);}),r.on("end",()=>{if(w){e.statusCode=413,e.end("capture payload too large");return}try{let u=JSON.parse(Buffer.concat(m).toString("utf8"));l?n.receive(u):t.receive(u),e.statusCode=204,e.end();}catch(u){e.statusCode=400,e.end(u instanceof Error?u.message:String(u));}}),true}a(we,"handleCaptureEndpoint");function Ae(r,e,t){return {name:"three-blocks:shader-capture-endpoint",transformIndexHtml(){return [{tag:"script",children:q(),injectTo:"head-prepend"}]},configureServer(n){n.middlewares.use((a,o,s)=>{let l=new URL(a.url??"/","http://three-blocks.invalid").searchParams.get("captureId");l!==null&&e.markFirstRequest(l),!we(a,o,r,e,t)&&s();});}}}a(Ae,"captureEndpointPlugin");function ne(r,e,t){let n=new URL(e.url,r);for(let[a,o]of Object.entries(t))n.searchParams.set(a,o);return n.href}a(ne,"browserUrl");function Fe(r,e){let t=new URL(e.url,r);for(let n of ["capture","precompiled"])t.searchParams.delete(n);return t.searchParams.set("captureId",e.key),t.searchParams.set("threeBlocksShaderMode","precompiled"),t.searchParams.set("tbStats","1"),t.href}a(Fe,"publishedBrowserUrl");function ae(r){return Be.some(e=>e.test(r))}a(ae,"knownNoise");async function P(r){let e;try{await Promise.race([r(),new Promise(t=>{e=setTimeout(t,pe);})]);}catch{}finally{e&&clearTimeout(e);}}a(P,"closeBrowserResource");async function oe(r){let e;try{return await Promise.race([r().catch(()=>null),new Promise(t=>{e=setTimeout(()=>t(null),pe);})])}finally{e!==void 0&&clearTimeout(e);}}a(oe,"readPageDiagnostic");function $(r){let e=a(()=>{},"resolveFirst"),t=new Promise(s=>{e=s;}),n={console:[],page:[],first:t},a$1=false,o=a(s=>{a$1||(a$1=true,e(new Error(s)));},"report");return r.on("console",s=>{let i=s.type()==="warning"&&/\[three-blocks\/shaders\].*(?:has no entry|manifest miss|hydration)/iu.test(s.text());if(s.type()!=="error"&&!i||ae(s.text()))return;let l=s.location().url,m=l.length>0?`${s.text()} (${l})`:s.text();n.console.push(m),o(`Browser console ${i?"warning":"error"}: ${m}`);}),r.on("pageerror",s=>{if(ae(s.message))return;let i=s.stack||s.message;n.page.push(i),o(`Browser page error: ${i}`);}),r.on("crash",()=>o("Browser page crashed before shader capture completed.")),r.on("close",()=>o("Browser page closed before shader capture completed.")),n}a($,"collectErrors");function C(r,e,t=false){return typeof r[e]=="boolean"?r[e]:t}a(C,"booleanField");function De(r){if(!a$1(r))throw new Error("Browser shader stats are unavailable.");let e=a((t,n=true)=>{let a=r[t];if(typeof a!="number"||!Number.isFinite(a)||a<0||n&&!Number.isSafeInteger(a))throw new Error(`Browser shader stats.${t} is invalid.`);return a},"read");return {buildCalls:e("buildCalls"),renderBuilds:e("renderBuilds"),computeBuilds:e("computeBuilds"),registeredBuilds:e("registeredBuilds"),registeredRenderBuilds:e("registeredRenderBuilds"),registeredComputeBuilds:e("registeredComputeBuilds"),buildMs:e("buildMs",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(De,"parseStats");function L(r,e,t,n){if(!a$1(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 a=r.readiness;if(!a$1(a))throw new Error("The shader bridge readiness snapshot is invalid.");let o={workerReady:C(a,"workerReady"),assetsReady:C(a,"assetsReady"),textReady:e.requiresText?C(a,"textReady"):true,compileEnd:C(a,"compileEnd"),firstFrame:C(a,"firstFrame",t)};if(!o.workerReady||!o.assetsReady||!o.textReady||!o.compileEnd)throw new Error(`Scene "${e.key}" did not reach worker/assets/text/compile readiness.`);let s=t?THREE_WEBGPU_R185_COMPATIBILITY:r.compatibility,i=t?w:r.transform;if(s!==THREE_WEBGPU_R185_COMPATIBILITY||i!==w)throw new Error(`Scene "${e.key}" exposed incompatible shader bridge metadata.`);return S(n),{compatibility:s,transform:i,readiness:o,stats:De(r.stats)}}a(L,"parseBridge");async function A(r,e){return r.evaluate(t=>{let n=globalThis;if(!t)return n.__threeBlocksShaderTools??null;let a=n.__threeBlocks,o=n.__threeBlocksTslStats;if(!a||typeof a!="object")return null;let s=a;return {readiness:{workerReady:s.workerReady===true,assetsReady:s.loadEnd===true||s.assetsReady===true,textReady:s.textReady===true,compileEnd:s.compileEnd===true,firstFrame:true},stats:o}},e)}a(A,"readBridge");async function F(r,e,t,n){return r.evaluate(async a$1=>{let s=globalThis.__threeBlocksShaderTools;if(s&&typeof s=="object"){let m=Reflect.get(s,"settle");if(typeof m=="function"){let p=await m(a$1.frames,a$1.targetFrame);return typeof p=="number"&&Number.isSafeInteger(p)?p:0}}if(!a$1.legacy||!a$1.modulePath)throw new Error("The public shader bridge does not provide deterministic settle().");let i=await import(a$1.modulePath);if(!i.store||typeof i.store!="object")throw new Error("Legacy deterministic store is unavailable.");let l=i.store;return l.recordFrameCount=0,l.recordFrameRate=60,l.recordTotalFrames=a$1.frames,l.recording=true,await new Promise((m,p)=>{let w=Date.now(),u=a(()=>{if(l.recording===false)return m();if(Date.now()-w>a$1.timeoutMs)return p(new Error("Legacy deterministic settle timed out."));setTimeout(u,25);},"poll");u();}),0},{frames:t,targetFrame:n,legacy:e.bridge.legacyLab,modulePath:e.bridge.deterministicModule??null,timeoutMs:e.timeoutMs})}a(F,"settlePage");async function se(r,e,t){e.readiness.selector===void 0&&e.readiness.global===void 0||await Promise.race([r.waitForFunction(n=>{let a=globalThis;if(n.selector!==void 0&&a.document?.querySelector(n.selector)==null)return false;if(n.global===void 0)return true;let o=a;for(let l of n.global.split(".")){if((typeof o!="object"||o===null)&&typeof o!="function")return false;o=Reflect.get(o,l);}if(o===true)return true;if(typeof o!="object"||o===null||typeof Reflect.get(o,"then")!="function")return false;let s=a.__threeBlocksReadinessState,i=s instanceof Map?s:new Map;return s instanceof Map||(a.__threeBlocksReadinessState=i),i.has(o)||(i.set(o,false),Promise.resolve(o).then(()=>i.set(o,true),()=>i.set(o,false))),i.get(o)===true},e.readiness,{timeout:e.timeoutMs}),t.first.then(n=>Promise.reject(n))]);}a(se,"waitForConfiguredReadiness");async function ie(r){let e=r.locator("canvas"),n=(await e.evaluateAll(a=>a.map((o,s)=>{let i=o.getBoundingClientRect();return {index:s,area:Math.max(0,i.width)*Math.max(0,i.height)}}))).sort((a,o)=>o.area-a.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(ie,"primaryCanvasScreenshot");async function H(r,e,t,n,a){let o=ge(n,a),s=await O(),i=`(() => {
68
- const runtime = globalThis[Symbol.for(${JSON.stringify(te)})];
69
- if (!runtime || typeof runtime.configureThreeBlocksShaderCapture !== 'function') {
70
- throw new Error('@three-blocks/devtools attached shader capture runtime is incompatible.');
71
- }
72
- runtime.configureThreeBlocksShaderCapture(${JSON.stringify(o).replaceAll("<","\\u003c")});
73
- })();`;await r.addInitScript({content:`${s}
74
- ${i}`}),await r.addInitScript({content:q()}),await r.route("**/*",async l=>{let m=l.request(),p=new URL(m.url()),w=p.pathname;if(m.method()==="GET"&&n!=="precompiled"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.json$/u.test(w)){await l.fulfill({status:204});return}if(w===D&&m.method()==="GET"){let c=t.read(p.searchParams.get("scene")??"");await l.fulfill(c===void 0?{status:204}:{status:200,contentType:"application/json",body:JSON.stringify(c)});return}let u=w===ce,h=w===D;if((u||h)&&m.method()==="POST"){let c=m.postDataBuffer()??Buffer.alloc(0);if(c.byteLength>me){await l.fulfill({status:413,body:"capture payload too large"});return}try{let f=JSON.parse(c.toString("utf8"));h?t.receive(f):e.receive(f),await l.fulfill({status:204});}catch(f){await l.fulfill({status:400,body:f instanceof Error?f.message:String(f)});}return}await l.continue();});}a(H,"configureAttachedContext");var Me=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 Ie(r){let e=[`<script src="${he}"></script>`,`<script type="module" src="${ue}"></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(Ie,"injectStaticShaderCaptureHtml");function Ne(r,e){let t=ge(r,e);return [`import { configureThreeBlocksShaderCapture } from ${JSON.stringify(le)};`,`configureThreeBlocksShaderCapture( ${JSON.stringify(t).replaceAll("<","\\u003c")} );`].join(`
75
- `)}a(Ne,"staticCaptureBootstrap");function ge(r,e){return {capture:r==="capture",forceLive:r!=="precompiled",settleFrames:e.settleFrames,settleTimeoutMs:e.settleTimeoutMs??3e4,readiness:e.readiness,transform:w}}a(ge,"shaderCaptureConfiguration");async function Ue(r,e){let t=await m(r,e,s=>/\.(?:c|m)?js$/u.test(s),16384),n=false,a=false,o;for(let s of t){let i=(await l(r,s,d.texture,"Static application JavaScript")).data.toString("utf8");if(i.includes("nodeBuilderStateProvider")&&(n=true),i.includes("three-blocks.shader-capture.runtime.v1")&&(a=true,o??=s),n&&a)break}if(!n||!a)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,...o===void 0?{}:{id:o}}}a(Ue,"inspectStaticCaptureTransform");async function $e(r,e){let t;try{t=decodeURIComponent(e);}catch{return}if(t.includes("\0"))return;let n=t.replace(/^\/+/u,""),a=E.resolve(r,n.length===0?"index.html":n);if(!h(r,a)||a===r||(await g(a)&&(await lstat(a)).isDirectory()&&(a=E.join(a,"index.html")),!await g(a)&&E.extname(a).length===0&&(a=E.join(r,"index.html")),!await g(a)))return;let o=await l(r,a,d.texture,"Static application asset");return {data:o.data,file:o.path}}a($e,"staticRequestFile");async function He(r,e,t,n,a){let o=await realpath(r.root),s=await realpath(E.resolve(o,r.serve));if(!h(o,s)||s===o)throw new Error("--serve must name a built application directory inside the project root.");let i=await Ue(o,s),l=await M(),m=Ne(e,t),p=q(),w=createServer((h,c)=>{(async()=>{if(we(h,c,n,a,e!=="precompiled"))return;let f=new URL(h.url??"/","http://three-blocks.invalid");if(h.method!=="GET"&&h.method!=="HEAD"){c.statusCode=405,c.end("GET or HEAD required");return}let y=f.pathname===le?l:f.pathname===ue?m:f.pathname===he?p:void 0;if(y!==void 0){c.statusCode=200,c.setHeader("Content-Type","text/javascript; charset=utf-8"),c.setHeader("Cache-Control","no-store"),c.end(h.method==="HEAD"?void 0:y);return}let g=await $e(s,f.pathname);if(g===void 0){c.statusCode=404,c.end("Not found");return}let S=E.extname(g.file).toLowerCase(),B=S===".html"?Buffer.from(Ie(g.data.toString("utf8"))):g.data;c.statusCode=200,c.setHeader("Content-Type",Me[S]??"application/octet-stream"),c.setHeader("Content-Length",String(B.byteLength)),c.setHeader("Cache-Control","no-store"),c.end(h.method==="HEAD"?void 0:B);})().catch(f=>{if(c.headersSent)return c.destroy(f instanceof Error?f:void 0);c.statusCode=500,c.end(f instanceof Error?f.message:String(f));});});await new Promise((h,c)=>{w.once("error",c),w.listen(0,"127.0.0.1",()=>{w.off("error",c),h();});});let u=w.address();if(!u||typeof u=="string")throw new Error("Static capture server did not expose an ephemeral TCP address.");return {server:w,baseUrl:`http://127.0.0.1:${u.port}`,transform:i}}a(He,"startStaticShaderServer");function Ve(r,e,t){return r===e?true:t&&r!==void 0&&r!=="capture"&&e!=="capture"}a(Ve,"canReuseShaderBrowserSession");function de(r){let e=r instanceof Error?r.message:String(r);return e.includes("Execution context was destroyed")&&e.includes("navigation")}a(de,"isRetryableShaderObservationNavigation");var _=class{static{a(this,"PlaywrightShaderDriver");}#e;#t=new W;#n=new G;#u;#h;#o;#s;#r;#a;#m;#d;#f;#c=0;#l;constructor(e){this.#e=e;}#i(){return this.#u?.status??this.#h??{seen:false,applied:false,alreadyPresent:false}}async#p(e){if(this.#r?.isConnected()===true)return;this.#r=void 0;let t=await xe();this.#l??=await mkdtemp(E.join(tmpdir(),"three-blocks-shader-cache-")),this.#r=await t.launch({headless:ee(this.#e.headed===true),args:[...Z(),`--disk-cache-dir=${this.#l}`],timeout:e.timeoutMs}),this.#c=0;}async#w(e,t){let n=this.#o!==void 0||this.#s!==void 0||this.#e.url!==void 0&&this.#a!==void 0,a=this.#s!==void 0?this.#d===e:Ve(this.#d,e,t.bridge.legacyLab);if(n&&a){this.#d=e,await this.#p(t);return}if(n&&await this.close(),this.#d=e,this.#e.url!==void 0){let o=new URL(this.#e.url);if(!["http:","https:"].includes(o.protocol)||o.username||o.password||o.hash)throw new Error("Attached shader URL must be an HTTP(S) URL without credentials or a fragment.");this.#a=o.href,this.#h={seen:true,applied:true,alreadyPresent:false,captureApplied:true,id:"attached-application"},await this.#p(t);return}if(this.#e.serve!==void 0)try{let o=await He({root:this.#e.root,runtime:this.#e.runtime,serve:this.#e.serve,...this.#e.headed===void 0?{}:{headed:this.#e.headed}},e,t,this.#t,this.#n);this.#s=o.server,this.#h=o.transform,this.#a=o.baseUrl,await this.#p(t);return}catch(o){throw await this.close(),o}this.#u=R(this.#e.runtime.three,{disableTimestampQueries:b.env.THREE_BLOCKS_SOFTWARE_WEBGPU==="1",...t.bridge.legacyLab?{}:{capture:{capture:e==="capture",forceLive:e!=="precompiled",settleFrames:t.settleFrames,settleTimeoutMs:t.settleTimeoutMs??3e4,readiness:t.readiness}}}),this.#m={THREE_BLOCKS_SHADER_TOOL:b.env.THREE_BLOCKS_SHADER_TOOL,THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER:b.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER},b.env.THREE_BLOCKS_SHADER_TOOL="1",b.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER="1";try{let o=await Oe(this.#e.root);this.#o=await o({root:this.#e.root,logLevel:"error",plugins:[this.#u.plugin,Ae(this.#t,this.#n,e!=="precompiled")],server:{host:"127.0.0.1",port:0}}),await this.#o.listen();let s=this.#o.httpServer?.address();if(!s||typeof s=="string")throw new Error("Vite did not expose an ephemeral TCP address.");this.#a=`http://127.0.0.1:${s.port}`,await this.#p(t);}catch(o){throw await this.close(),o}}async capture(e,t){let n=Date.now();if(await this.#w("capture",t),!this.#r||!this.#a)throw new Error("Shader browser driver did not start.");let a$2=this.#r,o=await a$2.newContext({viewport:t.viewport});this.#e.url!==void 0&&await H(o,this.#t,this.#n,"capture",t);let s=await o.newPage(),i=$(s);this.#n.clear(e.key);let l=this.#t.wait(e.key,t.timeoutMs),m=Promise.race([l,i.first.then(h=>Promise.reject(h))]),p=a(()=>{},"resolveDisconnected"),w=new Promise(h=>{p=h;}),u=a(()=>p(new Error("Shader capture browser disconnected before posting a manifest.")),"onDisconnected");a$2.on("disconnected",u);try{let h=s.goto(ne(this.#a,e,{threeBlocksShaderCapture:"1",capture:"1",captureId:e.key,captureFrames:String(Math.max(4,t.settleFrames)),settleFrames:String(t.settleFrames)}),{waitUntil:"domcontentloaded",timeout:t.timeoutMs}),c=await je(h,Promise.race([m,w.then(y=>Promise.reject(y))]));S(this.#i());let f=[...i.page,...i.console];if(f.length>0)throw new Error(`Capture browser errors:
76
- - ${f.join(`
77
- - `)}`);return a$1(c)?{...c,timing:{...a$1(c.timing)?c.timing:{},launch:n,...this.#n.firstRequest(e.key)===void 0?{}:{firstRequest:this.#n.firstRequest(e.key)},posted:Date.now()}}:c}catch(h){let c=h instanceof Error?h:new Error(String(h));this.#t.cancel(e.key,c),await l.catch(()=>{});let f=this.#n.read(e.key);if(c.message.includes("timed out")){let y=await oe(()=>s.evaluate(()=>{let g=globalThis,S=g.__threeBlocksShaderTools,B=S&&typeof S=="object"?S:void 0,ye=g.document,v=Reflect.get(g,Symbol.for("three-blocks.shader-capture.cache-value.v1")),x=g.location,Se=x!==null&&typeof x=="object"&&typeof Reflect.get(x,"href")=="string"?String(Reflect.get(x,"href")):"http://three-blocks.invalid/",be=new URL(Se).searchParams.get("captureId")??"default",J=v!==null&&typeof v=="object"&&typeof Reflect.get(v,"registrations")=="function"?Reflect.apply(Reflect.get(v,"registrations"),v,[be]):void 0;return {documentReadyState:ye?.readyState??null,parityTargetFrame:Number(g.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(g.__threeBlocksParityCompletedFrame??0),readiness:B?.readiness??null,captureCache:v!==null&&typeof v=="object"?{activeScene:Reflect.get(v,"activeScene")??null,registrations:Array.isArray(J)?J.slice(0,16).map(R=>R!==null&&typeof R=="object"?{key:Reflect.get(R,"key")??null,kind:Reflect.get(R,"kind")??null}:null):null}:null,threeRuntimeResources:performance.getEntriesByType("resource").map(R=>R.name).filter(R=>R.includes("three.webgpu"))}}));throw new Error(`${c.message} Last capture state for "${e.key}": ${JSON.stringify({page:y,telemetry:f??null,transform:this.#i()})}`)}throw c}finally{a$2.off("disconnected",u),await P(()=>o.close()),this.#c++,(!a$2.isConnected()||this.#c>=(t.browserRelaunchScenes??8))&&(this.#r===a$2&&(this.#r=void 0),await P(()=>a$2.close()),this.#c=0);}}async observe(e,t,n,a){for(let o=0;o<2;o++)try{return await this.#g(e,t,n,a)}catch(s){if(o===0&&de(s))continue;throw s}throw new Error(`Shader observation retry was exhausted for scene "${e.key}".`)}async#g(e,t,n,a){if(await this.#w(t,n),!this.#r||!this.#a)throw new Error("Shader browser driver did not start.");let o=await this.#r.newContext({viewport:n.viewport});this.#e.url!==void 0&&await H(o,this.#t,this.#n,t,n);let s=await o.newPage(),i=$(s);this.#n.clear(e.key);try{await s.goto(ne(this.#a,e,{threeBlocksShaderCapture:"1",threeBlocksShaderMode:t,captureId:e.key,...t==="live"?{precompiled:"0"}:{}}),{waitUntil:"domcontentloaded",timeout:n.timeoutMs}),await Promise.race([s.waitForFunction(n.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:n.timeoutMs}),i.first.then(u=>Promise.reject(u))]),L(await A(s,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#i()),await se(s,n,i);let l=e.parityFrames??n.parity.frames,m=await F(s,n,l,a),p=Buffer.from(await s.screenshot({type:"png"}));e.parityFrames!==void 0&&l<n.parity.frames&&await F(s,n,n.parity.frames-l);let w=L(await A(s,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#i());return this.#f===void 0&&(this.#f=await s.evaluate(async()=>{let u=Reflect.get(navigator,"gpu"),h=typeof u=="object"&&u!==null?Reflect.get(u,"requestAdapter"):void 0,c=typeof h=="function"?await Reflect.apply(h,u,[]):void 0,f=typeof c=="object"&&c!==null?Reflect.get(c,"info"):void 0,y=["description","device","architecture","vendor"].flatMap(g=>{let S=typeof f=="object"&&f!==null?Reflect.get(f,g):void 0;return typeof S=="string"&&S.length>0?[S]:[]});return {adapter:[...new Set(y)].join(" \xB7 ")||"WebGPU adapter",platform:navigator.platform||navigator.userAgent}})),{scene:e.key,mode:t,...w,frame:m,screenshot:p,errors:[...i.page,...i.console]}}catch(l){let m=l instanceof Error?l:new Error(String(l));if(/(?:timed?\s*out|timeout)/iu.test(m.message)){let p=this.#n.read(e.key),w=await oe(()=>s.evaluate(()=>{let u=globalThis,h=u.__threeBlocksShaderTools,c=h&&typeof h=="object"?h:void 0;return {documentReadyState:u.document?.readyState??null,parityTargetFrame:Number(u.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(u.__threeBlocksParityCompletedFrame??0),readiness:c?.readiness??null,threeRuntimeResources:performance.getEntriesByType("resource").map(y=>y.name).filter(y=>y.includes("three.webgpu"))}}));throw new Error(`${m.message} Last ${t} state for "${e.key}": ${JSON.stringify({page:w,telemetry:p??null})}`)}throw m}finally{await o.close();}}async observePublished(e,t){for(let n=0;n<2;n++)try{return await this.#y(e,t)}catch(a){if(n===0&&de(a))continue;throw a}throw new Error(`Published shader observation retry was exhausted for scene "${e.key}".`)}async#y(e,t){if(await this.#w("precompiled",t),!this.#r||!this.#a)throw new Error("Shader browser driver did not start.");let n=await this.#r.newContext({viewport:t.viewport});this.#e.url!==void 0&&await H(n,this.#t,this.#n,"precompiled",t);let a=await n.newPage(),o=$(a);this.#n.clear(e.key);try{await a.goto(Fe(this.#a,e),{waitUntil:"domcontentloaded",timeout:t.timeoutMs}),await Promise.race([a.waitForFunction(t.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:t.timeoutMs}),o.first.then(p=>Promise.reject(p))]),await se(a,t,o),L(await A(a,t.bridge.legacyLab),e,t.bridge.legacyLab,this.#i()),await F(a,t,2);let s=await ie(a),i=await F(a,t,120),l=await ie(a),m=L(await A(a,t.bridge.legacyLab),e,t.bridge.legacyLab,this.#i());return {scene:e.key,mode:"precompiled",...m,frame:i,beforeScreenshot:s,screenshot:l,errors:[...o.page,...o.console]}}finally{await n.close();}}timingEnvironment(){return this.#f??{adapter:"WebGPU adapter",platform:`${b.platform}/${b.arch}`}}async close(){this.#t.rejectAll(new Error("Shader browser driver closed.")),this.#r&&await P(()=>this.#r?.close()??Promise.resolve());let e=this.#o?.httpServer,t=e?Reflect.get(e,"closeAllConnections"):void 0;if(e&&typeof t=="function"&&Reflect.apply(t,e,[]),this.#o&&await P(()=>this.#o?.close()??Promise.resolve()),this.#s){let n=this.#s;n.closeAllConnections(),await P(()=>new Promise(a=>{n.close(()=>a());}));}if(this.#r=void 0,this.#o=void 0,this.#s=void 0,this.#a=void 0,this.#u=void 0,this.#h=void 0,this.#d=void 0,this.#f=void 0,this.#c=0,this.#l!==void 0&&(await rm(this.#l,{recursive:true,force:true}),this.#l=void 0),this.#m){for(let[n,a]of Object.entries(this.#m))a===void 0?delete b.env[n]:b.env[n]=a;this.#m=void 0;}}};function ct(r){return new _(r)}a(ct,"createPlaywrightShaderDriver");function lt(r){return new _(r)}a(lt,"createStaticPlaywrightShaderDriver");function ut(r){return new _(r)}a(ut,"createAttachedPlaywrightShaderDriver");
78
- export{ve as a,We as b,Z as c,ee as d,je as e,Le as f,Ve as g,de as h,ct as i,lt as j,ut as k};
@@ -1 +0,0 @@
1
- export{g as canReuseShaderBrowserSession,k as createAttachedPlaywrightShaderDriver,i as createPlaywrightShaderDriver,j as createStaticPlaywrightShaderDriver,h as isRetryableShaderObservationNavigation,f as settleShaderParityFrames,e as waitForShaderCaptureAcrossNavigation}from'./chunk-VGJ3V4QQ.js';import'./chunk-SCJNCGMF.js';import'./chunk-EI7MMDWY.js';
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export{k as canReuseShaderBrowserSession,o as createAttachedPlaywrightShaderDriver,m as createPlaywrightShaderDriver,n as createStaticPlaywrightShaderDriver,l as isRetryableShaderObservationNavigation,j as settleShaderParityFrames,i as waitForShaderCaptureAcrossNavigation}from'./chunk-INDAJN42.js';import'./chunk-NE7SC2BX.js';import'./chunk-ZT6T2W4B.js';import'./chunk-HRYYNBVC.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import'./chunk-HOZDD6PW.js';
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export{e as captureShaders,d as inspectShaderMatrix,f as testShaders}from'./chunk-ME3X2KFY.js';import'./chunk-INDAJN42.js';import'./chunk-NE7SC2BX.js';import'./chunk-ZT6T2W4B.js';import'./chunk-HRYYNBVC.js';import'./chunk-ZDNZCQUQ.js';import'./chunk-5L2VS3BN.js';import'./chunk-HOZDD6PW.js';