@three-blocks/devtools 2.0.0-alpha.238.g8723f0a28ca3 → 3.0.0-alpha.282.g3f938d990c02
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -37
- package/dist/{browser-smoke-EIKJ6OVK.js → browser-smoke-JHZLPGEB.js} +1 -1
- package/dist/{chunk-GA7PGW2R.js → chunk-3CKEE22B.js} +1 -1
- package/dist/{chunk-OQLHTDDH.js → chunk-AIAYEDXX.js} +1 -1
- package/dist/{chunk-4YRR36JN.js → chunk-FKZT7XLM.js} +18 -18
- package/dist/{chunk-TUIINI6U.js → chunk-L2CZ7RSV.js} +1 -1
- package/dist/{chunk-LUULHXFK.js → chunk-NQIAU3XU.js} +6 -6
- package/dist/chunk-QJFPNM6W.js +2 -0
- package/dist/chunk-YHHGR2AJ.js +80 -0
- package/dist/cli.js +8 -8
- package/dist/{environment-bake-XMRKQJXM.js → environment-bake-BGMGFAVK.js} +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +5 -5
- package/dist/{shader-browser-EYE3UT2U.js → shader-browser-523TEBVA.js} +1 -1
- package/dist/{shader-browser-WF4HNSAV.js → shader-browser-YPBP3WQY.js} +1 -1
- package/dist/shader-capture-server.d.ts +1 -1
- package/dist/shader-capture-server.js +5 -5
- package/dist/{shader-watch-ISNWIAXN.js → shader-watch-XY6A2KGQ.js} +1 -1
- package/dist/shader-workflow-T7W7UHWJ.js +2 -0
- package/dist/{status-D2RF6QTL.js → status-RFA7WAM6.js} +1 -1
- package/dist/transform.js +1 -1
- package/dist/webpack-loader.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-V34C7NIM.js +0 -80
- package/dist/chunk-W6UL2OW7.js +0 -2
- package/dist/shader-workflow-T72N2CLS.js +0 -2
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {c,b as b$1,d}from'./chunk-
|
|
2
|
+
import {c,b as b$1,d,a as a$4}from'./chunk-QJFPNM6W.js';import {a as a$3}from'./chunk-ZT6T2W4B.js';import {e as e$1,g}from'./chunk-NPLE7PPF.js';import {a as a$2,c as c$2}from'./chunk-65VEJRRT.js';import {a as a$1,c as c$1,d as d$1,f,e,i,j,k}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import D from'process';import {createServer}from'http';import {createRequire}from'module';import {mkdtemp,rm,lstat,readFile,unlink,mkdir,readdir,realpath}from'fs/promises';import b from'path';import {tmpdir}from'os';import {pathToFileURL}from'url';import {THREE_WEBGL_R185_COMPATIBILITY,THREE_WEBGPU_R185_COMPATIBILITY,THREE_R186DEV_VERSION,THREE_WEBGPU_R186DEV_COMPATIBILITY,parsePrecompiledManifest,SHADER_HYDRATION_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_ADDRESS_SCHEMA_VERSION,PRECOMPILED_MANIFEST_VERSION}from'three-blocks/shaders';import {transformThreeWebgpuProviderHooks,transformThreeWebgpuCaptureInstrumentation}from'three-blocks/vite';function x(r,e="webgpu"){if(/^0\.185\./u.test(r))return e==="webgl"?THREE_WEBGL_R185_COMPATIBILITY:THREE_WEBGPU_R185_COMPATIBILITY;if(r===THREE_R186DEV_VERSION&&e==="webgpu")return THREE_WEBGPU_R186DEV_COMPATIBILITY;throw new Error(`Three.js ${r} is outside the supported shader compatibility contracts.`)}a(x,"shaderCompatibilityForThree");var N=62,ze="timing.local.json",Ye="timing.json",Se="parity.json",ne=4096,_r=4096;function ye(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(ye,"boundedString");function R(r,e,t=true){if(typeof r!="number"||!Number.isFinite(r)||r<0||t&&!Number.isSafeInteger(r))throw new Error(`${e} must be a non-negative ${t?"integer":"finite number"}.`);return r}a(R,"nonNegativeNumber");function Mr(r){if(!a$2(r))throw new Error("Shader capture stats are missing.");let e={buildCalls:R(r.buildCalls,"capture stats.buildCalls"),renderBuilds:R(r.renderBuilds,"capture stats.renderBuilds"),computeBuilds:R(r.computeBuilds,"capture stats.computeBuilds"),registeredBuilds:R(r.registeredBuilds,"capture stats.registeredBuilds"),registeredRenderBuilds:R(r.registeredRenderBuilds,"capture stats.registeredRenderBuilds"),registeredComputeBuilds:R(r.registeredComputeBuilds,"capture stats.registeredComputeBuilds"),buildMs:R(r.buildMs,"capture stats.buildMs",false),syncBuildMs:R(r.syncBuildMs,"capture stats.syncBuildMs",false),asyncBuildElapsedMs:R(r.asyncBuildElapsedMs,"capture stats.asyncBuildElapsedMs",false),precompiledSetupMs:R(r.precompiledSetupMs,"capture stats.precompiledSetupMs",false),maxSyncBuildMs:R(r.maxSyncBuildMs??r.syncBuildMs,"capture stats.maxSyncBuildMs",false),maxPrecompiledSetupMs:R(r.maxPrecompiledSetupMs??r.precompiledSetupMs,"capture stats.maxPrecompiledSetupMs",false),hydrationMs:R(r.hydrationMs??0,"capture stats.hydrationMs",false),maxHydrationMs:R(r.maxHydrationMs??r.hydrationMs??0,"capture stats.maxHydrationMs",false),injected:R(r.injected,"capture stats.injected"),injectedRender:R(r.injectedRender,"capture stats.injectedRender"),injectedCompute:R(r.injectedCompute,"capture stats.injectedCompute"),missed:R(r.missed,"capture stats.missed"),missedRender:R(r.missedRender,"capture stats.missedRender"),missedCompute:R(r.missedCompute,"capture stats.missedCompute"),...Array.isArray(r.missedKeys)&&r.missedKeys.every(t=>typeof t=="string")?{missedKeys:r.missedKeys.slice(0,ne)}:{}};if(e.renderBuilds+e.computeBuilds!==e.buildCalls||e.registeredRenderBuilds+e.registeredComputeBuilds!==e.registeredBuilds||e.injectedRender+e.injectedCompute!==e.injected||e.missedRender+e.missedCompute!==e.missed||e.registeredBuilds>e.buildCalls||Math.abs(e.syncBuildMs+e.asyncBuildElapsedMs-e.buildMs)>.001||e.maxSyncBuildMs>e.syncBuildMs+.001||e.maxPrecompiledSetupMs>e.precompiledSetupMs+.001||e.maxHydrationMs>e.hydrationMs+.001)throw new Error("Shader capture stats totals are inconsistent.");return e}a(Mr,"captureStats");function xr(r){if(!Array.isArray(r)||r.length>ne)throw new Error("Shader capture skipped builds are invalid.");return r.map((e,t)=>{if(!a$2(e)||e.kind!=="render"&&e.kind!=="compute")throw new Error(`Shader capture skipped build ${t} is invalid.`);return {kind:e.kind,name:ye(e.name,`skipped build ${t} name`,512),reason:ye(e.reason,`skipped build ${t} reason`)}})}a(xr,"skippedBuilds");function Ar(r){let e=0,t=0,n=0,i=0;for(let s of Object.values(r.entries)){let a=r.states[s];a!==void 0&&((a.vertex!==null||a.fragment!==null)&&e++,a.vertex!==null&&t++,a.fragment!==null&&n++,a.compute!==null&&i++);}return {render:e,vertex:t,fragment:n,compute:i}}a(Ar,"shaderCoverage");function Rt(r,e){if(!a$2(r))throw new Error("Shader capture payload must be an object.");if(r.scene!==e.scene)throw new Error(`Shader capture scene does not match "${e.scene}".`);if(r.protocolVersion!==2)throw new Error("Shader capture protocolVersion must be 2.");let t=e.backend??"webgpu",n=x(e.runtime.three,t);if(r.compatibility!==n)throw new Error(`Shader capture compatibility must be "${n}".`);if(!a$2(r.entries))throw new Error("Shader capture entries must be an object.");if(typeof r.requiresSetup!="boolean")throw new Error("Shader capture requiresSetup must be boolean.");let i=Object.keys(r.entries).length;if(i>ne)throw new Error(`Shader capture must contain at most ${ne} entries.`);if(!Array.isArray(r.errors)||r.errors.length>_r)throw new Error("Shader capture errors are invalid.");let s=r.errors.map((S,l)=>ye(S,`capture error ${l}`,64*1024));if(s.length>0)throw new Error(`Shader capture failed:
|
|
3
3
|
- ${s.join(`
|
|
4
|
-
- `)}`);let a=xr(r.skipped);if(i===0&&(t!=="webgl"||a.length===0))throw new Error("Shader capture must contain an entry unless WebGL explicitly skipped every live build.");let o=Mr(r.stats),c=a$2(r.timing)?r.timing:void 0,m=c===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(S=>{let l=c[S];if(l===void 0)return [];if(typeof l!="number"||!Number.isFinite(l)||l<0)throw new Error(`Shader capture timing.${S} is invalid.`);return [[S,l]]})),p;if(r.provenance!==void 0){if(!a$2(r.provenance)||typeof r.provenance.userAgent!="string"||r.provenance.userAgent.length>1024||typeof r.provenance.adapter!="string"||r.provenance.adapter.length>1024||!Array.isArray(r.provenance.features)||r.provenance.features.length>256||!r.provenance.features.every(S=>typeof S=="string"&&S.length<=128))throw new Error("Shader capture provenance is invalid.");p={userAgent:r.provenance.userAgent,adapter:r.provenance.adapter,features:[...new Set(r.provenance.features)].sort()};}let y=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:e.scene,three:e.runtime.three,threeBlocks:e.runtime.threeBlocks,runtime:{id:n,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...r.automatic===void 0?{}:{automatic:r.automatic},requiresSetup:r.requiresSetup,modules:r.modules,nodes:r.nodes,layouts:r.layouts,attributePlans:r.attributePlans,updatePlans:r.updatePlans,requirementPlans:r.requirementPlans,states:r.states,entries:r.entries,...r.fallbacks===void 0?{}:{fallbacks:r.fallbacks}}),h=Ar(y);if(o.registeredRenderBuilds<h.render||o.registeredComputeBuilds<h.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:e.scene,backend:t,manifest:y,skipped:a,stats:o,coverage:h,...m===void 0?{}:{timing:m},...p===void 0?{}:{provenance:p}}}a(
|
|
4
|
+
- `)}`);let a=xr(r.skipped);if(i===0&&(t!=="webgl"||a.length===0))throw new Error("Shader capture must contain an entry unless WebGL explicitly skipped every live build.");let o=Mr(r.stats),c=a$2(r.timing)?r.timing:void 0,m=c===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(S=>{let l=c[S];if(l===void 0)return [];if(typeof l!="number"||!Number.isFinite(l)||l<0)throw new Error(`Shader capture timing.${S} is invalid.`);return [[S,l]]})),p;if(r.provenance!==void 0){if(!a$2(r.provenance)||typeof r.provenance.userAgent!="string"||r.provenance.userAgent.length>1024||typeof r.provenance.adapter!="string"||r.provenance.adapter.length>1024||!Array.isArray(r.provenance.features)||r.provenance.features.length>256||!r.provenance.features.every(S=>typeof S=="string"&&S.length<=128))throw new Error("Shader capture provenance is invalid.");p={userAgent:r.provenance.userAgent,adapter:r.provenance.adapter,features:[...new Set(r.provenance.features)].sort()};}let y=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:e.scene,three:e.runtime.three,threeBlocks:e.runtime.threeBlocks,runtime:{id:n,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...r.automatic===void 0?{}:{automatic:r.automatic},requiresSetup:r.requiresSetup,modules:r.modules,nodes:r.nodes,layouts:r.layouts,attributePlans:r.attributePlans,updatePlans:r.updatePlans,requirementPlans:r.requirementPlans,states:r.states,entries:r.entries,...r.fallbacks===void 0?{}:{fallbacks:r.fallbacks}}),h=Ar(y);if(o.registeredRenderBuilds<h.render||o.registeredComputeBuilds<h.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:e.scene,backend:t,manifest:y,skipped:a,stats:o,coverage:h,...m===void 0?{}:{timing:m},...p===void 0?{}:{provenance:p}}}a(Rt,"validateShaderCapture");function O(r,e=0){let t=" ".repeat(e),n=" ".repeat(e+1);if(Array.isArray(r))return r.length===0?"[]":r.every(s=>s===null||["number","string","boolean"].includes(typeof s))?JSON.stringify(r):`[
|
|
5
5
|
${r.map(s=>`${n}${O(s,e+1)}`).join(`,
|
|
6
6
|
`)}
|
|
7
7
|
${t}]`;if(r!==null&&typeof r=="object"){let s=r,a=Object.keys(s).sort();return a.length===0?"{}":`{
|
|
8
8
|
${a.map(o=>{let c=s[o];return `${n}${JSON.stringify(o)}: ${O(c,e+1)}`}).join(`,
|
|
9
9
|
`)}
|
|
10
10
|
${t}}`}let i=JSON.stringify(r);if(i===void 0)throw new Error("Shader artifact contains a non-serializable value.");return i}a(O,"stableStringify");function jr(r){return ["// GENERATED FILE \u2014 do not edit by hand.","// Produced by @three-blocks/devtools.","import type { PrecompiledManifest } from 'three-blocks/shaders';","",`export default ${O(r)} satisfies PrecompiledManifest;`,""].join(`
|
|
11
|
-
`)}a(jr,"serializeShaderManifest");function
|
|
12
|
-
`),t===void 0)return {local:m};let p=
|
|
13
|
-
`),{local:m,committed:p}}a(
|
|
14
|
-
`),y}a(
|
|
15
|
-
`);}a(
|
|
16
|
-
`;await f(b.join(s,k),A),c.push(b.relative(i$1,b.join(s,k)).split(b.sep).join("/"));let B=w.skipped.filter(P=>P.kind==="render").length,_=w.skipped.length-B;o[f$1]={backend:g$1,artifact:v,artifactHash:c$1(E),asset:k,assetHash:c$1(A),inputs:Object.fromEntries(Object.entries(u).sort(([P],[
|
|
17
|
-
`),c.push("meta.json"),{directory:e$2,receipt:p,files:c}}a(
|
|
18
|
-
`):null:null},transform(i,s){if(!$r(s))return null;t.seen=true,t.id=s;try{let a=
|
|
11
|
+
`)}a(jr,"serializeShaderManifest");function He(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(He,"timingLabel");function ge(r){if(!a$2(r)||r.schemaVersion!==3||r.source!=="latest-local-capture"&&r.source!=="committed-capture"||typeof r.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(r.receiptHash)||typeof r.measuredAt!="string"||!Number.isFinite(Date.parse(r.measuredAt))||!a$2(r.scenes))throw new Error("Shader timing is invalid.");let e={};for(let[n,i]of Object.entries(r.scenes)){if(n.length===0||n.length>128||!a$2(i))throw new Error("Shader timing scene is invalid.");let s={builds:R(i.builds,`timing ${n}.builds`),setupMeasured:i.setupMeasured===true,liveBuildMs:R(i.liveBuildMs,`timing ${n}.liveBuildMs`,false),precompiledBuildMs:R(i.precompiledBuildMs,`timing ${n}.precompiledBuildMs`,false),avoidedBuildMs:R(i.avoidedBuildMs,`timing ${n}.avoidedBuildMs`,false),runs:R(i.runs,`timing ${n}.runs`),spreadMs:R(i.spreadMs,`timing ${n}.spreadMs`,false)};if(s.runs<1)throw new Error(`Shader timing runs are invalid for scene "${n}".`);if(Math.abs(s.avoidedBuildMs-Math.max(0,s.liveBuildMs-s.precompiledBuildMs))>.001)throw new Error(`Shader timing delta is inconsistent for scene "${n}".`);e[n]=s;}if(Object.keys(e).length===0)throw new Error("Shader timing contains no scenes.");let t={schemaVersion:3,receiptHash:r.receiptHash,measuredAt:r.measuredAt,scenes:e};return r.source==="latest-local-capture"?{...t,source:"latest-local-capture"}:{...t,source:"committed-capture",adapter:He(r.adapter,"Shader timing adapter"),platform:He(r.platform,"Shader timing platform")}}a(ge,"parseShaderTiming");function ie(r){return /^[a-z0-9][a-z0-9_-]{0,63}(?:\.webgl)?$/u.test(r)}a(ie,"validParityScene");function Ue(r){return typeof r=="string"&&Number.isFinite(Date.parse(r))}a(Ue,"validParityTimestamp");function be(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)||!Ue(r.verifiedAt)||!Array.isArray(r.scenes)||r.scenes.length===0||r.scenes.length>64||!r.scenes.every(n=>typeof n=="string"&&ie(n)))throw new Error("Shader parity evidence is invalid.");return {schemaVersion:1,receiptHash:r.receiptHash,verifiedAt:r.verifiedAt,scenes:[...new Set(r.scenes)].sort()}}if(r.schemaVersion!==2||!a$2(r.scenes))throw new Error("Shader parity evidence is invalid.");let e=Object.entries(r.scenes);if(e.length===0||e.length>64)throw new Error("Shader parity evidence is invalid.");let t={};for(let[n,i]of e.sort(([s],[a])=>s.localeCompare(a))){if(!ie(n)||!a$2(i)||typeof i.fingerprint!="string"||!/^[a-f0-9]{64}$/u.test(i.fingerprint)||!Ue(i.verifiedAt))throw new Error("Shader parity evidence is invalid.");t[n]={fingerprint:i.fingerprint,verifiedAt:i.verifiedAt};}return {schemaVersion:2,scenes:t}}a(be,"parseShaderParityEvidence");function we(r,e){let t=r.scenes[e];if(t===void 0)throw new Error(`Shader receipt has no scene "${e}" for parity evidence.`);return c$1(O({runtime:{three:r.runtime.three,threeBlocks:r.runtime.threeBlocks,threeBlocksShaderClosure:r.runtime.threeBlocksShaderClosure},...r.tool===void 0?{}:{tool:r.tool},scene:t}))}a(we,"shaderSceneParityFingerprint");async function Ve(r,e,t,n){let i=b.join(r,t);try{if(!await d$1(i))return;let s=await lstat(i);if(s.isSymbolicLink()||!s.isFile()||s.size>1024*1024)return;let a=ge(JSON.parse(await readFile(i,"utf8")));return a.source===n&&a.receiptHash===c$1(e)?a:void 0}catch{return}}a(Ve,"readShaderTimingFile");async function vt(r,e){return await Ve(r,e,ze,"latest-local-capture")??await Ve(r,e,Ye,"committed-capture")}a(vt,"readShaderTiming");async function Qe(r,e){let t=b.join(r,Se);try{if(!await d$1(t))return;let n=await lstat(t);if(n.isSymbolicLink()||!n.isFile()||n.size>1024*1024)return;let i=be(JSON.parse(await readFile(t,"utf8"))),s=c$2(JSON.parse(Buffer.from(e).toString("utf8"))),a={};if(i.schemaVersion===1){if(i.receiptHash!==c$1(e))return;for(let o of i.scenes)s.scenes[o]!==void 0&&(a[o]={fingerprint:we(s,o),verifiedAt:i.verifiedAt});}else for(let[o,c]of Object.entries(i.scenes))s.scenes[o]===void 0||c.fingerprint!==we(s,o)||(a[o]=c);return Object.keys(a).length===0?void 0:{schemaVersion:2,scenes:a}}catch{return}}a(Qe,"readShaderParityEvidence");async function Xe(r,e,t){let n=await ae(r),i=b.join(n,"meta.json"),s=await lstat(i);if(s.isSymbolicLink()||!s.isFile())throw new Error("Shader receipt must be a regular file before timing.");let a=await readFile(i),o=new Date().toISOString(),c=Object.fromEntries(Object.entries(e).sort(([y],[h])=>y.localeCompare(h))),m=ge({schemaVersion:3,receiptHash:c$1(a),measuredAt:o,source:"latest-local-capture",scenes:c});if(await f(b.join(n,ze),`${O(m)}
|
|
12
|
+
`),t===void 0)return {local:m};let p=ge({schemaVersion:3,receiptHash:c$1(a),measuredAt:o,source:"committed-capture",adapter:t.adapter,platform:t.platform,scenes:c});return await f(b.join(n,Ye),`${O(p)}
|
|
13
|
+
`),{local:m,committed:p}}a(Xe,"writeShaderTimings");async function Tt(r,e){return (await Xe(r,e)).local}a(Tt,"writeShaderLocalTiming");async function Pt(r,e,t){if(e.length===0||e.length>64||e.some(h=>!ie(h)))throw new Error("Shader parity evidence must contain 1...64 valid scene keys.");let n=await ae(r),i=b.join(n,"meta.json"),s=await lstat(i);if(s.isSymbolicLink()||!s.isFile())throw new Error("Shader receipt must be a regular file before parity evidence.");let a=await readFile(i);if(t!==void 0&&c$1(a)!==c$1(t))throw new Error("Shader receipt changed during browser parity verification; completed observations were not attached to the new receipt.");let o=c$2(JSON.parse(a.toString("utf8"))),c=await Qe(n,a),m=new Date().toISOString(),p={...c?.scenes};for(let h of [...new Set(e)].sort())p[h]={fingerprint:we(o,h),verifiedAt:m};let y=be({schemaVersion:2,scenes:p});return await f(b.join(n,Se),`${O(y)}
|
|
14
|
+
`),y}a(Pt,"writeShaderParityEvidence");async function kt(r,e,t){if(e.length===0||e.length>64||e.some(p=>!ie(p)))throw new Error("Shader parity invalidation must contain 1...64 valid scene keys.");let n=await ae(r),i=await readFile(b.join(n,"meta.json"));if(c$1(i)!==c$1(t))throw new Error("Shader receipt changed before prior parity evidence could be invalidated.");let s=await Qe(n,i);if(s===void 0)return;let a=new Set(e),o=Object.fromEntries(Object.entries(s.scenes).filter(([p])=>!a.has(p))),c=b.join(n,Se);if(Object.keys(o).length===0){await unlink(c).catch(p=>{if(!a$2(p)||p.code!=="ENOENT")throw p});return}let m=be({schemaVersion:2,scenes:o});await f(c,`${O(m)}
|
|
15
|
+
`);}a(kt,"removeShaderParityEvidence");async function Ct(r,e,t){let n=await Xe(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(Ct,"writeShaderTimingTwins");async function Ge(r){if(!await d$1(r)){await mkdir(r);return}let e=await lstat(r);if(e.isSymbolicLink()||!e.isDirectory())throw new Error(`Shader artifact path is not a real directory: ${r}.`)}a(Ge,"assertDirectory");async function ae(r){let e=b.resolve(r),t=b.join(e,".three-blocks");await Ge(t);let n=b.join(t,"shaders");return await Ge(n),n}a(ae,"artifactRoot");async function Bt(r){let e$2=await ae(r.root),t=r.backends??["webgpu"],n=Object.fromEntries(t.map(l=>[l,x(r.runtime.three,l)])),i$1=b.resolve(r.root),s=b.resolve(i$1,r.publicDirectory??"public");if(!e(i$1,s)||s===i$1)throw new Error("Shader public directory must stay inside the project root.");let a=b.join(s,"three-blocks","shaders");await mkdir(a,{recursive:true}),await i(i$1,a,"Shader static-asset directory");let o={},c=[];for(let l of [...r.scenes].sort((u,g)=>u.key.localeCompare(g.key))){let u=r.inputs.get(l.key);if(u===void 0)throw new Error(`Shader input matrix is missing scene "${l.key}".`);for(let g$1 of e$1(l,t)){let f$1=g(l.key,g$1),w=r.captures.get(f$1);if(w===void 0){let P=r.previousReceipt?.scenes[f$1];if(P===void 0)continue;let q=await readFile(b.join(e$2,P.artifact));if(c$1(q)!==P.artifactHash)throw new Error(`Preserved shader artifact checksum differs for "${f$1}".`);if(P.asset!==void 0&&P.assetHash!==void 0){let J=await readFile(b.join(s,P.asset));if(c$1(J)!==P.assetHash)throw new Error(`Preserved static shader manifest checksum differs for "${f$1}".`)}o[f$1]={...P,backend:g$1,inputs:Object.fromEntries(Object.entries(u).sort(([J],[j])=>J.localeCompare(j)))},c.push(P.artifact),P.asset!==void 0&&c.push(b.relative(i$1,b.join(s,P.asset)).split(b.sep).join("/"));continue}if(w.scene!==l.key||w.backend!==g$1||w.manifest.scene!==l.key)throw new Error(`Capture matrix scene/backend "${f$1}" is inconsistent.`);let v=`${l.key}.${g$1}.ts`,E=jr(w.manifest);await f(b.join(e$2,v),E),c.push(v);let k=`three-blocks/shaders/${l.key}.${g$1}.json`,A=`${O(w.manifest)}
|
|
16
|
+
`;await f(b.join(s,k),A),c.push(b.relative(i$1,b.join(s,k)).split(b.sep).join("/"));let B=w.skipped.filter(P=>P.kind==="render").length,_=w.skipped.length-B;o[f$1]={backend:g$1,artifact:v,artifactHash:c$1(E),asset:k,assetHash:c$1(A),inputs:Object.fromEntries(Object.entries(u).sort(([P],[q])=>P.localeCompare(q))),coverage:w.coverage,bytes:Buffer.byteLength(E),skipped:{render:B,compute:_}};}}let m=[...r.captures.values()].find(l=>l.provenance!==void 0)?.provenance??r.previousReceipt?.runtime.capture,p={schemaVersion:2,runtime:{...r.runtime,...m===void 0?{}:{capture:m}},tool:{name:"@three-blocks/devtools",version:a$3,compatibility:n[t[0]??"webgpu"],compatibilities:n,transform:N,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},scenes:o},y=new Set(c);for(let l of await readdir(e$2,{withFileTypes:true}))if(!(!/\.(?:webgpu|webgl)\.ts$/u.test(l.name)||y.has(l.name))){if(l.isSymbolicLink()||!l.isFile())throw new Error(`Orphan shader artifact is not a regular file: ${l.name}.`);await unlink(b.join(e$2,l.name));}let h=new Set(r.scenes.flatMap(l=>e$1(l,t).map(u=>`${l.key}.${u}.json`))),S=new Set(Object.values(r.previousReceipt?.scenes??{}).map(l=>l.asset===void 0?void 0:b.posix.basename(l.asset)).filter(l=>l!==void 0));try{let l=c$2(JSON.parse(await readFile(b.join(e$2,"meta.json"),"utf8")));for(let u of Object.values(l.scenes))u.asset!==void 0&&S.add(b.posix.basename(u.asset));}catch{}for(let l of await readdir(a,{withFileTypes:true}))if(!(!l.name.endsWith(".json")||h.has(l.name))&&S.has(l.name)){if(l.isSymbolicLink()||!l.isFile())throw new Error(`Orphan shader static asset is not a regular file: ${l.name}.`);await unlink(b.join(a,l.name));}return await f(b.join(e$2,"meta.json"),`${O(p)}
|
|
17
|
+
`),c.push("meta.json"),{directory:e$2,receipt:p,files:c}}a(Bt,"writeShaderArtifacts");var Ee="three-blocks.shader-capture.runtime.v1";var Q;async function W(){Q===void 0&&(Q=(async()=>{let e=createRequire(b.join(process.cwd(),"package.json")).resolve("@three-blocks/devtools/browser/shader-capture"),t=b.resolve(b.dirname(e),"../..");return (await j(t,e,a$1.metadata,"Shader capture browser runtime")).data.toString("utf8")})());let r=Q;try{return await r}catch(e){throw Q===r&&(Q=void 0),e}}a(W,"loadShaderCaptureRuntimeSource");var Ze="virtual:three-blocks-shader-capture-client",er="\0three-blocks:shader-capture-client",ve="virtual:three-blocks-shader-capture-runtime",rr="\0three-blocks:shader-capture-runtime";async function nr(){let r=await W(),e=r.replace(/\bexport\{[^{}]*\};?\s*$/u,"");if(e===r)throw new Error("Shader capture browser runtime no longer has the expected final ESM export list.");return e}a(nr,"loadShaderCaptureRuntimeScriptSource");function $r(r){let e=r.split("?",1)[0];return e===void 0?false:e.split(b.sep).join("/").endsWith("/build/three.webgpu.js")}a($r,"isThreeWebGPUModule");function ir(r){let e=/^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/u.exec(r);return e?.[1]==="0"&&e[2]==="185"}a(ir,"supportedVersion");function Fr(r,e,t={}){if(!ir(e))throw new Error(`Shader provider transform ${THREE_WEBGPU_R185_COMPATIBILITY} supports Three.js 0.185.x; received "${e}".`);let n=transformThreeWebgpuProviderHooks(r,{threeVersion:e,...t.threeRevision===void 0?{}:{threeRevision:t.threeRevision},id:"three/build/three.webgpu.js"}),i=n.state==="already-applied",s=n.code;return t.instrumentCapture&&(s=transformThreeWebgpuCaptureInstrumentation(s,{...t.captureRuntimeImport===void 0?{}:{runtimeImport:t.captureRuntimeImport},...t.forceWebGL===true?{forceWebGL:true}:{}}).code),{code:s,alreadyPresent:i,captureApplied:t.instrumentCapture===true}}a(Fr,"applyShaderProviderTransform");var Nr=/this\.trackTimestamp\s*=\s*\(\s*parameters\.trackTimestamp\s*===\s*true\s*\);/gu,Hr="Object.defineProperty( this, 'trackTimestamp', { get: () => false, set: () => {} } );";function ar(r,e={}){if(!ir(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===Ze?er:e.capture&&i===ve?rr:null},async load(i){return e.capture?i===rr?W():i===er?[`export * from '${ve}';`,`import { configureThreeBlocksShaderCapture } from '${ve}';`,`configureThreeBlocksShaderCapture( ${JSON.stringify({capture:e.capture.capture,backend:e.capture.forceWebGL===true?"webgl":"webgpu",forceLive:e.capture.forceLive,driven:e.capture.driven,settleFrames:e.capture.settleFrames,settleTimeoutMs:e.capture.settleTimeoutMs,visibilityGuard:e.capture.visibilityGuard,captureId:e.capture.captureId,sessionKey:e.capture.sessionKey,token:e.capture.token,readiness:e.capture.readiness??{},transform:N})} );`].join(`
|
|
18
|
+
`):null:null},transform(i,s){if(!$r(s))return null;t.seen=true,t.id=s;try{let a=Fr(i,r,{instrumentCapture:e.capture!==void 0,forceWebGL:e.capture?.forceWebGL===!0,...e.capture!==void 0?{captureRuntimeImport:Ze}:{}}),o=e.disableTimestampQueries===!0?a.code.replace(Nr,Hr):a.code;if(e.disableTimestampQueries===!0&&o===a.code)throw new Error("Three.js timestamp tracking anchor drifted; refusing software WebGPU capture.");return t.applied=!0,t.alreadyPresent=a.alreadyPresent,t.captureApplied=a.captureApplied,o===i?null:{code:o,map:null}}catch(a){throw t.error=a instanceof Error?a.message:String(a),a}}},status:t}}a(ar,"createShaderProviderTransform");function Te(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(Te,"assertShaderProviderTransform");var ur="/__three-blocks/shaders/capture",ce="/__three-blocks/shaders/telemetry",mr="/__three-blocks/shaders/runtime.js",pr="/__three-blocks/shaders/bootstrap.js",hr="/__three-blocks/shaders/bridge.js",fr=a$1.manifest*2,Ce=/^[a-z0-9][a-z0-9_-]{0,63}$/u,yr=64,gr=2e3;async function zr(){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(zr,"loadChromium");async function Yr(r){let e;try{e=createRequire(b.join(r,"package.json")).resolve("vite");}catch(n){throw new Error("Shader capture requires Vite in the target project.",{cause:n})}let t=await import(pathToFileURL(e).href);if(typeof t.createServer!="function")throw new Error(`The target project's Vite entry does not export createServer(): ${e}`);return t.createServer}a(Yr,"loadProjectCreateServer");var Be=class{static{a(this,"CaptureInbox");}#e=new Map;#r=new Map;wait(e,t){let n=this.#r.get(e);if(n!==void 0)return this.#r.delete(e),Promise.resolve(n);if(this.#e.has(e))throw new Error(`A shader capture is already waiting for scene "${e}".`);return new Promise((i,s)=>{let a=setTimeout(()=>{this.#e.delete(e),s(new Error(`Shader capture "${e}" timed out after ${t}ms.`));},t);this.#e.set(e,{resolve:i,reject:s,timer:a});})}receive(e){if(!a$2(e)||typeof e.scene!="string"||!Ce.test(e.scene))throw new Error("Capture POST has no safe scene key.");if(!this.#r.has(e.scene)&&!this.#e.has(e.scene)&&this.#r.size>=yr)throw new Error("Capture POST exceeds the scene inbox limit.");let t=this.#e.get(e.scene);t?(clearTimeout(t.timer),this.#e.delete(e.scene),t.resolve(e)):this.#r.set(e.scene,e);}cancel(e,t){let n=this.#e.get(e);n&&(clearTimeout(n.timer),this.#e.delete(e),n.reject(t));}rejectAll(e){for(let t of this.#e.values())clearTimeout(t.timer),t.reject(e);this.#e.clear(),this.#r.clear();}};async function Qr(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(Qr,"waitForShaderCaptureAcrossNavigation");var _e=class{static{a(this,"TelemetryHub");}#e=new Map;#r=new Map;markFirstRequest(e){Ce.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"||!Ce.test(e.scene))throw new Error("Shader telemetry has no bounded scene key.");if(!this.#e.has(e.scene)&&this.#e.size>=yr)throw new Error("Shader telemetry exceeds the scene limit.");this.#e.set(e.scene,e);}read(e){return this.#e.get(e)}clear(e){this.#e.delete(e),this.#r.delete(e);}},Xr=a(async(r,e,t,n,i)=>{let s=0;for(;r.__threeBlocksParityUsesAnimationLoop!==true&&s<e;)await n(),s+=1;if(r.__threeBlocksParityUsesAnimationLoop===true){let a=Number(r.__threeBlocksParityCompletedFrame||0),o=Number(t),c=Number.isSafeInteger(o)&&o>=a?o:a+e;for(r.__threeBlocksParityTargetFrame=c;Number(r.__threeBlocksParityCompletedFrame||0)<c;)await n();}return await i(),Number(r.__threeBlocksParityCompletedFrame||0)},"settleShaderParityFrames");function Me(r,e){return `(() => {
|
|
19
19
|
const root = globalThis;
|
|
20
20
|
const scene = new URL(location.href).searchParams.get('captureId')
|
|
21
21
|
|| 'default';
|
|
@@ -49,7 +49,7 @@ ${t}}`}let i=JSON.stringify(r);if(i===void 0)throw new Error("Shader artifact co
|
|
|
49
49
|
};
|
|
50
50
|
const readiness = { workerReady: false, assetsReady: false, textReady: false, compileEnd: false, firstFrame: false };
|
|
51
51
|
const stats = { buildCalls: 0, renderBuilds: 0, computeBuilds: 0, registeredBuilds: 0, registeredRenderBuilds: 0, registeredComputeBuilds: 0, buildMs: 0, syncBuildMs: 0, asyncBuildElapsedMs: 0, precompiledSetupMs: 0, maxSyncBuildMs: 0, maxPrecompiledSetupMs: 0, hydrationMs: 0, maxHydrationMs: 0, injected: 0, injectedRender: 0, injectedCompute: 0, missed: 0, missedRender: 0, missedCompute: 0, missedKeys: [] };
|
|
52
|
-
const settleParityFrames = ${
|
|
52
|
+
const settleParityFrames = ${Xr.toString()};
|
|
53
53
|
const settle = (frames, requestedTarget) => settleParityFrames(
|
|
54
54
|
root,
|
|
55
55
|
frames,
|
|
@@ -57,7 +57,7 @@ ${t}}`}let i=JSON.stringify(r);if(i===void 0)throw new Error("Shader artifact co
|
|
|
57
57
|
() => new Promise((resolve) => requestAnimationFrame(resolve)),
|
|
58
58
|
() => new Promise((resolve) => setTimeout(resolve, 100)),
|
|
59
59
|
);
|
|
60
|
-
const bridge = { protocolVersion: 1, compatibility: ${JSON.stringify(r)}, transform: ${
|
|
60
|
+
const bridge = { protocolVersion: 1, compatibility: ${JSON.stringify(r)}, transform: ${N}, readiness, stats, settle };
|
|
61
61
|
root.__threeBlocksShaderTools = bridge;
|
|
62
62
|
requestAnimationFrame(() => requestAnimationFrame(() => { readiness.firstFrame = true; }));
|
|
63
63
|
const poll = async () => {
|
|
@@ -83,15 +83,15 @@ ${t}}`}let i=JSON.stringify(r);if(i===void 0)throw new Error("Shader artifact co
|
|
|
83
83
|
setTimeout(poll, 40);
|
|
84
84
|
};
|
|
85
85
|
void poll();
|
|
86
|
-
})();`}a(
|
|
87
|
-
const runtime = globalThis[Symbol.for(${JSON.stringify(
|
|
86
|
+
})();`}a(Me,"publicBridgeScript");function wr(r,e,t,n,i=false){let s=new URL(r.url??"/","http://three-blocks.invalid"),a=s.pathname;if(i&&r.method==="GET"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.(?:webgpu|webgl)\.json$/u.test(a))return e.statusCode=204,e.end(),true;if(a===ce&&r.method==="GET"){let h=s.searchParams.get("scene")??"",S=n.read(h);return S===void 0?(e.statusCode=204,e.end()):(e.statusCode=200,e.setHeader("Content-Type","application/json"),e.end(JSON.stringify(S))),true}let o=a===ur,c=a===ce;if(!o&&!c)return false;if(r.method!=="POST")return e.statusCode=405,e.end("POST required"),true;let m=[],p=0,y=false;return r.on("data",h=>{p+=h.byteLength,p>fr?y=true:m.push(h);}),r.on("end",()=>{if(y){e.statusCode=413,e.end("capture payload too large");return}try{let h=JSON.parse(Buffer.concat(m).toString("utf8"));c?n.receive(h):t.receive(h),e.statusCode=204,e.end();}catch(h){e.statusCode=400,e.end(h instanceof Error?h.message:String(h));}}),true}a(wr,"handleCaptureEndpoint");function Zr(r,e,t,n,i){return {name:"three-blocks:shader-capture-endpoint",transformIndexHtml(){return [{tag:"script",children:Me(n,i),injectTo:"head-prepend"}]},configureServer(s){s.middlewares.use((a,o,c)=>{let p=new URL(a.url??"/","http://three-blocks.invalid").searchParams.get("captureId");p!==null&&e.markFirstRequest(p),!wr(a,o,r,e,t)&&c();});}}}a(Zr,"captureEndpointPlugin");function or(r,e,t){let n=new URL(e.url,r);for(let[i,s]of Object.entries(t))n.searchParams.set(i,s);return n.href}a(or,"browserUrl");function et(r,e,t){let n=new URL(e.url,r);for(let i of ["capture","precompiled"])n.searchParams.delete(i);return n.searchParams.set("captureId",e.key),n.searchParams.set("threeBlocksShaderCapture","1"),n.searchParams.set("threeBlocksShaderMode","precompiled"),t==="webgl"&&n.searchParams.set("webgl","1"),n.searchParams.set("tbStats","1"),n.href}a(et,"publishedBrowserUrl");async function H(r){let e;try{await Promise.race([r(),new Promise(t=>{e=setTimeout(t,gr);})]);}catch{}finally{e&&clearTimeout(e);}}a(H,"closeBrowserResource");async function de(r){let e;try{return await Promise.race([r().catch(()=>null),new Promise(t=>{e=setTimeout(()=>t(null),gr);})])}finally{e!==void 0&&clearTimeout(e);}}a(de,"readPageDiagnostic");function Pe(r){let e=a(()=>{},"resolveFirst"),t=new Promise(a=>{e=a;}),n={console:[],page:[],first:t},i=false,s=a(a=>{i||(i=true,e(new Error(a)));},"report");return r.on("console",a=>{let o=a.type()==="warning"&&/\[three-blocks\/shaders\].*(?:has no entry|manifest miss|hydration)/iu.test(a.text());if(a.type()!=="error"&&!o||a$4(a.text()))return;let c=a.location().url,m=c.length>0?`${a.text()} (${c})`:a.text();n.console.push(m),s(`Browser console ${o?"warning":"error"}: ${m}`);}),r.on("pageerror",a=>{if(a$4(a.message))return;let o=a.stack||a.message;n.page.push(o),s(`Browser page error: ${o}`);}),r.on("crash",()=>s("Browser page crashed before shader capture completed.")),r.on("close",()=>s("Browser page closed before shader capture completed.")),n}a(Pe,"collectErrors");function X(r,e,t=false){return typeof r[e]=="boolean"?r[e]:t}a(X,"booleanField");function rt(r){if(!a$2(r))throw new Error("Browser shader stats are unavailable.");let e=a((t,n=true)=>{let i=r[t];if(typeof i!="number"||!Number.isFinite(i)||i<0||n&&!Number.isSafeInteger(i))throw new Error(`Browser shader stats.${t} is invalid.`);return i},"read");return {buildCalls:e("buildCalls"),renderBuilds:e("renderBuilds"),computeBuilds:e("computeBuilds"),registeredBuilds:e("registeredBuilds"),registeredRenderBuilds:e("registeredRenderBuilds"),registeredComputeBuilds:e("registeredComputeBuilds"),buildMs:e("buildMs",false),syncBuildMs:e("syncBuildMs",false),asyncBuildElapsedMs:e("asyncBuildElapsedMs",false),precompiledSetupMs:e("precompiledSetupMs",false),maxSyncBuildMs:e("maxSyncBuildMs",false),maxPrecompiledSetupMs:e("maxPrecompiledSetupMs",false),hydrationMs:e("hydrationMs",false),maxHydrationMs:e("maxHydrationMs",false),injected:e("injected"),injectedRender:e("injectedRender"),injectedCompute:e("injectedCompute"),missed:e("missed"),missedRender:e("missedRender"),missedCompute:e("missedCompute"),...Array.isArray(r.missedKeys)&&r.missedKeys.every(t=>typeof t=="string")?{missedKeys:r.missedKeys}:{}}}a(rt,"parseStats");function se(r,e,t,n,i){if(!a$2(r))throw new Error("The page did not expose the public shader devtools bridge.");if(!t&&r.protocolVersion!==1)throw new Error(`Scene "${e.key}" exposed an unsupported shader bridge protocol.`);let s=r.readiness;if(!a$2(s))throw new Error("The shader bridge readiness snapshot is invalid.");let a={workerReady:X(s,"workerReady"),assetsReady:X(s,"assetsReady"),textReady:e.requiresText?X(s,"textReady"):true,compileEnd:X(s,"compileEnd"),firstFrame:X(s,"firstFrame",t)};if(!a.workerReady||!a.assetsReady||!a.textReady||!a.compileEnd)throw new Error(`Scene "${e.key}" did not reach worker/assets/text/compile readiness.`);let o=t?i:r.compatibility,c=t?N:r.transform;if(o!==i||c!==N)throw new Error(`Scene "${e.key}" exposed incompatible shader bridge metadata.`);Te(n);let m=Array.isArray(r.demands)?r.demands.filter(a$2).slice(0,64):void 0;return {compatibility:i,transform:c,readiness:a,stats:rt(r.stats),...m===void 0?{}:{demands:m}}}a(se,"parseBridge");async function oe(r,e){return r.evaluate(t=>{let n=globalThis;if(!t)return n.__threeBlocksShaderTools??null;let i=n.__threeBlocks,s=n.__threeBlocksTslStats;if(!i||typeof i!="object")return null;let a=i;return {readiness:{workerReady:a.workerReady===true,assetsReady:a.loadEnd===true||a.assetsReady===true,textReady:a.textReady===true,compileEnd:a.compileEnd===true,firstFrame:true},stats:s}},e)}a(oe,"readBridge");async function Sr(r,e){let t=await de(()=>r.evaluate(n=>{let i=globalThis,s=a(o=>{let c=i;for(let m of o.split(".")){if(c===null||typeof c!="object"&&typeof c!="function")return;c=Reflect.get(c,m);}return c},"resolveGlobal"),a$1=null;if(n!==null)try{a$1=JSON.stringify(s(`${n}Diagnostics`))??null;}catch{a$1=null;}return JSON.stringify({parityCompletedFrame:Number(i.__threeBlocksParityCompletedFrame??0),diagnostics:a$1})},e??null));return t===null?{alive:false,signature:""}:{alive:true,signature:t}}a(Sr,"probePageProgress");async function Z(r,e,t,n){let i=r.evaluate(async m=>{let y=globalThis.__threeBlocksShaderTools;if(y&&typeof y=="object"){let l=Reflect.get(y,"settle");if(typeof l=="function"){let u=await l(m.frames,m.targetFrame);return typeof u=="number"&&Number.isSafeInteger(u)?u:0}}if(!m.legacy||!m.modulePath)throw new Error("The public shader bridge does not provide deterministic settle().");let h=await import(m.modulePath);if(!h.store||typeof h.store!="object")throw new Error("Legacy deterministic store is unavailable.");let S=h.store;return S.recordFrameCount=0,S.recordFrameRate=60,S.recordTotalFrames=m.frames,S.recording=true,await new Promise((l,u)=>{let g=Date.now(),f=a(()=>{if(S.recording===false)return l();if(Date.now()-g>m.timeoutMs)return u(new Error("Legacy deterministic settle timed out."));setTimeout(f,25);},"poll");f();}),0},{frames:t,targetFrame:n,legacy:e.bridge.legacyLab,modulePath:e.bridge.deterministicModule??null,timeoutMs:e.timeoutMs}),s=V(e),a$1=false,o,c=(async()=>{let m=Date.now(),p=m,y="";for(;;){let h=s-(Date.now()-m);if(h<=0)throw new Error(`Shader parity settle timed out after ${s}ms.`);let S=e.timeoutMs-(Date.now()-p);if(S<=0){let l=await Sr(r,e.readiness.global);if(a$1)throw new Error("Shader parity settle already resolved.");if(l.alive&&l.signature===y)throw new Error(`Shader parity settle timed out after ${e.timeoutMs}ms without progress (hard cap ${s}ms).`);y=l.signature,p=Date.now();continue}if(await new Promise(l=>{o=setTimeout(l,Math.min(S,h,2500));}),a$1)throw new Error("Shader parity settle already resolved.")}})();try{return await Promise.race([i,c])}finally{a$1=true,o!==void 0&&clearTimeout(o),c.catch(()=>{});}}a(Z,"settlePage");async function dr(r,e,t){e.readiness.selector===void 0&&e.readiness.global===void 0||await Promise.race([r.waitForFunction(n=>{let i=globalThis;if(n.selector!==void 0&&i.document?.querySelector(n.selector)==null)return false;if(n.global===void 0)return true;let s=i;for(let c of n.global.split(".")){if((typeof s!="object"||s===null)&&typeof s!="function")return false;s=Reflect.get(s,c);}if(s===true)return true;if(typeof s!="object"||s===null||typeof Reflect.get(s,"then")!="function")return false;let a=i.__threeBlocksReadinessState,o=a instanceof Map?a:new Map;return a instanceof Map||(i.__threeBlocksReadinessState=o),o.has(s)||(o.set(s,false),Promise.resolve(s).then(()=>o.set(s,true),()=>o.set(s,false))),o.get(s)===true},e.readiness,{timeout:V(e)}),t.first.then(n=>Promise.reject(n))]);}a(dr,"waitForConfiguredReadiness");async function cr(r){let e=r.locator("canvas"),n=(await e.evaluateAll(i=>i.map((s,a)=>{let o=s.getBoundingClientRect();return {index:a,area:Math.max(0,o.width)*Math.max(0,o.height)}}))).sort((i,s)=>s.area-i.area)[0];if(n===void 0||n.area<=0)throw new Error("Published page has no visible renderer canvas.");return Buffer.from(await e.nth(n.index).screenshot({type:"png"}))}a(cr,"primaryCanvasScreenshot");async function ke(r,e,t,n,i,s,a){let o=le(n,i,s),c=await nr(),m=`(() => {
|
|
87
|
+
const runtime = globalThis[Symbol.for(${JSON.stringify(Ee)})];
|
|
88
88
|
if (!runtime || typeof runtime.configureThreeBlocksShaderCapture !== 'function') {
|
|
89
89
|
throw new Error('@three-blocks/devtools attached shader capture runtime is incompatible.');
|
|
90
90
|
}
|
|
91
91
|
runtime.configureThreeBlocksShaderCapture(${JSON.stringify(o).replaceAll("<","\\u003c")});
|
|
92
92
|
})();`;await r.addInitScript({content:`${c}
|
|
93
|
-
${m}`}),await r.addInitScript({content:
|
|
94
|
-
`)}a(
|
|
93
|
+
${m}`}),await r.addInitScript({content:Me(a,o)}),await r.route("**/*",async p=>{let y=p.request(),h=new URL(y.url()),S=h.pathname;if(y.method()==="GET"&&n!=="precompiled"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.(?:webgpu|webgl)\.json$/u.test(S)){await p.fulfill({status:204});return}if(S===ce&&y.method()==="GET"){let g=t.read(h.searchParams.get("scene")??"");await p.fulfill(g===void 0?{status:204}:{status:200,contentType:"application/json",body:JSON.stringify(g)});return}let l=S===ur,u=S===ce;if((l||u)&&y.method()==="POST"){let g=y.postDataBuffer()??Buffer.alloc(0);if(g.byteLength>fr){await p.fulfill({status:413,body:"capture payload too large"});return}try{let f=JSON.parse(g.toString("utf8"));u?t.receive(f):e.receive(f),await p.fulfill({status:204});}catch(f){await p.fulfill({status:400,body:f instanceof Error?f.message:String(f)});}return}await p.continue();});}a(ke,"configureAttachedContext");var tt=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 nt(r){let e=[`<script src="${hr}"></script>`,`<script type="module" src="${pr}"></script>`].join(""),t=/<head(?:\s[^>]*)?>/iu.exec(r);return t===null?`${e}${r}`:`${r.slice(0,t.index+t[0].length)}${e}${r.slice(t.index+t[0].length)}`}a(nt,"injectStaticShaderCaptureHtml");function it(r,e,t){let n=le(r,e,t);return [`import { configureThreeBlocksShaderCapture } from ${JSON.stringify(mr)};`,`configureThreeBlocksShaderCapture( ${JSON.stringify(n).replaceAll("<","\\u003c")} );`].join(`
|
|
94
|
+
`)}a(it,"staticCaptureBootstrap");var at=5e3;function V(r){return Math.max(r.maxTimeoutMs??r.timeoutMs,r.timeoutMs)}a(V,"configuredHardCapMs");function le(r,e,t){return {capture:r==="capture",backend:t,driven:true,forceLive:r!=="precompiled",settleFrames:e.settleFrames,settleTimeoutMs:e.settleTimeoutMs??3e4,...r==="capture"?{deadlineAt:Date.now()+Math.max(1e3,V(e)-at)}:{},readiness:e.readiness,transform:N}}a(le,"shaderCaptureConfiguration");async function st(r,e){let t=await k(r,e,a=>/\.(?:c|m)?js$/u.test(a),16384),n=false,i=false,s;for(let a of t){let o=(await j(r,a,a$1.texture,"Static application JavaScript")).data.toString("utf8");if(o.includes("nodeBuilderStateProvider")&&(n=true),o.includes("three-blocks.shader-capture.runtime.v1")&&(i=true,s??=a),n&&i)break}if(!n||!i)throw new Error("The static build does not contain the Three.js shader capture transform. Run `shaders capture` without an explicit driver or URL to preview adapter wiring and build automatically, or add the manual adapter from the package README and rebuild.");return {seen:true,applied:true,alreadyPresent:false,captureApplied:true,...s===void 0?{}:{id:s}}}a(st,"inspectStaticCaptureTransform");async function ot(r,e$1){let t;try{t=decodeURIComponent(e$1);}catch{return}if(t.includes("\0"))return;let n=t.replace(/^\/+/u,""),i=b.resolve(r,n.length===0?"index.html":n);if(!e(r,i)||i===r||(await d$1(i)&&(await lstat(i)).isDirectory()&&(i=b.join(i,"index.html")),!await d$1(i)&&b.extname(i).length===0&&(i=b.join(r,"index.html")),!await d$1(i)))return;let s=await j(r,i,a$1.texture,"Static application asset");return {data:s.data,file:s.path}}a(ot,"staticRequestFile");async function dt(r,e$1,t,n,i,s){let a=await realpath(r.root),o=await realpath(b.resolve(a,r.serve));if(!e(a,o)||o===a)throw new Error("--serve must name a built application directory inside the project root.");let c=await st(a,o),m=await W(),p=it(e$1,n,t),y=Me(x(r.runtime.three,t),le(e$1,n,t)),h=createServer((l,u)=>{(async()=>{if(wr(l,u,i,s,e$1!=="precompiled"))return;let g=new URL(l.url??"/","http://three-blocks.invalid");if(l.method!=="GET"&&l.method!=="HEAD"){u.statusCode=405,u.end("GET or HEAD required");return}let f=g.pathname===mr?m:g.pathname===pr?p:g.pathname===hr?y:void 0;if(f!==void 0){u.statusCode=200,u.setHeader("Content-Type","text/javascript; charset=utf-8"),u.setHeader("Cache-Control","no-store"),u.end(l.method==="HEAD"?void 0:f);return}let w=await ot(o,g.pathname);if(w===void 0){u.statusCode=404,u.end("Not found");return}let v=b.extname(w.file).toLowerCase(),E=v===".html"?Buffer.from(nt(w.data.toString("utf8"))):w.data;u.statusCode=200,u.setHeader("Content-Type",tt[v]??"application/octet-stream"),u.setHeader("Content-Length",String(E.byteLength)),u.setHeader("Cache-Control","no-store"),u.end(l.method==="HEAD"?void 0:E);})().catch(g=>{if(u.headersSent)return u.destroy(g instanceof Error?g:void 0);u.statusCode=500,u.end(g instanceof Error?g.message:String(g));});});await new Promise((l,u)=>{h.once("error",u),h.listen(0,"127.0.0.1",()=>{h.off("error",u),l();});});let S=h.address();if(!S||typeof S=="string")throw new Error("Static capture server did not expose an ephemeral TCP address.");return {server:h,baseUrl:`http://127.0.0.1:${S.port}`,transform:c}}a(dt,"startStaticShaderServer");function ct(r,e,t){return r===e?true:t&&r!==void 0&&r!=="capture"&&e!=="capture"}a(ct,"canReuseShaderBrowserSession");function lr(r){let e=r instanceof Error?r.message:String(r);return e.includes("Execution context was destroyed")&&e.includes("navigation")||/^launch: Timeout \d+ms exceeded\./u.test(e)}a(lr,"isRetryableShaderObservationNavigation");var ee=class{static{a(this,"PlaywrightShaderDriver");}#e;#r=new Be;#n=new _e;#m;#p;#s;#o;#t;#i;#h;#c;#f;#y;#l=0;#u;constructor(e){this.#e=e;}#d(){return this.#m?.status??this.#p??{seen:false,applied:false,alreadyPresent:false}}async#g(e,t){if(this.#t?.isConnected()===true)return;this.#t=void 0;let n=await zr();this.#u??=await mkdtemp(b.join(tmpdir(),"three-blocks-shader-cache-")),this.#t=await n.launch({headless:t==="webgl"?this.#e.headed!==true:d(this.#e.headed===true),args:[...t==="webgl"?c():b$1(),`--disk-cache-dir=${this.#u}`],timeout:e.timeoutMs}),this.#l=0;}async#a(e,t,n){let i;try{return await Promise.race([n(),new Promise((s,a)=>{i=setTimeout(()=>a(new Error(`launch: Timeout ${t.timeoutMs}ms exceeded.`)),t.timeoutMs);})])}catch(s){throw this.#t===e&&(this.#t=void 0),await H(()=>e.close()),s}finally{i!==void 0&&clearTimeout(i);}}async#w(e,t,n){let i=this.#s!==void 0||this.#o!==void 0||this.#e.url!==void 0&&this.#i!==void 0,s=this.#f===t&&(this.#o!==void 0?this.#c===e:ct(this.#c,e,n.bridge.legacyLab));if(i&&s){this.#c=e,await this.#g(n,t);return}if(i&&await this.close(),this.#c=e,this.#f=t,this.#e.url!==void 0){let a=new URL(this.#e.url);if(!["http:","https:"].includes(a.protocol)||a.username||a.password||a.hash)throw new Error("Attached shader URL must be an HTTP(S) URL without credentials or a fragment.");this.#i=a.href,this.#p={seen:true,applied:true,alreadyPresent:false,captureApplied:true,id:"attached-application"},await this.#g(n,t);return}if(this.#e.serve!==void 0)try{let a=await dt({root:this.#e.root,runtime:this.#e.runtime,serve:this.#e.serve,...this.#e.headed===void 0?{}:{headed:this.#e.headed}},e,t,n,this.#r,this.#n);this.#o=a.server,this.#p=a.transform,this.#i=a.baseUrl,await this.#g(n,t);return}catch(a){throw await this.close(),a}this.#m=ar(this.#e.runtime.three,{disableTimestampQueries:D.env.THREE_BLOCKS_SOFTWARE_WEBGPU==="1",...n.bridge.legacyLab?{}:{capture:{capture:e==="capture",driven:true,forceLive:e!=="precompiled",forceWebGL:t==="webgl",settleFrames:n.settleFrames,settleTimeoutMs:n.settleTimeoutMs??3e4,readiness:n.readiness}}}),this.#h={THREE_BLOCKS_SHADER_TOOL:D.env.THREE_BLOCKS_SHADER_TOOL,THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER:D.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER},D.env.THREE_BLOCKS_SHADER_TOOL="1",D.env.THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER="1";try{let a=await Yr(this.#e.root);this.#s=await a({root:this.#e.root,logLevel:"error",plugins:[this.#m.plugin,Zr(this.#r,this.#n,e!=="precompiled",x(this.#e.runtime.three,t),le(e,n,t))],server:{host:"127.0.0.1",port:0}}),await this.#s.listen();let o=this.#s.httpServer?.address();if(!o||typeof o=="string")throw new Error("Vite did not expose an ephemeral TCP address.");this.#i=`http://127.0.0.1:${o.port}`,await this.#g(n,t);}catch(a){throw await this.close(),a}}async capture(e,t,n="webgpu"){let i=Date.now();if(await this.#w("capture",n,t),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let s=this.#t,a$1=await this.#a(s,t,()=>s.newContext({viewport:t.viewport}));this.#e.url!==void 0&&await this.#a(s,t,()=>ke(a$1,this.#r,this.#n,"capture",t,n,x(this.#e.runtime.three,n)));let o=await this.#a(s,t,()=>a$1.newPage()),c=Pe(o);this.#n.clear(e.key);let m=V(t),p=this.#r.wait(e.key,m),y=false;m>t.timeoutMs?(async()=>{let f=Math.min(5e3,Math.max(1e3,Math.round(t.timeoutMs/8))),w=Date.now(),v="",E="";for(;!y;){if(await new Promise(_=>setTimeout(_,f)),y)return;let k=this.#n.read(e.key),A=k===void 0?"":JSON.stringify(k);if(A!==v){v=A,w=Date.now();continue}if(Date.now()-w<t.timeoutMs)continue;let B=await Sr(o,t.readiness.global);if(y)return;if(!B.alive||B.signature!==E){E=B.signature,w=Date.now();continue}this.#r.cancel(e.key,new Error(`Shader capture "${e.key}" timed out after ${t.timeoutMs}ms without progress (hard cap ${m}ms).`));return}})().catch(()=>{}):void 0;let S=Promise.race([p,c.first.then(f=>Promise.reject(f))]),l=a(()=>{},"resolveDisconnected"),u=new Promise(f=>{l=f;}),g=a(()=>l(new Error("Shader capture browser disconnected before posting a manifest.")),"onDisconnected");s.on("disconnected",g);try{let f=o.goto(or(this.#i,e,{threeBlocksShaderCapture:"1",capture:"1",captureId:e.key,captureFrames:String(Math.max(4,t.settleFrames)),settleFrames:String(t.settleFrames),...n==="webgl"?{webgl:"1"}:{}}),{waitUntil:"domcontentloaded",timeout:t.timeoutMs}),w=await Qr(f,Promise.race([S,u.then(E=>Promise.reject(E))]));Te(this.#d());let v=[...c.page,...c.console];if(v.length>0)throw new Error(`Capture browser errors:
|
|
95
95
|
- ${v.join(`
|
|
96
|
-
- `)}`);return a$2(w)?{...w,timing:{...a$2(w.timing)?w.timing:{},launch:i,...this.#n.firstRequest(e.key)===void 0?{}:{firstRequest:this.#n.firstRequest(e.key)},posted:Date.now()}}:w}catch(f){let w=f instanceof Error?f:new Error(String(f));this.#r.cancel(e.key,w),await p.catch(()=>{});let v=this.#n.read(e.key);if(w.message.includes("timed out")){let E=await de(()=>o.evaluate(B=>{let _=globalThis,P=_.__threeBlocksShaderTools,
|
|
97
|
-
${n} demands: ${l}`):y}finally{await H(()=>o.close());}}async observePublished(e,t,n="webgpu"){for(let i=0;i<2;i++)try{return await this.#b(e,n,t)}catch(s){if(i===0&&lr(s))continue;throw s}throw new Error(`Published shader observation retry was exhausted for scene "${e.key}".`)}async#b(e,t,n){if(await this.#w("precompiled",t,n),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let i=this.#t,s=await this.#a(i,n,()=>i.newContext({viewport:n.viewport}));this.#e.url!==void 0&&await this.#a(i,n,()=>
|
|
96
|
+
- `)}`);return a$2(w)?{...w,timing:{...a$2(w.timing)?w.timing:{},launch:i,...this.#n.firstRequest(e.key)===void 0?{}:{firstRequest:this.#n.firstRequest(e.key)},posted:Date.now()}}:w}catch(f){let w=f instanceof Error?f:new Error(String(f));this.#r.cancel(e.key,w),await p.catch(()=>{});let v=this.#n.read(e.key);if(w.message.includes("timed out")){let E=await de(()=>o.evaluate(B=>{let _=globalThis,P=_.__threeBlocksShaderTools,q=P&&typeof P=="object"?P:void 0,J=_.document,j=Reflect.get(_,Symbol.for("three-blocks.shader-capture.cache-value.v1")),re=_.location,br=re!==null&&typeof re=="object"&&typeof Reflect.get(re,"href")=="string"?String(Reflect.get(re,"href")):"http://three-blocks.invalid/",Er=new URL(br).searchParams.get("captureId")??"default",xe=j!==null&&typeof j=="object"&&typeof Reflect.get(j,"registrations")=="function"?Reflect.apply(Reflect.get(j,"registrations"),j,[Er]):void 0,Ae=a(C=>{let I=_;for(let Rr of C.split(".")){if(I===null||typeof I!="object"&&typeof I!="function")return;I=Reflect.get(I,Rr);}return I},"resolveGlobal"),je=null,ue=null;if(B!==null){let C=Ae(B);je=C===true||C===false?C:C===void 0?"absent":C!==null&&typeof C.then=="function"?"promise":typeof C;try{let I=JSON.stringify(Ae(`${B}Diagnostics`));ue=typeof I=="string"?I.slice(0,2048):null;}catch{ue=null;}}return {documentReadyState:J?.readyState??null,parityTargetFrame:Number(_.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(_.__threeBlocksParityCompletedFrame??0),readiness:q?.readiness??null,readinessGlobal:je,readinessDiagnostics:ue,captureCache:j!==null&&typeof j=="object"?{activeScene:Reflect.get(j,"activeScene")??null,registrations:Array.isArray(xe)?xe.slice(0,16).map(C=>C!==null&&typeof C=="object"?{key:Reflect.get(C,"key")??null,kind:Reflect.get(C,"kind")??null}:null):null}:null,threeRuntimeResources:performance.getEntriesByType("resource").map(C=>C.name).filter(C=>C.includes("three.webgpu"))}},t.readiness.global??null)),k=t.readiness.global!==void 0&&E!==null&&E.readinessGlobal!==true,A=E===null?"Capture page did not answer diagnostics before the deadline; its main thread was blocked or gone. ":k?`Application readiness "${t.readiness.global}" never completed (state: ${JSON.stringify(E.readinessGlobal)}${E.readinessDiagnostics===null?"":`, diagnostics: ${E.readinessDiagnostics}`}). `:"";throw new Error(`${A}${w.message} Last capture state for "${e.key}": ${JSON.stringify({page:E,telemetry:v??null,transform:this.#d()})}`)}throw w}finally{y=true,s.off("disconnected",g),await H(()=>a$1.close()),this.#l++,(!s.isConnected()||this.#l>=(t.browserRelaunchScenes??8))&&(this.#t===s&&(this.#t=void 0),await H(()=>s.close()),this.#l=0);}}async observe(e,t,n,i,s="webgpu"){for(let a=0;a<2;a++)try{return await this.#S(e,s,t,n,i)}catch(o){if(a===0&&lr(o))continue;throw o}throw new Error(`Shader observation retry was exhausted for scene "${e.key}".`)}async#S(e,t,n,i,s){if(await this.#w(n,t,i),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let a=this.#t,o=await this.#a(a,i,()=>a.newContext({viewport:i.viewport}));this.#e.url!==void 0&&await this.#a(a,i,()=>ke(o,this.#r,this.#n,n,i,t,x(this.#e.runtime.three,t)));let c=await this.#a(a,i,()=>o.newPage()),m=Pe(c);this.#n.clear(e.key);try{await c.goto(or(this.#i,e,{threeBlocksShaderCapture:"1",threeBlocksShaderMode:n,captureId:e.key,...n==="live"?{precompiled:"0"}:{},...t==="webgl"?{webgl:"1"}:{}}),{waitUntil:"domcontentloaded",timeout:i.timeoutMs}),await Promise.race([c.waitForFunction(i.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:V(i)}),m.first.then(u=>Promise.reject(u))]),se(await oe(c,i.bridge.legacyLab),e,i.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t)),await dr(c,i,m),await Promise.race([c.waitForFunction(i.bridge.legacyLab?"true":"globalThis.__threeBlocksShaderTools?.readiness?.firstFrame === true",void 0,{timeout:V(i)}),m.first.then(u=>Promise.reject(u))]),await Z(c,i,1);let p=Buffer.from(await c.screenshot({type:"png",timeout:i.timeoutMs})),y=e.parityFrames??i.parity.frames,h=await Z(c,i,y,s),S=Buffer.from(await c.screenshot({type:"png",timeout:i.timeoutMs}));e.parityFrames!==void 0&&y<i.parity.frames&&await Z(c,i,i.parity.frames-y);let l=se(await oe(c,i.bridge.legacyLab),e,i.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t));return this.#y===void 0&&(this.#y=await c.evaluate(async u=>{if(u==="webgl"){let B=Reflect.get(globalThis,"document").querySelector("canvas")?.getContext("webgl2"),_=B?.getExtension("WEBGL_debug_renderer_info");return {adapter:B&&_?String(B.getParameter(_.UNMASKED_RENDERER_WEBGL)):"WebGL adapter",platform:navigator.platform||navigator.userAgent}}let g=Reflect.get(navigator,"gpu"),f=typeof g=="object"&&g!==null?Reflect.get(g,"requestAdapter"):void 0,w=typeof f=="function"?await Reflect.apply(f,g,[]):void 0,v=typeof w=="object"&&w!==null?Reflect.get(w,"info"):void 0,E=["description","device","architecture","vendor"].flatMap(k=>{let A=typeof v=="object"&&v!==null?Reflect.get(v,k):void 0;return typeof A=="string"&&A.length>0?[A]:[]});return {adapter:[...new Set(E)].join(" \xB7 ")||"WebGPU adapter",platform:navigator.platform||navigator.userAgent}},t)),{scene:e.key,mode:n,...l,frame:h,firstFrameScreenshot:p,screenshot:S,errors:[...m.page,...m.console]}}catch(p){let y=p instanceof Error?p:new Error(String(p));if(/(?:timed?\s*out|timeout)/iu.test(y.message)){let u=this.#n.read(e.key),g=await de(()=>c.evaluate(()=>{let f=globalThis,w=f.__threeBlocksShaderTools,v=w&&typeof w=="object"?w:void 0;return {documentReadyState:f.document?.readyState??null,parityTargetFrame:Number(f.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(f.__threeBlocksParityCompletedFrame??0),readiness:v?.readiness??null,threeRuntimeResources:performance.getEntriesByType("resource").map(k=>k.name).filter(k=>k.includes("three.webgpu"))}}));throw new Error(`${y.message} Last ${n} state for "${e.key}": ${JSON.stringify({page:g,telemetry:u??null})}`)}let h=this.#n.read(e.key),l=(a$2(h)&&Array.isArray(h.demands)&&h.demands.length>0?JSON.stringify(h.demands).slice(0,6e3):void 0)??await de(()=>c.evaluate(u=>{let g=globalThis,f=Reflect.get(g,Symbol.for(u)),w=f!==null&&typeof f=="object"?Reflect.get(f,"readThreeBlocksShaderDemands"):void 0,v=typeof w=="function"?Reflect.apply(w,f,[]):void 0,E=g.__threeBlocksShaderTools,k=Array.isArray(v)&&v.length>0?v:E&&typeof E=="object"?Reflect.get(E,"demands"):void 0;return Array.isArray(k)&&k.length>0?JSON.stringify(k).slice(0,6e3):null},Ee));throw typeof l=="string"?new Error(`${y.message}
|
|
97
|
+
${n} demands: ${l}`):y}finally{await H(()=>o.close());}}async observePublished(e,t,n="webgpu"){for(let i=0;i<2;i++)try{return await this.#b(e,n,t)}catch(s){if(i===0&&lr(s))continue;throw s}throw new Error(`Published shader observation retry was exhausted for scene "${e.key}".`)}async#b(e,t,n){if(await this.#w("precompiled",t,n),!this.#t||!this.#i)throw new Error("Shader browser driver did not start.");let i=this.#t,s=await this.#a(i,n,()=>i.newContext({viewport:n.viewport}));this.#e.url!==void 0&&await this.#a(i,n,()=>ke(s,this.#r,this.#n,"precompiled",n,t,x(this.#e.runtime.three,t)));let a=await this.#a(i,n,()=>s.newPage()),o=Pe(a);this.#n.clear(e.key);try{await a.goto(et(this.#i,e,t),{waitUntil:"domcontentloaded",timeout:n.timeoutMs}),await Promise.race([a.waitForFunction(n.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:V(n)}),o.first.then(h=>Promise.reject(h))]),await dr(a,n,o),se(await oe(a,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t)),await Z(a,n,2);let c=await cr(a),m=await Z(a,n,120),p=await cr(a),y=se(await oe(a,n.bridge.legacyLab),e,n.bridge.legacyLab,this.#d(),x(this.#e.runtime.three,t));return {scene:e.key,mode:"precompiled",...y,frame:m,firstFrameScreenshot:c,beforeScreenshot:c,screenshot:p,errors:[...o.page,...o.console]}}finally{await H(()=>s.close());}}timingEnvironment(){return this.#y??{adapter:this.#f==="webgl"?"WebGL adapter":"WebGPU adapter",platform:`${D.platform}/${D.arch}`}}async close(){this.#r.rejectAll(new Error("Shader browser driver closed.")),this.#t&&await H(()=>this.#t?.close()??Promise.resolve());let e=this.#s?.httpServer,t=e?Reflect.get(e,"closeAllConnections"):void 0;if(e&&typeof t=="function"&&Reflect.apply(t,e,[]),this.#s&&await H(()=>this.#s?.close()??Promise.resolve()),this.#o){let n=this.#o;n.closeAllConnections(),await H(()=>new Promise(i=>{n.close(()=>i());}));}if(this.#t=void 0,this.#s=void 0,this.#o=void 0,this.#i=void 0,this.#m=void 0,this.#p=void 0,this.#c=void 0,this.#f=void 0,this.#y=void 0,this.#l=0,this.#u!==void 0&&(await rm(this.#u,{recursive:true,force:true}),this.#u=void 0),this.#h){for(let[n,i]of Object.entries(this.#h))i===void 0?delete D.env[n]:D.env[n]=i;this.#h=void 0;}}};function on(r){return new ee(r)}a(on,"createPlaywrightShaderDriver");function dn(r){return new ee(r)}a(dn,"createStaticPlaywrightShaderDriver");function cn(r){return new ee(r)}a(cn,"createAttachedPlaywrightShaderDriver");export{x as a,N as b,Rt as c,O as d,vt as e,Tt as f,Pt as g,kt as h,Ct as i,Bt as j,Qr as k,Xr as l,Me as m,ct as n,lr as o,on as p,dn as q,cn as r};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {d as d$2,b as b$2,c as c$3,g as g$2}from'./chunk-76WRV5MZ.js';import {g as g$1}from'./chunk-JHBQB7WC.js';import {a as a$3,c as c$2,b,d as d$1}from'./chunk-LUULHXFK.js';import {a as a$1,c,b as b$1}from'./chunk-65VEJRRT.js';import {j,d,i,a as a$2,c as c$1}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {realpath}from'fs/promises';import h from'path';var te=".three-blocks/runtime/status.json",re=256*1024,H="three-blocks browser smoke",se=["three-blocks.json","three-blocks.shaders.json","three-blocks.text.ts"];function Q(e){return "kind"in e&&e.kind==="adopted"}a(Q,"isAdoptedProjectStatus");async function O(e,t,r,s){let n=await j(e,t,r,s);return JSON.parse(n.data.toString("utf8"))}a(O,"readJsonWithin");var ne=["starting","worker ready","assets ready","compiled","first frame","updating","error"],ae=["ready","generating","fallback","missing","invalid"],oe=["WebGPU","WebGL"],ie=["OffscreenCanvas","MainThread"],de=/^[0-9A-Za-z][0-9A-Za-z._-]{0,63}$/,X=16,K=1e9;function g(e,t,r,s=[]){if(!a$1(e))throw new Error(`${t} must be an object.`);let n=new Set([...r,...s]);for(let o of r)if(!Object.hasOwn(e,o))throw new Error(`${t}.${o} is required.`);for(let o of Object.keys(e))if(!n.has(o))throw new Error(`${t}.${o} is not supported by schema v1.`);return e}a(g,"exactRecord");function A(e,t,r){if(typeof e!="string"||!t.includes(e))throw new Error(`${r} has an unsupported value.`);return e}a(A,"enumValue");function p(e,t){if(typeof e!="boolean")throw new Error(`${t} must be a boolean.`);return e}a(p,"booleanValue");function Y(e,t){return e===null?null:p(e,t)}a(Y,"nullableBoolean");function E(e,t){if(typeof e!="number"||!Number.isSafeInteger(e)||e<0||e>K)throw new Error(`${t} must be a non-negative integer no greater than ${K}.`);return e}a(E,"boundedCounter");function ce(e){if(typeof e!="string"||e.length>32)throw new Error("Runtime status receipt observedAt must be a bounded ISO timestamp.");let t=Date.parse(e);if(!Number.isFinite(t)||new Date(t).toISOString()!==e)throw new Error("Runtime status receipt observedAt must be an exact ISO timestamp.");return e}a(ce,"observedTimestamp");function ue(e){if(e===null)return null;if(typeof e!="string"||e.length===0||e.length>2048||/[\u0000-\u001f\u007f]/u.test(e))throw new Error("Runtime status receipt error must be null or one bounded display-safe line.");return e}a(ue,"receiptError");function le(e){if(!Array.isArray(e)||e.length>X)throw new Error(`Runtime status receipt assets.codecs must contain at most ${X} entries.`);let t=e.map((r,s)=>{let n=g(r,`Runtime status receipt assets.codecs[${s}]`,["name","available","decoded"]);if(typeof n.name!="string"||!de.test(n.name))throw new Error(`Runtime status receipt assets.codecs[${s}].name is invalid.`);let o=p(n.available,`Runtime status receipt assets.codecs[${s}].available`),a=p(n.decoded,`Runtime status receipt assets.codecs[${s}].decoded`);if(a&&!o)throw new Error(`Runtime status receipt codec ${JSON.stringify(n.name)} cannot be decoded when unavailable.`);return {name:n.name,available:o,decoded:a}});if(new Set(t.map(r=>r.name)).size!==t.length)throw new Error("Runtime status receipt assets.codecs must have unique names.");return t}a(le,"parseRuntimeCodecs");function me(e){if(e.assetsReady&&!e.workerReady)throw new Error("Runtime lifecycle assetsReady requires workerReady.");if(e.compiled&&!e.assetsReady)throw new Error("Runtime lifecycle compiled requires assetsReady.");if(e.firstFrame&&!e.compiled)throw new Error("Runtime lifecycle firstFrame requires compiled.");let t=e.state==="starting"?[false,false,false,false]:e.state==="worker ready"?[true,false,false,false]:e.state==="assets ready"?[true,true,false,false]:e.state==="compiled"?[true,true,true,false]:e.state==="first frame"||e.state==="updating"?[true,true,true,true]:null;if(t!==null&&![e.workerReady,e.assetsReady,e.compiled,e.firstFrame].every((r,s)=>r===t[s]))throw new Error(`Runtime lifecycle flags do not match state ${JSON.stringify(e.state)}.`)}a(me,"validateLifecycle");function pe(e){let t=g(e,"Runtime status receipt",["schemaVersion","observedAt","worker","assets","hmr","stats","lifecycle","shaders","error"],["text"]);if(t.schemaVersion!==1)throw new Error("Runtime status receipt must use schemaVersion 1.");let r=g(t.worker,"Runtime status receipt worker",["backend","renderer","protocolVersion"]);if(r.protocolVersion!==1)throw new Error("Runtime status receipt worker.protocolVersion must be 1.");let s=g(t.assets,"Runtime status receipt assets",["codecs","resources"]),n=g(t.hmr,"Runtime status receipt hmr",["capabilities","outcome"]),o=g(n.capabilities,"Runtime status receipt hmr.capabilities",["scene","component","assetManifest","workerRestart"]),a=g(n.outcome,"Runtime status receipt hmr.outcome",["attempted","succeeded","rollbackPreserved","workerRestarted"]),d=p(a.attempted,"Runtime status receipt hmr.outcome.attempted"),l=Y(a.succeeded,"Runtime status receipt hmr.outcome.succeeded"),m=Y(a.rollbackPreserved,"Runtime status receipt hmr.outcome.rollbackPreserved"),y=p(a.workerRestarted,"Runtime status receipt hmr.outcome.workerRestarted");if(d?l===null||m===null:l!==null||m!==null||y)throw new Error("Runtime status receipt HMR outcome fields are inconsistent with attempted.");let k={scene:p(o.scene,"Runtime status receipt hmr.capabilities.scene"),component:p(o.component,"Runtime status receipt hmr.capabilities.component"),assetManifest:p(o.assetManifest,"Runtime status receipt hmr.capabilities.assetManifest"),workerRestart:p(o.workerRestart,"Runtime status receipt hmr.capabilities.workerRestart")};if(d&&!k.scene)throw new Error("Runtime status receipt cannot attempt HMR without the scene capability.");if(y&&!k.workerRestart)throw new Error("Runtime status receipt cannot restart a worker without the workerRestart capability.");let x=g(t.stats,"Runtime status receipt stats",["snapshots","textures","workerProfiler","mainPanels"]),R=g(t.lifecycle,"Runtime status receipt lifecycle",["state","workerReady","assetsReady","compiled","firstFrame"]),S={state:A(R.state,ne,"Runtime status receipt lifecycle.state"),workerReady:p(R.workerReady,"Runtime status receipt lifecycle.workerReady"),assetsReady:p(R.assetsReady,"Runtime status receipt lifecycle.assetsReady"),compiled:p(R.compiled,"Runtime status receipt lifecycle.compiled"),firstFrame:p(R.firstFrame,"Runtime status receipt lifecycle.firstFrame")};me(S);let V=g(t.shaders,"Runtime status receipt shaders",["mode","pipelines"]),P=A(V.mode,["precompiled","live"],"Runtime status receipt shaders.mode"),T=E(V.pipelines,"Runtime status receipt shaders.pipelines");if(P==="precompiled"&&T===0)throw new Error("A precompiled runtime receipt must observe at least one shader pipeline.");let f;if(t.text!==void 0){let I=g(t.text,"Runtime status receipt text",["state","atlases","glyphs","requiredGlyphs"]);if(f={state:A(I.state,ae,"Runtime status receipt text.state"),atlases:E(I.atlases,"Runtime status receipt text.atlases"),glyphs:E(I.glyphs,"Runtime status receipt text.glyphs"),requiredGlyphs:E(I.requiredGlyphs,"Runtime status receipt text.requiredGlyphs")},f.state==="ready"&&(f.atlases===0||f.requiredGlyphs===0||f.glyphs<f.requiredGlyphs))throw new Error("A ready text receipt must cover a non-empty required glyph set with at least one atlas.")}let b=ue(t.error);if(S.state==="error"?b===null:b!==null)throw new Error("Runtime status receipt error must be present only when lifecycle.state is error.");return {schemaVersion:1,observedAt:ce(t.observedAt),worker:{backend:A(r.backend,ie,"Runtime status receipt worker.backend"),renderer:A(r.renderer,oe,"Runtime status receipt worker.renderer"),protocolVersion:1},assets:{codecs:le(s.codecs),resources:E(s.resources,"Runtime status receipt assets.resources")},hmr:{capabilities:k,outcome:{attempted:d,succeeded:l,rollbackPreserved:m,workerRestarted:y}},stats:{snapshots:E(x.snapshots,"Runtime status receipt stats.snapshots"),textures:E(x.textures,"Runtime status receipt stats.textures"),workerProfiler:p(x.workerProfiler,"Runtime status receipt stats.workerProfiler"),mainPanels:p(x.mainPanels,"Runtime status receipt stats.mainPanels")},lifecycle:S,shaders:{mode:P,pipelines:T},...f===void 0?{}:{text:f},error:b}}a(pe,"parseRuntimeStatusReceipt");function he(e,t){return e.render===t.render&&e.vertex===t.vertex&&e.fragment===t.fragment&&e.compute===t.compute}a(he,"sameCoverage");async function ee(e=process.cwd()){let t=h.resolve(e);for(;;){if((await Promise.all(se.map(s=>d(h.join(t,s))))).some(Boolean))return realpath(t);let r=h.dirname(t);if(r===t)return realpath(h.resolve(e));t=r;}}a(ee,"findProjectRoot");async function fe(e,t){let r=t.template,s=h.join(e,".three-blocks","shaders"),n=h.join(s,"meta.json");if(!await d(s)||!await d(n))return {state:"missing",scene:r,reason:t.artifacts?.shaders==="pending"?"The selected template has no verified shader capture yet.":".three-blocks/shaders/meta.json is absent."};try{let o=await i(e,s,"Shader artifact directory"),a=c(await O(o,n,a$2.receipt,"Shader receipt")),d=a.scenes[r];if(d===void 0)return {state:"invalid",scene:r,reason:`Shader receipt has no "${r}" scene.`};let l=await j(o,h.join(o,d.artifact),a$2.manifest,"Shader manifest");if(c$1(l.data)!==d.artifactHash)return {state:"invalid",scene:r,reason:"The selected shader manifest checksum does not match its receipt."};let m=a$3(l.data.toString("utf8"),l.path,r);if(!he(m,d.coverage))return {state:"invalid",scene:r,reason:"Shader receipt coverage does not match the manifest entries.",coverage:m};let{three:y,threeBlocks:k,threeBlocksShaderClosure:x}=await c$2(e);if(a.runtime.three!==y||t.runtime.three!==y||a.runtime.threeBlocks!==k||t.runtime.threeBlocks!==k)return {state:"stale",scene:r,reason:`Installed runtime versions (${y}, ${k}) do not match the metadata and shader receipt.`,coverage:m};if(a.runtime.threeBlocksShaderClosure!==x)return {state:"stale",scene:r,reason:"The installed three-blocks/shaders runtime closure differs from the capture receipt.",coverage:m};let R=await b(e),S=Object.keys(R),V=Object.keys(d.inputs),P=S.filter(b=>!Object.hasOwn(d.inputs,b)),T=V.filter(b=>!Object.hasOwn(R,b)),f=S.filter(b=>Object.hasOwn(d.inputs,b)&&d.inputs[b]!==R[b]);return P.length>0||T.length>0||f.length>0?{state:"stale",scene:r,reason:`${P.length} added, ${T.length} removed, and ${f.length} changed semantic shader inputs.`,coverage:m,...f.length>0?{changedInputs:f}:{},...P.length>0?{addedInputs:P}:{},...T.length>0?{removedInputs:T}:{}}:{state:"fresh",scene:r,reason:"Manifest, installed shader runtime closure, and the shader-relevant source snapshot match.",coverage:m}}catch(o){return {state:"invalid",scene:r,reason:o instanceof Error?o.message:String(o)}}}a(fe,"inspectShaders");async function ye(e,t){if(t.artifacts?.text==="pending")return {state:"missing",reason:"The template has no verified text artifacts yet.",atlases:[]};let r=await g$1(e);return {state:r.state,reason:r.reason,atlases:r.atlases.map(s=>({name:s.font.key,glyphs:s.codePoints.length,width:s.texture.width,height:s.texture.height}))}}a(ye,"inspectText");function Re(e,t){if(e.lifecycle.assetsReady&&e.assets.codecs.some(r=>!r.available))throw new Error("Runtime status receipt claims assets ready while a configured codec is unavailable.");if(t.features.text!==(e.text!==void 0))throw new Error("Runtime status receipt text observation does not match three-blocks.json.")}a(Re,"validateRuntimeReceiptForProject");async function be(e,t){let r=h.join(e,...te.split("/"));if(!await d(r))return {kind:"absent",receipt:null,reason:"No browser observation receipt is available."};try{let s=await i(e,h.dirname(r),"Runtime status receipt directory"),n=pe(await O(s,h.join(s,h.basename(r)),re,"Runtime status receipt"));return Re(n,t),{kind:"valid",receipt:n,reason:n.error??`Browser observation captured at ${n.observedAt}.`}}catch(s){return {kind:"invalid",receipt:null,reason:`Runtime status receipt is invalid: ${s instanceof Error?s.message:String(s)}`}}}a(be,"inspectRuntimeReceipt");function ge(){return {scene:false,component:false,assetManifest:false,workerRestart:false}}a(ge,"emptyCapabilities");function we(){return {attempted:false,succeeded:null,rollbackPreserved:null,workerRestarted:false}}a(we,"emptyOutcome");function ke(){return []}a(ke,"configuredCodecs");function Se(e,t,r){if(t.state!=="fresh")return "three-blocks shaders capture";if(r!==void 0&&r.state!=="ready")return "three-blocks text generate";let s=e.receipt;return e.kind!=="valid"||s===null||s.lifecycle.state==="error"?H:s.text!==void 0&&s.text.state!=="ready"?"three-blocks text generate":H}a(Se,"recoveryCommand");async function xe(e=process.cwd()){let t=await ee(e),r=b$1(await O(t,h.join(t,"three-blocks.json"),a$2.metadata,"Project metadata")),s=await fe(t,r),n=r.features.text?await ye(t,r):void 0,o=await be(t,r),a=o.receipt,d=o.kind==="invalid",l=d||a?.lifecycle.state==="error",m=a===null?{state:d?"error":"starting",backend:null,renderer:null,protocolVersion:1}:{state:l?"error":a.lifecycle.workerReady?"worker ready":"starting",backend:a.worker.backend,renderer:a.worker.renderer,protocolVersion:a.worker.protocolVersion},y=a===null?{state:d?"error":"starting",codecs:ke(),resources:0}:{state:l?"error":a.lifecycle.assetsReady?"assets ready":"starting",codecs:a.assets.codecs,resources:a.assets.resources},k=a===null?{state:d?"error":"starting",capabilities:ge(),outcome:we()}:{state:l||a.hmr.outcome.attempted&&(a.hmr.outcome.succeeded!==true||a.hmr.outcome.rollbackPreserved!==true)?"error":a.hmr.outcome.attempted?"first frame":"starting",capabilities:a.hmr.capabilities,outcome:a.hmr.outcome},x=a===null?{state:d?"error":"starting",snapshots:0,textures:0,workerProfiler:false,mainPanels:false}:{state:l?"error":a.stats.snapshots>0&&a.stats.workerProfiler&&a.stats.mainPanels?"first frame":"starting",...a.stats},R=a===null?{state:d?"error":"starting",mode:null,pipelines:0,artifactState:s.state}:{state:l?"error":a.lifecycle.compiled?s.state==="fresh"?a.shaders.mode:s.state:a.lifecycle.state,mode:a.shaders.mode,pipelines:a.shaders.pipelines,artifactState:s.state},S=n===void 0?void 0:a?.text===void 0?{state:d?"error":"starting",atlases:0,glyphs:0,requiredGlyphs:0}:{state:l?"error":n.state==="ready"?a.text.state:n.state,atlases:a.text.atlases,glyphs:a.text.glyphs,requiredGlyphs:a.text.requiredGlyphs};return {schemaVersion:1,root:t,metadata:r,configuration:{worker:m,assets:y,hmr:k,optimization:R,stats:x,...S===void 0?{}:{text:S}},runtime:{state:d?"error":a?.lifecycle.state??"starting",observed:a!==null,observedAt:a?.observedAt??null,reason:o.reason,recovery:Se(o,s,n),observation:a},shaders:s,...n?{text:n}:{}}}a(xe,"inspectProject");async function Z(e){let[t,r]=await Promise.all([d(h.join(e,"three-blocks.shaders.json")),d(h.join(e,"three-blocks.text.ts"))]),[s,n]=await Promise.all([t?d$1(e):Promise.resolve(void 0),r?g$1(e):Promise.resolve(void 0)]);return {schemaVersion:1,root:e,kind:"adopted",markers:{shaders:t,text:r},...s===void 0?{}:{shaders:s},...n===void 0?{}:{text:n}}}a(Z,"inspectAdoptedProject");async function qe(e=process.cwd()){let t=await ee(e),r=h.join(t,"three-blocks.json");if(await d(r)){try{b$1(await O(t,r,a$2.metadata,"Project metadata"));}catch{return Z(t)}return xe(t)}return Z(t)}a(qe,"inspectThreeBlocksStatus");function Ge(e){return Q(e)?(e.markers.shaders||e.markers.text)&&(e.shaders===void 0||e.shaders.state==="fresh")&&(e.text===void 0||e.text.state==="ready"):e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error"}a(Ge,"threeBlocksStatusIsFresh");function $e(e){return e==="ktx2"?"KTX2":e==="draco"?"Draco":e==="meshopt"?"Meshopt":e}a($e,"codecName");function ve(e,t=Date.now()){let r=t-Date.parse(e);if(!Number.isFinite(r)||r<0)return e;let s=Math.round(r/1e3);if(s<60)return "just now";let n=Math.round(s/60);if(n<60)return `${n} minute${n===1?"":"s"} ago`;let o=Math.round(n/60);return o<48?`${o} hour${o===1?"":"s"} ago`:`${Math.round(o/24)} days ago`}a(ve,"relativeTime");function w(e,t,r){return `${e} ${d$2(t,12)} ${r}`}a(w,"row");function v(e,t){return ` ${d$2(b$2.dim(e),12)} ${b$2.dim(t)}`}a(v,"subRow");function Pe(e){return e<100?e.toFixed(1):Math.round(e).toString()}a(Pe,"milliseconds");function Te(e){return e?`${e.render} render \xB7 ${e.compute} compute`:"no coverage"}a(Te,"coverageText");function je(e){let t=[w(g$2(e.state),"shaders",`${e.state==="fresh"?"fresh":b$2.warn(e.state)} ${c$3.dot} ${b$2.dim(e.reason)}`)];for(let r of e.scenes){let s=r.timing,n=s?.source==="committed-capture"?s.adapter??"captured adapter":"this capture",o=s===void 0?"":s.runs>1?`measured median of ${s.runs}`:"single-capture estimate",a=s===void 0?"":`\u2248${Pe(s.avoidedBuildMs)} ms TSL work avoided`,d=s===void 0?r.state==="fresh"?` ${c$3.dot} ${b$2.dim("capture again to record a timing estimate")}`:"":` ${c$3.dot} ${b$2.dim(`${a} \xB7 ${o} \xB7 ${n}`)}`;t.push(w(g$2(r.state),`${r.scene}:${r.backend}`,`${r.state} ${c$3.dot} ${Te(r.coverage)}${d}`)),s!==void 0&&s.spreadMs>s.avoidedBuildMs*.4&&t.push(v("measure",b$2.warn("noisy measurement \u2014 close other GPU apps and re-run")));let l=[...r.changedInputs??[],...r.addedInputs??[],...r.removedInputs??[]];l.length>0&&t.push(v("changed",l.join(", ")));}return e.state!=="fresh"&&t.push(`${c$3.info} ${b$2.accent("three-blocks shaders capture")}`),t.join(`
|
|
2
|
+
import {d as d$2,b as b$2,c as c$3,g as g$2}from'./chunk-76WRV5MZ.js';import {g as g$1}from'./chunk-JHBQB7WC.js';import {a as a$3,c as c$2,b,d as d$1}from'./chunk-NQIAU3XU.js';import {a as a$1,c,b as b$1}from'./chunk-65VEJRRT.js';import {j,d,i,a as a$2,c as c$1}from'./chunk-5L2VS3BN.js';import {a}from'./chunk-HOZDD6PW.js';import {realpath}from'fs/promises';import h from'path';var te=".three-blocks/runtime/status.json",re=256*1024,H="three-blocks browser smoke",se=["three-blocks.json","three-blocks.shaders.json","three-blocks.text.ts"];function Q(e){return "kind"in e&&e.kind==="adopted"}a(Q,"isAdoptedProjectStatus");async function O(e,t,r,s){let n=await j(e,t,r,s);return JSON.parse(n.data.toString("utf8"))}a(O,"readJsonWithin");var ne=["starting","worker ready","assets ready","compiled","first frame","updating","error"],ae=["ready","generating","fallback","missing","invalid"],oe=["WebGPU","WebGL"],ie=["OffscreenCanvas","MainThread"],de=/^[0-9A-Za-z][0-9A-Za-z._-]{0,63}$/,X=16,K=1e9;function g(e,t,r,s=[]){if(!a$1(e))throw new Error(`${t} must be an object.`);let n=new Set([...r,...s]);for(let o of r)if(!Object.hasOwn(e,o))throw new Error(`${t}.${o} is required.`);for(let o of Object.keys(e))if(!n.has(o))throw new Error(`${t}.${o} is not supported by schema v1.`);return e}a(g,"exactRecord");function A(e,t,r){if(typeof e!="string"||!t.includes(e))throw new Error(`${r} has an unsupported value.`);return e}a(A,"enumValue");function p(e,t){if(typeof e!="boolean")throw new Error(`${t} must be a boolean.`);return e}a(p,"booleanValue");function Y(e,t){return e===null?null:p(e,t)}a(Y,"nullableBoolean");function E(e,t){if(typeof e!="number"||!Number.isSafeInteger(e)||e<0||e>K)throw new Error(`${t} must be a non-negative integer no greater than ${K}.`);return e}a(E,"boundedCounter");function ce(e){if(typeof e!="string"||e.length>32)throw new Error("Runtime status receipt observedAt must be a bounded ISO timestamp.");let t=Date.parse(e);if(!Number.isFinite(t)||new Date(t).toISOString()!==e)throw new Error("Runtime status receipt observedAt must be an exact ISO timestamp.");return e}a(ce,"observedTimestamp");function ue(e){if(e===null)return null;if(typeof e!="string"||e.length===0||e.length>2048||/[\u0000-\u001f\u007f]/u.test(e))throw new Error("Runtime status receipt error must be null or one bounded display-safe line.");return e}a(ue,"receiptError");function le(e){if(!Array.isArray(e)||e.length>X)throw new Error(`Runtime status receipt assets.codecs must contain at most ${X} entries.`);let t=e.map((r,s)=>{let n=g(r,`Runtime status receipt assets.codecs[${s}]`,["name","available","decoded"]);if(typeof n.name!="string"||!de.test(n.name))throw new Error(`Runtime status receipt assets.codecs[${s}].name is invalid.`);let o=p(n.available,`Runtime status receipt assets.codecs[${s}].available`),a=p(n.decoded,`Runtime status receipt assets.codecs[${s}].decoded`);if(a&&!o)throw new Error(`Runtime status receipt codec ${JSON.stringify(n.name)} cannot be decoded when unavailable.`);return {name:n.name,available:o,decoded:a}});if(new Set(t.map(r=>r.name)).size!==t.length)throw new Error("Runtime status receipt assets.codecs must have unique names.");return t}a(le,"parseRuntimeCodecs");function me(e){if(e.assetsReady&&!e.workerReady)throw new Error("Runtime lifecycle assetsReady requires workerReady.");if(e.compiled&&!e.assetsReady)throw new Error("Runtime lifecycle compiled requires assetsReady.");if(e.firstFrame&&!e.compiled)throw new Error("Runtime lifecycle firstFrame requires compiled.");let t=e.state==="starting"?[false,false,false,false]:e.state==="worker ready"?[true,false,false,false]:e.state==="assets ready"?[true,true,false,false]:e.state==="compiled"?[true,true,true,false]:e.state==="first frame"||e.state==="updating"?[true,true,true,true]:null;if(t!==null&&![e.workerReady,e.assetsReady,e.compiled,e.firstFrame].every((r,s)=>r===t[s]))throw new Error(`Runtime lifecycle flags do not match state ${JSON.stringify(e.state)}.`)}a(me,"validateLifecycle");function pe(e){let t=g(e,"Runtime status receipt",["schemaVersion","observedAt","worker","assets","hmr","stats","lifecycle","shaders","error"],["text"]);if(t.schemaVersion!==1)throw new Error("Runtime status receipt must use schemaVersion 1.");let r=g(t.worker,"Runtime status receipt worker",["backend","renderer","protocolVersion"]);if(r.protocolVersion!==1)throw new Error("Runtime status receipt worker.protocolVersion must be 1.");let s=g(t.assets,"Runtime status receipt assets",["codecs","resources"]),n=g(t.hmr,"Runtime status receipt hmr",["capabilities","outcome"]),o=g(n.capabilities,"Runtime status receipt hmr.capabilities",["scene","component","assetManifest","workerRestart"]),a=g(n.outcome,"Runtime status receipt hmr.outcome",["attempted","succeeded","rollbackPreserved","workerRestarted"]),d=p(a.attempted,"Runtime status receipt hmr.outcome.attempted"),l=Y(a.succeeded,"Runtime status receipt hmr.outcome.succeeded"),m=Y(a.rollbackPreserved,"Runtime status receipt hmr.outcome.rollbackPreserved"),y=p(a.workerRestarted,"Runtime status receipt hmr.outcome.workerRestarted");if(d?l===null||m===null:l!==null||m!==null||y)throw new Error("Runtime status receipt HMR outcome fields are inconsistent with attempted.");let S={scene:p(o.scene,"Runtime status receipt hmr.capabilities.scene"),component:p(o.component,"Runtime status receipt hmr.capabilities.component"),assetManifest:p(o.assetManifest,"Runtime status receipt hmr.capabilities.assetManifest"),workerRestart:p(o.workerRestart,"Runtime status receipt hmr.capabilities.workerRestart")};if(d&&!S.scene)throw new Error("Runtime status receipt cannot attempt HMR without the scene capability.");if(y&&!S.workerRestart)throw new Error("Runtime status receipt cannot restart a worker without the workerRestart capability.");let x=g(t.stats,"Runtime status receipt stats",["snapshots","textures","workerProfiler","mainPanels"]),R=g(t.lifecycle,"Runtime status receipt lifecycle",["state","workerReady","assetsReady","compiled","firstFrame"]),k={state:A(R.state,ne,"Runtime status receipt lifecycle.state"),workerReady:p(R.workerReady,"Runtime status receipt lifecycle.workerReady"),assetsReady:p(R.assetsReady,"Runtime status receipt lifecycle.assetsReady"),compiled:p(R.compiled,"Runtime status receipt lifecycle.compiled"),firstFrame:p(R.firstFrame,"Runtime status receipt lifecycle.firstFrame")};me(k);let V=g(t.shaders,"Runtime status receipt shaders",["mode","pipelines"]),P=A(V.mode,["precompiled","live"],"Runtime status receipt shaders.mode"),T=E(V.pipelines,"Runtime status receipt shaders.pipelines");if(P==="precompiled"&&T===0)throw new Error("A precompiled runtime receipt must observe at least one shader pipeline.");let f;if(t.text!==void 0){let I=g(t.text,"Runtime status receipt text",["state","atlases","glyphs","requiredGlyphs"]);if(f={state:A(I.state,ae,"Runtime status receipt text.state"),atlases:E(I.atlases,"Runtime status receipt text.atlases"),glyphs:E(I.glyphs,"Runtime status receipt text.glyphs"),requiredGlyphs:E(I.requiredGlyphs,"Runtime status receipt text.requiredGlyphs")},f.state==="ready"&&(f.atlases===0||f.requiredGlyphs===0||f.glyphs<f.requiredGlyphs))throw new Error("A ready text receipt must cover a non-empty required glyph set with at least one atlas.")}let b=ue(t.error);if(k.state==="error"?b===null:b!==null)throw new Error("Runtime status receipt error must be present only when lifecycle.state is error.");return {schemaVersion:1,observedAt:ce(t.observedAt),worker:{backend:A(r.backend,ie,"Runtime status receipt worker.backend"),renderer:A(r.renderer,oe,"Runtime status receipt worker.renderer"),protocolVersion:1},assets:{codecs:le(s.codecs),resources:E(s.resources,"Runtime status receipt assets.resources")},hmr:{capabilities:S,outcome:{attempted:d,succeeded:l,rollbackPreserved:m,workerRestarted:y}},stats:{snapshots:E(x.snapshots,"Runtime status receipt stats.snapshots"),textures:E(x.textures,"Runtime status receipt stats.textures"),workerProfiler:p(x.workerProfiler,"Runtime status receipt stats.workerProfiler"),mainPanels:p(x.mainPanels,"Runtime status receipt stats.mainPanels")},lifecycle:k,shaders:{mode:P,pipelines:T},...f===void 0?{}:{text:f},error:b}}a(pe,"parseRuntimeStatusReceipt");function he(e,t){return e.render===t.render&&e.vertex===t.vertex&&e.fragment===t.fragment&&e.compute===t.compute}a(he,"sameCoverage");async function ee(e=process.cwd()){let t=h.resolve(e);for(;;){if((await Promise.all(se.map(s=>d(h.join(t,s))))).some(Boolean))return realpath(t);let r=h.dirname(t);if(r===t)return realpath(h.resolve(e));t=r;}}a(ee,"findProjectRoot");async function fe(e,t){let r=t.template,s=h.join(e,".three-blocks","shaders"),n=h.join(s,"meta.json");if(!await d(s)||!await d(n))return {state:"missing",scene:r,reason:t.artifacts?.shaders==="pending"?"The selected template has no verified shader capture yet.":".three-blocks/shaders/meta.json is absent."};try{let o=await i(e,s,"Shader artifact directory"),a=c(await O(o,n,a$2.receipt,"Shader receipt")),d=a.scenes[r];if(d===void 0)return {state:"invalid",scene:r,reason:`Shader receipt has no "${r}" scene.`};let l=await j(o,h.join(o,d.artifact),a$2.manifest,"Shader manifest");if(c$1(l.data)!==d.artifactHash)return {state:"invalid",scene:r,reason:"The selected shader manifest checksum does not match its receipt."};let m=a$3(l.data.toString("utf8"),l.path,r);if(!he(m,d.coverage))return {state:"invalid",scene:r,reason:"Shader receipt coverage does not match the manifest entries.",coverage:m};let{three:y,threeBlocks:S,threeBlocksShaderClosure:x}=await c$2(e);if(a.runtime.three!==y||t.runtime.three!==y||t.runtime.threeBlocks!==S)return {state:"stale",scene:r,reason:`Installed runtime versions (${y}, ${S}) do not match the metadata and shader receipt.`,coverage:m};if(a.runtime.threeBlocksShaderClosure!==x)return {state:"stale",scene:r,reason:"The installed three-blocks/shaders runtime closure differs from the capture receipt.",coverage:m};let R=await b(e),k=Object.keys(R),V=Object.keys(d.inputs),P=k.filter(b=>!Object.hasOwn(d.inputs,b)),T=V.filter(b=>!Object.hasOwn(R,b)),f=k.filter(b=>Object.hasOwn(d.inputs,b)&&d.inputs[b]!==R[b]);return P.length>0||T.length>0||f.length>0?{state:"stale",scene:r,reason:`${P.length} added, ${T.length} removed, and ${f.length} changed semantic shader inputs.`,coverage:m,...f.length>0?{changedInputs:f}:{},...P.length>0?{addedInputs:P}:{},...T.length>0?{removedInputs:T}:{}}:{state:"fresh",scene:r,reason:"Manifest, installed shader runtime closure, and the shader-relevant source snapshot match.",coverage:m}}catch(o){return {state:"invalid",scene:r,reason:o instanceof Error?o.message:String(o)}}}a(fe,"inspectShaders");async function ye(e,t){if(t.artifacts?.text==="pending")return {state:"missing",reason:"The template has no verified text artifacts yet.",atlases:[]};let r=await g$1(e);return {state:r.state,reason:r.reason,atlases:r.atlases.map(s=>({name:s.font.key,glyphs:s.codePoints.length,width:s.texture.width,height:s.texture.height}))}}a(ye,"inspectText");function Re(e,t){if(e.lifecycle.assetsReady&&e.assets.codecs.some(r=>!r.available))throw new Error("Runtime status receipt claims assets ready while a configured codec is unavailable.");if(t.features.text!==(e.text!==void 0))throw new Error("Runtime status receipt text observation does not match three-blocks.json.")}a(Re,"validateRuntimeReceiptForProject");async function be(e,t){let r=h.join(e,...te.split("/"));if(!await d(r))return {kind:"absent",receipt:null,reason:"No browser observation receipt is available."};try{let s=await i(e,h.dirname(r),"Runtime status receipt directory"),n=pe(await O(s,h.join(s,h.basename(r)),re,"Runtime status receipt"));return Re(n,t),{kind:"valid",receipt:n,reason:n.error??`Browser observation captured at ${n.observedAt}.`}}catch(s){return {kind:"invalid",receipt:null,reason:`Runtime status receipt is invalid: ${s instanceof Error?s.message:String(s)}`}}}a(be,"inspectRuntimeReceipt");function ge(){return {scene:false,component:false,assetManifest:false,workerRestart:false}}a(ge,"emptyCapabilities");function we(){return {attempted:false,succeeded:null,rollbackPreserved:null,workerRestarted:false}}a(we,"emptyOutcome");function ke(){return []}a(ke,"configuredCodecs");function Se(e,t,r){if(t.state!=="fresh")return "three-blocks shaders capture";if(r!==void 0&&r.state!=="ready")return "three-blocks text generate";let s=e.receipt;return e.kind!=="valid"||s===null||s.lifecycle.state==="error"?H:s.text!==void 0&&s.text.state!=="ready"?"three-blocks text generate":H}a(Se,"recoveryCommand");async function xe(e=process.cwd()){let t=await ee(e),r=b$1(await O(t,h.join(t,"three-blocks.json"),a$2.metadata,"Project metadata")),s=await fe(t,r),n=r.features.text?await ye(t,r):void 0,o=await be(t,r),a=o.receipt,d=o.kind==="invalid",l=d||a?.lifecycle.state==="error",m=a===null?{state:d?"error":"starting",backend:null,renderer:null,protocolVersion:1}:{state:l?"error":a.lifecycle.workerReady?"worker ready":"starting",backend:a.worker.backend,renderer:a.worker.renderer,protocolVersion:a.worker.protocolVersion},y=a===null?{state:d?"error":"starting",codecs:ke(),resources:0}:{state:l?"error":a.lifecycle.assetsReady?"assets ready":"starting",codecs:a.assets.codecs,resources:a.assets.resources},S=a===null?{state:d?"error":"starting",capabilities:ge(),outcome:we()}:{state:l||a.hmr.outcome.attempted&&(a.hmr.outcome.succeeded!==true||a.hmr.outcome.rollbackPreserved!==true)?"error":a.hmr.outcome.attempted?"first frame":"starting",capabilities:a.hmr.capabilities,outcome:a.hmr.outcome},x=a===null?{state:d?"error":"starting",snapshots:0,textures:0,workerProfiler:false,mainPanels:false}:{state:l?"error":a.stats.snapshots>0&&a.stats.workerProfiler&&a.stats.mainPanels?"first frame":"starting",...a.stats},R=a===null?{state:d?"error":"starting",mode:null,pipelines:0,artifactState:s.state}:{state:l?"error":a.lifecycle.compiled?s.state==="fresh"?a.shaders.mode:s.state:a.lifecycle.state,mode:a.shaders.mode,pipelines:a.shaders.pipelines,artifactState:s.state},k=n===void 0?void 0:a?.text===void 0?{state:d?"error":"starting",atlases:0,glyphs:0,requiredGlyphs:0}:{state:l?"error":n.state==="ready"?a.text.state:n.state,atlases:a.text.atlases,glyphs:a.text.glyphs,requiredGlyphs:a.text.requiredGlyphs};return {schemaVersion:1,root:t,metadata:r,configuration:{worker:m,assets:y,hmr:S,optimization:R,stats:x,...k===void 0?{}:{text:k}},runtime:{state:d?"error":a?.lifecycle.state??"starting",observed:a!==null,observedAt:a?.observedAt??null,reason:o.reason,recovery:Se(o,s,n),observation:a},shaders:s,...n?{text:n}:{}}}a(xe,"inspectProject");async function Z(e){let[t,r]=await Promise.all([d(h.join(e,"three-blocks.shaders.json")),d(h.join(e,"three-blocks.text.ts"))]),[s,n]=await Promise.all([t?d$1(e):Promise.resolve(void 0),r?g$1(e):Promise.resolve(void 0)]);return {schemaVersion:1,root:e,kind:"adopted",markers:{shaders:t,text:r},...s===void 0?{}:{shaders:s},...n===void 0?{}:{text:n}}}a(Z,"inspectAdoptedProject");async function qe(e=process.cwd()){let t=await ee(e),r=h.join(t,"three-blocks.json");if(await d(r)){try{b$1(await O(t,r,a$2.metadata,"Project metadata"));}catch{return Z(t)}return xe(t)}return Z(t)}a(qe,"inspectThreeBlocksStatus");function Ge(e){return Q(e)?(e.markers.shaders||e.markers.text)&&(e.shaders===void 0||e.shaders.state==="fresh")&&(e.text===void 0||e.text.state==="ready"):e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error"}a(Ge,"threeBlocksStatusIsFresh");function $e(e){return e==="ktx2"?"KTX2":e==="draco"?"Draco":e==="meshopt"?"Meshopt":e}a($e,"codecName");function ve(e,t=Date.now()){let r=t-Date.parse(e);if(!Number.isFinite(r)||r<0)return e;let s=Math.round(r/1e3);if(s<60)return "just now";let n=Math.round(s/60);if(n<60)return `${n} minute${n===1?"":"s"} ago`;let o=Math.round(n/60);return o<48?`${o} hour${o===1?"":"s"} ago`:`${Math.round(o/24)} days ago`}a(ve,"relativeTime");function w(e,t,r){return `${e} ${d$2(t,12)} ${r}`}a(w,"row");function v(e,t){return ` ${d$2(b$2.dim(e),12)} ${b$2.dim(t)}`}a(v,"subRow");function Pe(e){return e<100?e.toFixed(1):Math.round(e).toString()}a(Pe,"milliseconds");function Te(e){return e?`${e.render} render \xB7 ${e.compute} compute`:"no coverage"}a(Te,"coverageText");function je(e){let t=[w(g$2(e.state),"shaders",`${e.state==="fresh"?"fresh":b$2.warn(e.state)} ${c$3.dot} ${b$2.dim(e.reason)}`)];for(let r of e.scenes){let s=r.timing,n=s?.source==="committed-capture"?s.adapter??"captured adapter":"this capture",o=s===void 0?"":s.runs>1?`measured median of ${s.runs}`:"single-capture estimate",a=s===void 0?"":`\u2248${Pe(s.avoidedBuildMs)} ms TSL work avoided`,d=s===void 0?r.state==="fresh"?` ${c$3.dot} ${b$2.dim("capture again to record a timing estimate")}`:"":` ${c$3.dot} ${b$2.dim(`${a} \xB7 ${o} \xB7 ${n}`)}`;t.push(w(g$2(r.state),`${r.scene}:${r.backend}`,`${r.state} ${c$3.dot} ${Te(r.coverage)}${d}`)),s!==void 0&&s.spreadMs>s.avoidedBuildMs*.4&&t.push(v("measure",b$2.warn("noisy measurement \u2014 close other GPU apps and re-run")));let l=[...r.changedInputs??[],...r.addedInputs??[],...r.removedInputs??[]];l.length>0&&t.push(v("changed",l.join(", ")));}return e.state!=="fresh"&&t.push(`${c$3.info} ${b$2.accent("three-blocks shaders capture")}`),t.join(`
|
|
3
3
|
`)}a(je,"formatShaderMatrixStatus");function Ee(e){let t=e.scene,r=e.coverage,s=r?`${r.render} render \xB7 ${r.compute} compute`:"no coverage";if(e.state==="fresh")return [w(g$2("fresh"),t,`fresh ${c$3.dot} ${s} ${c$3.dot} ${b$2.dim("precompiled at runtime")}`)];let n=[w(g$2(e.state),t,`${e.state==="missing"?b$2.dim("missing"):b$2.warn(e.state)} ${c$3.dot} ${b$2.dim(e.reason)}`)],o=[...e.changedInputs??[],...e.addedInputs??[],...e.removedInputs??[]];return o.length>0&&n.push(v("changed",o.join(", "))),n}a(Ee,"shaderRow");function Me(e,t=Date.now()){let r=c$3.mark?`${c$3.mark} `:"",s=e.metadata.runtime,n=[`${r}${b$2.bold("three-blocks")} ${b$2.dim("status")}`,v("project",e.root),"",b$2.bold("Project"),w(c$3.tick,e.metadata.template,`three ${s.three} ${c$3.dot} three-blocks ${s.threeBlocks}`),"",b$2.bold("Shaders"),...Ee(e.shaders)];if(e.text){let d=e.text,l=d.atlases.reduce((m,y)=>m+y.glyphs,0);n.push("",b$2.bold("Text"),w(g$2(d.state),"coverage",d.state==="ready"?`ready ${c$3.dot} ${l} glyphs ${c$3.dot} ${d.atlases.length} atlas${d.atlases.length===1?"":"es"}`:`${b$2.warn(d.state)} ${c$3.dot} ${b$2.dim(d.reason)}`),...d.atlases.map(m=>v("atlas",`${m.name} \xB7 ${m.glyphs} glyphs \xB7 ${m.width}\xD7${m.height}`)));}let o=e.runtime.observation;if(n.push("",b$2.bold("Browser check")),o!==null&&e.runtime.state!=="error"){let d=o.assets.codecs.map(l=>`${$e(l.name)}${l.decoded?"":l.available?" (idle)":" (unavailable)"}`).join(" \xB7 ");n.push(w(c$3.tick,"verified",`${ve(o.observedAt,t)} ${c$3.dot} ${o.worker.renderer} worker ${c$3.dot} ${o.lifecycle.state} ${c$3.dot} ${o.shaders.pipelines} pipeline${o.shaders.pipelines===1?"":"s"} ${o.shaders.mode}`),v("codecs",d||"none configured")),o.hmr.outcome.attempted&&n.push(v("hmr",o.hmr.outcome.succeeded?`update succeeded${o.hmr.outcome.workerRestarted?" \xB7 worker restarted":""}`:"update failed"));}else e.runtime.state==="error"?n.push(w(c$3.cross,"runtime",b$2.danger(e.runtime.reason))):n.push(w(c$3.ring,"unverified",b$2.dim(`no browser run recorded \u2014 ${H}`)));return e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error"||n.push("",b$2.bold("Next"),`${c$3.info} ${b$2.accent(e.runtime.recovery)}`),n.join(`
|
|
4
4
|
`)}a(Me,"formatStatus");function He(e,t=Date.now()){if(!Q(e))return Me(e,t);let r=c$3.mark?`${c$3.mark} `:"",s=e.markers.shaders||e.markers.text,n=[`${r}${b$2.bold("three-blocks")} ${b$2.dim("status")}`,v("project",e.root)];if(!s)return n.push("",`${c$3.dot} ${b$2.dim("no Three Blocks project markers found")}`,` ${b$2.dim("shaders:")} add three-blocks.shaders.json \u2014 /docs/tools/devtools`,` ${b$2.dim("starter:")} npx three-blocks starter`),n.join(`
|
|
5
5
|
`);if(e.shaders!==void 0&&n.push("",b$2.bold("Shaders"),je(e.shaders)),e.text!==void 0){let o=e.text.atlases.reduce((a,d)=>a+d.codePoints.length,0);n.push("",b$2.bold("Text"),w(g$2(e.text.state),"coverage",e.text.state==="ready"?`ready ${c$3.dot} ${o} glyphs ${c$3.dot} ${e.text.atlases.length} atlas${e.text.atlases.length===1?"":"es"}`:`${b$2.warn(e.text.state)} ${c$3.dot} ${b$2.dim(e.text.reason)}`));}return n.join(`
|