@three-blocks/devtools 11.1.0 → 12.0.0-alpha.399.g24d19fd0f1a1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +6 -2
  3. package/dist/{asset-optimize-YJGWKD4Y.js → asset-optimize-AC3RBHSK.js} +1 -1
  4. package/dist/browser/shader-capture.js +2 -2
  5. package/dist/browser-smoke-ZHNB3MIO.js +1 -0
  6. package/dist/{chunk-BBODS5RH.js → chunk-2SGYUV6P.js} +1 -1
  7. package/dist/chunk-75JSWKB4.js +2 -0
  8. package/dist/chunk-7YWPJCDF.cjs +1 -0
  9. package/dist/chunk-EX34XRLW.js +78 -0
  10. package/dist/chunk-HIS44NIG.js +23 -0
  11. package/dist/chunk-RITS37ER.js +1 -0
  12. package/dist/{chunk-S5LI2C2H.js → chunk-SNPGWQMW.js} +2 -2
  13. package/dist/chunk-UDMY6S4M.js +16 -0
  14. package/dist/chunk-UO6IYJA3.js +257 -0
  15. package/dist/chunk-WWBW6MPB.js +2 -0
  16. package/dist/cli.js +28 -27
  17. package/dist/index.d.ts +87 -48
  18. package/dist/index.js +1 -1
  19. package/dist/shader-browser-N5LY2NJX.js +1 -0
  20. package/dist/shader-capture-server.d.ts +13 -1
  21. package/dist/shader-capture-server.js +14 -14
  22. package/dist/{shader-config-AKZEKIRB.js → shader-config-TOBHWNCD.js} +1 -1
  23. package/dist/shader-workflow-JU5VYBN7.js +1 -0
  24. package/dist/status-CJTXLJBV.js +1 -0
  25. package/dist/transform.cjs +1 -1
  26. package/dist/transform.js +1 -1
  27. package/dist/webpack-loader.cjs +1 -1
  28. package/dist/webpack-loader.js +1 -1
  29. package/node/index.d.mts +2 -1
  30. package/node/index.mjs +10 -2
  31. package/node/layout.mjs +14 -2
  32. package/node/loader.mjs +5 -2
  33. package/node/worker.mjs +29 -6
  34. package/package.json +9 -4
  35. package/dist/browser-smoke-4MYMHKWB.js +0 -1
  36. package/dist/chunk-4SVF5BRM.js +0 -2
  37. package/dist/chunk-DCLDEPPB.js +0 -253
  38. package/dist/chunk-LMLJIVNY.cjs +0 -1
  39. package/dist/chunk-LSH64HEU.js +0 -80
  40. package/dist/chunk-NDIPQLTU.js +0 -16
  41. package/dist/chunk-NJITVI23.js +0 -2
  42. package/dist/chunk-O5FU2ASS.js +0 -16
  43. package/dist/chunk-QQKHDH26.js +0 -1
  44. package/dist/chunk-SBUKHO24.js +0 -1
  45. package/dist/shader-browser-6ICBHK3S.js +0 -1
  46. package/dist/shader-watch-JBUA4LP5.js +0 -1
  47. package/dist/shader-workflow-5EHHR32D.js +0 -1
  48. package/dist/status-GDVSLQWV.js +0 -1
@@ -1,4 +1,4 @@
1
- import {a as a$3,c as c$2,b,d as d$1}from'./chunk-O5FU2ASS.js';import {d as d$2,b as b$2,c as c$3,g as g$1}from'./chunk-CMMYXGQ3.js';import {m}from'./chunk-MIJXPQPM.js';import {a as a$1,c,b as b$1}from'./chunk-WNSGAV6N.js';import {j,d,i,a as a$2,c as c$1}from'./chunk-ECQE4D2U.js';import {a}from'./chunk-7X4DHW36.js';import {realpath}from'fs/promises';import h from'path';var te=".three-blocks/runtime/status.json",re=256*1024,O="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 C(e,t,r,s){let n=await j(e,t,r,s);return JSON.parse(n.data.toString("utf8"))}a(C,"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 C(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 m(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 C(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){if(t!==void 0&&t.state!=="ready")return "three-blocks text generate";let r=e.receipt;return e.kind!=="valid"||r===null||r.lifecycle.state==="error"?O:r.text!==void 0&&r.text.state!=="ready"?"three-blocks text generate":O}a(Se,"recoveryCommand");async function xe(e=process.cwd()){let t=await ee(e),r=b$1(await C(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,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?m(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 C(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$1(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$1(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(`
1
+ import {a as a$3,c as c$2,b,d as d$1}from'./chunk-HIS44NIG.js';import {d as d$2,b as b$2,c as c$3,g as g$1}from'./chunk-CMMYXGQ3.js';import {m}from'./chunk-MIJXPQPM.js';import {a as a$1,c,b as b$1}from'./chunk-WNSGAV6N.js';import {j,d,i,a as a$2,c as c$1}from'./chunk-ECQE4D2U.js';import {a}from'./chunk-7X4DHW36.js';import {realpath}from'fs/promises';import h from'path';var te=".three-blocks/runtime/status.json",re=256*1024,O="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 C(e,t,r,s){let n=await j(e,t,r,s);return JSON.parse(n.data.toString("utf8"))}a(C,"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 C(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 m(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 C(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){if(t!==void 0&&t.state!=="ready")return "three-blocks text generate";let r=e.receipt;return e.kind!=="valid"||r===null||r.lifecycle.state==="error"?O:r.text!==void 0&&r.text.state!=="ready"?"three-blocks text generate":O}a(Se,"recoveryCommand");async function xe(e=process.cwd()){let t=await ee(e),r=b$1(await C(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,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?m(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 C(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$1(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$1(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
2
  `)}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$1("fresh"),t,`fresh ${c$3.dot} ${s} ${c$3.dot} ${b$2.dim("precompiled at runtime")}`)];let n=[w(g$1(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$1(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 ${O}`)));return !(e.shaders.state==="fresh"&&(e.text===void 0||e.text.state==="ready")&&e.runtime.state!=="error")&&(e.runtime.state==="error"||e.runtime.recovery!==O)&&n.push("",b$2.bold("Next"),`${c$3.info} ${b$2.accent(e.runtime.recovery)}`),n.join(`
3
3
  `)}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(`
4
4
  `);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$1(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(`
@@ -0,0 +1,2 @@
1
+ import {a as a$1,b as b$1}from'./chunk-WNSGAV6N.js';import {d,j as j$1,a as a$2,g}from'./chunk-ECQE4D2U.js';import {a}from'./chunk-7X4DHW36.js';import {realpath,readFile,readdir}from'fs/promises';import c from'path';var S="three-blocks.shaders.json",U=".three-blocks/shaders",V=".three-blocks/shaders/parity",D=/^[a-z0-9][a-z0-9_-]{0,63}$/u,M=/^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)*$/u,x=64,E=64,R={schemaVersion:1,backend:"both",scenes:[{key:"default",url:"/"}]};function z(n="both"){return n==="both"?["webgpu","webgl"]:[n]}a(z,"shaderBackends");function A(n,r){return n.backend===void 0?r:r.filter(e=>e===n.backend)}a(A,"shaderSceneBackends");function J(n,r){return r.flatMap(e=>n.filter(t=>A(t,[e]).length>0).map(t=>({scene:t,backend:e,key:B(t.key,e)})))}a(J,"shaderScenePairs");function B(n,r){return r==="webgpu"?n:`${n}.webgl`}a(B,"shaderReceiptKey");function j(n,r,e){if(n===void 0)return e;if(typeof n!="string"||n.length===0||n.length>512||c.isAbsolute(n)||/[\u0000-\u001f\u007f]/u.test(n))throw new Error(`${r} must be a bounded project-relative directory.`);let t=c.posix.normalize(n.replaceAll("\\","/")).replace(/\/+$/u,"");if(t==="."||t===".."||t.startsWith("../"))throw new Error(`${r} must stay inside the project.`);return t}a(j,"safeProjectDirectory");function F(n,r){let e=j(n,r,"");if(typeof n!="string"||n.endsWith("/"))throw new Error(`${r} must be a project-relative file.`);return e}a(F,"safeProjectFile");function h(n,r,e,t,a){if(n===void 0)return a;if(!Number.isSafeInteger(n)||Number(n)<e||Number(n)>t)throw new Error(`${r} must be an integer in ${e}...${t}.`);return Number(n)}a(h,"boundedInteger");function T(n,r,e){if(n===void 0)return e;if(typeof n!="number"||!Number.isFinite(n)||n<0||n>1)throw new Error(`${r} must be a finite ratio in 0...1.`);return n}a(T,"finiteRatio");function $(n,r){if(typeof n!="string"||n.length===0||n.length>2048||/[\u0000-\u001f\u007f]/u.test(n))throw new Error(`${r} must be a bounded project-relative URL.`);let e;try{e=new URL(n,"http://three-blocks.invalid/");}catch{throw new Error(`${r} is not a valid URL.`)}if(e.origin!=="http://three-blocks.invalid"||e.hash.length>0)throw new Error(`${r} must stay within the project and must not contain a fragment.`);return `${e.pathname}${e.search}`}a($,"safeBrowserUrl");function N(n){if(!Array.isArray(n)||n.length===0||n.length>x)throw new Error(`Shader config scenes must contain 1...${x} entries.`);let r=new Set;return n.map((e,t)=>{if(!a$1(e)||typeof e.key!="string"||!D.test(e.key))throw new Error(`Shader config scene ${t} has an invalid key.`);if(r.has(e.key))throw new Error(`Shader config scene key "${e.key}" is duplicated.`);r.add(e.key);let a=e.parityFrames,o=e.maxDiffRatio;if(e.inputs!==void 0&&(!Array.isArray(e.inputs)||e.inputs.length===0||e.inputs.length>E))throw new Error(`Shader config scene "${e.key}" inputs must contain 1...${E} files.`);let i=e.inputs===void 0?void 0:e.inputs.map((f,l)=>F(f,`Shader config scene "${e.key}" input ${l}`));if(i!==void 0&&new Set(i).size!==i.length)throw new Error(`Shader config scene "${e.key}" inputs must be unique.`);if(e.runtimeMotion!==void 0&&typeof e.runtimeMotion!="boolean")throw new Error(`Shader config scene "${e.key}" runtimeMotion must be a boolean.`);if(e.backend!==void 0&&e.backend!=="webgpu"&&e.backend!=="webgl")throw new Error(`Shader config scene "${e.key}" backend must be "webgpu" or "webgl".`);return {key:e.key,url:$(e.url,`Shader config scene "${e.key}" URL`),...e.backend===void 0?{}:{backend:e.backend},requiresText:e.requiresText===true,...i===void 0?{}:{inputs:i},...a===void 0?{}:{parityFrames:h(a,`Shader config scene "${e.key}" parityFrames`,0,1e4,0)},...o===void 0?{}:{maxDiffRatio:T(o,`Shader config scene "${e.key}" maxDiffRatio`,.01)},...e.runtimeMotion===true?{runtimeMotion:true}:{}}})}a(N,"parseScenes");function y(n){if(!a$1(n)||n.schemaVersion!==void 0&&n.schemaVersion!==1)throw new Error("Shader config must use schemaVersion 1.");let r=n.viewport;if(r!==void 0&&!a$1(r))throw new Error("Shader config viewport must be an object.");let e=n.parity;if(e!==void 0&&!a$1(e))throw new Error("Shader config parity must be an object.");let t=n.bridge;if(t!==void 0&&!a$1(t))throw new Error("Shader config bridge must be an object.");let a=a$1(t)?t.deterministicModule:void 0;a!==void 0&&$(a,"Shader deterministic module");let o=n.readiness;if(o!==void 0&&!a$1(o))throw new Error("Shader config readiness must be an object.");let i=a$1(o)?o.selector:void 0;if(i!==void 0&&(typeof i!="string"||i.length===0||i.length>512||/[\u0000-\u001f\u007f]/u.test(i)))throw new Error("Shader readiness selector must be a bounded, non-empty CSS selector.");let f=a$1(o)?o.global:void 0;if(f!==void 0&&(typeof f!="string"||!M.test(f)))throw new Error("Shader readiness global must be a dot-separated JavaScript property path.");if(n.backend!==void 0&&n.backend!=="webgpu"&&n.backend!=="webgl"&&n.backend!=="both")throw new Error('Shader config backend must be "webgpu", "webgl", or "both".');let l=h(n.timeoutMs,"Shader timeoutMs",1e3,15*6e4,24e4);return {schemaVersion:1,backend:n.backend??"both",scenes:N(n.scenes),settleFrames:h(n.settleFrames,"Shader settleFrames",0,1e4,60),settleTimeoutMs:h(n.settleTimeoutMs,"Shader settleTimeoutMs",1e3,15*6e4,3e4),browserRelaunchScenes:h(n.browserRelaunchScenes,"Shader browserRelaunchScenes",1,64,8),timeoutMs:l,maxTimeoutMs:Math.max(l,h(n.maxTimeoutMs,"Shader maxTimeoutMs",1e3,15*6e4,l)),viewport:{width:h(a$1(r)?r.width:void 0,"Shader viewport width",64,8192,1024),height:h(a$1(r)?r.height:void 0,"Shader viewport height",64,8192,640)},parity:{frames:h(a$1(e)?e.frames:void 0,"Shader parity frames",0,1e4,90),channelTolerance:h(a$1(e)?e.channelTolerance:void 0,"Shader parity channelTolerance",0,255,8),maxDiffRatio:T(a$1(e)?e.maxDiffRatio:void 0,"Shader parity maxDiffRatio",.01)},bridge:{legacyLab:a$1(t)&&t.legacyLab===true,...typeof a=="string"?{deterministicModule:a}:{}},readiness:{...typeof i=="string"?{selector:i}:{},...typeof f=="string"?{global:f}:{}},publicDir:j(n.publicDir,"Shader publicDir","public"),allowLiveBuilds:n.allowLiveBuilds!==false}}a(y,"parseShaderToolConfig");async function v(n=process.cwd()){let r=c.resolve(n);for(;;){if(await d(c.join(r,S))||await d(c.join(r,"three-blocks.json")))return realpath(r);let e=c.join(r,"package.json");if(await d(e)){let a=await j$1(r,e,a$2.packageJson,"Project package.json"),o;try{o=JSON.parse(a.data.toString("utf8"));}catch{throw new Error(`Project package.json is not valid JSON: ${e}.`)}if(a$1(o)&&[o.dependencies,o.devDependencies,o.peerDependencies,o.optionalDependencies].filter(a$1).some(l=>typeof l.three=="string"||typeof l["three-blocks"]=="string"||typeof l["@three-blocks/devtools"]=="string"))return realpath(r)}let t=c.dirname(r);if(t===r)throw new Error(`No Three Blocks shader project found from ${JSON.stringify(c.resolve(n))}; add Three.js to package.json or pass --root.`);r=t;}}a(v,"findShaderProjectRoot");async function b(n){let r=await realpath(n),e=c.join(r,S);if(await d(e)){let a=await j$1(r,e,a$2.metadata,"Shader configuration");return y(JSON.parse(a.data.toString("utf8")))}let t=c.join(r,"three-blocks.json");if(await d(t)){let a=b$1(JSON.parse(await readFile(t,"utf8"))),o=c.join(r,"src","scenes"),i=[];for(let f of (await readdir(o).catch(()=>[])).sort())await d(c.join(o,f,"scene.ts"))&&i.push(f);return y({schemaVersion:1,backend:"both",scenes:[{key:a.template,url:"/"},...i.map(f=>({key:f,url:`/?scene=${encodeURIComponent(f)}`}))].map(f=>({...f,requiresText:a.features.text}))})}return y(R)}a(b,"loadShaderToolConfig");async function G(n){let r=await realpath(n);for(let o of ["vite.config.ts","vite.config.mts","vite.config.js","vite.config.mjs","vite.config.cts","vite.config.cjs"])if(await d(c.join(r,o)))return {driverKind:"vite",reason:`Detected ${o}.`};let e,t=c.join(r,"package.json");if(await d(t)){let o=await j$1(r,t,a$2.packageJson,"Project package.json"),i=JSON.parse(o.data.toString("utf8"));a$1(i)&&(e=i);}let a$3=a(o=>[e?.dependencies,e?.devDependencies,e?.peerDependencies,e?.optionalDependencies].some(i=>a$1(i)&&typeof i[o]=="string"),"hasDependency");if(a$3("vite"))return {driverKind:"vite",reason:"Detected the Vite dependency."};for(let o of ["dist","build","out"])if(await d(c.join(r,o,"index.html")))return {driverKind:"static",serve:o,reason:`Detected the built ${o}/index.html application.`};if(a$3("next"))throw new Error("Detected Next.js without an attach URL. Run `shaders capture` without an explicit driver or URL to preview the withThreeBlocksNext adapter and start a project-local capture server, or pass --url <local-url> for a server you manage.");if(a$3("webpack")||a$3("esbuild")||a$3("rollup"))throw new Error("Detected a non-Vite bundler but no static index.html. Run `shaders capture` without an explicit driver or URL to preview adapter wiring and build the project, or build it yourself and pass --driver static --serve <directory>.");return {driverKind:"vite",reason:"Using the Vite golden-path driver."}}a(G,"inferShaderCaptureTarget");async function K(n){let r=await realpath(n),e=c.join(r,S);if(await d(e))return {config:await b(r),file:e,created:false};let t=c.join(r,"three-blocks.json");if(await d(t))return {config:await b(r),file:t,created:false};let a=R,o=y(a),i=await g(e,`${JSON.stringify(a,null,2)}
2
+ `);return {config:i?o:await b(r),file:e,created:i}}a(K,"ensureShaderToolConfig");export{S as a,U as b,V as c,z as d,A as e,J as f,B as g,y as h,v as i,b as j,G as k,K as l};
@@ -0,0 +1 @@
1
+ 'use strict';var fs=require('fs'),module$1=require('module'),d=require('path'),vite=require('three-blocks/vite');require('fs/promises'),require('three-blocks/shaders'),require('crypto');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var d__default=/*#__PURE__*/_interopDefault(d);var A=Object.defineProperty;var i=(e,r)=>A(e,"name",{value:r,configurable:true});function m(e){let r=e.split("?",1)[0];return r===void 0?false:r.split(d__default.default.sep).join("/").endsWith("/build/three.webgpu.js")}i(m,"isThreeWebGPUModule");function k(e,r,t={}){if(!vite.isSupportedThreeVersion(r))throw new Error(`The shader provider transform supports Three.js ${vite.THREE_BLOCKS_SUPPORTED_THREE_RANGE}; received "${r}".`);let n=vite.transformThreeWebgpuProviderHooks(e,{threeVersion:r,...t.threeRevision===void 0?{}:{threeRevision:t.threeRevision},id:"three/build/three.webgpu.js"}),o=n.state==="already-applied",a=n.code;return t.instrumentCapture&&(a=vite.transformThreeWebgpuCaptureInstrumentation(a,{...t.captureRuntimeImport===void 0?{}:{runtimeImport:t.captureRuntimeImport},...t.forceWebGL===true?{forceWebGL:true}:{}}).code),{code:a,alreadyPresent:o,captureApplied:t.instrumentCapture===true}}i(k,"applyShaderProviderTransform");var y="@three-blocks/devtools/webpack-loader";function g(e){if(typeof e=="string")return e===y;if(Array.isArray(e))return e.some(g);if(e===null||typeof e!="object")return false;let r=e;return r.loader===y||g(r.use)}i(g,"webpackRuleUsesShaderLoader");function R(e){let r=S(process.cwd()),t=i(o=>j(r,o),"exact"),n={...e.resolve?.alias,...t("three")===void 0?{}:{three$:t("three")},...t("three/webgpu")===void 0?{}:{"three/webgpu$":t("three/webgpu")},...t("three/tsl")===void 0?{}:{"three/tsl$":t("three/tsl")},"three/addons":d__default.default.join(r.root,"examples/jsm"),"three/examples/jsm":d__default.default.join(r.root,"examples/jsm")};return {...e,resolve:{...e.resolve,alias:n}}}i(R,"withTargetThreeAliases");function T(e){let r=R(e),t=r.module?.rules??[];return t.some(g)?r:{...r,module:{...r.module,rules:[...t,{enforce:"pre",test:/three[\\/]build[\\/]three\.webgpu\.js$/u,use:[{loader:y}]}]}}}i(T,"withShaderWebpackRule");function Tr(e){return T(e)}i(Tr,"withThreeBlocksWebpack");function xr(e){let t=e.webpack;return {...e,webpack(n,...o){let a=t?.call(this,n,...o)??n,s=o[0];return s!==null&&typeof s=="object"&&Reflect.get(s,"isServer")===true?R(a):T(a)}}}i(xr,"withThreeBlocksNext");function S(e){let r;try{r=module$1.createRequire(d__default.default.join(d__default.default.resolve(e),"package.json")).resolve("three");}catch(a){throw new Error("The shader adapter could not resolve Three.js from the target project.",{cause:a})}let t=d__default.default.dirname(r),n,o;for(;;){let a=d__default.default.join(t,"package.json");if(fs.existsSync(a)){let c=JSON.parse(fs.readFileSync(a,"utf8"));if(c.name==="three"){n=a,o=c;break}}let s=d__default.default.dirname(t);if(s===t)break;t=s;}if(n===void 0)throw new Error(`The shader adapter could not locate Three.js package metadata from ${r}.`);if(typeof o?.version!="string"||o.version.length===0)throw new Error(`The resolved Three.js package has no version: ${n}`);return {root:d__default.default.dirname(n),version:o.version,exports:o.exports}}i(S,"resolveThreePackage");function U(e=process.cwd()){return S(e).version}i(U,"resolveShaderAdapterThreeVersion");function x(e){return {version:e.threeVersion??U(e.root),capture:e.capture??process.env.THREE_BLOCKS_SHADER_TOOL==="1"}}i(x,"resolvedOptions");var E=false;function b(e,r){return !r.capture&&!vite.isSupportedThreeVersion(r.version)?(E||console.warn(`[three-blocks] Three.js ${r.version} is not a verified revision (${vite.THREE_BLOCKS_SUPPORTED_THREE_RANGE}); shader precompilation is off and scenes compile live.`),E=true,null):k(e,r.version,{instrumentCapture:r.capture})}i(b,"transformVerifiedThree");function jr(e,r,t={}){return m(r)?b(e,x(t)):null}i(jr,"transformThreeWebGPUModule");function h(e){if(typeof e=="string")return e;if(Array.isArray(e)){for(let t of e){let n=h(t);if(n!==void 0)return n}return}if(e===null||typeof e!="object")return;let r=e;for(let t of ["browser","import","default"]){let n=h(r[t]);if(n!==void 0)return n}}i(h,"exportTarget");function j(e,r){if(e.exports===null||typeof e.exports!="object")return;let t=e.exports,n=r==="three"?".":`./${r.slice(6)}`,o=h(t[n]);if(o!==void 0)return d__default.default.resolve(e.root,o);for(let[a,s]of Object.entries(t)){let c=a.indexOf("*");if(c<0)continue;let u=a.slice(0,c),l=a.slice(c+1);if(!n.startsWith(u)||!n.endsWith(l))continue;let p=n.slice(u.length,n.length-l.length),f=h(s);if(f!==void 0)return d__default.default.resolve(e.root,f.replaceAll("*",p))}}i(j,"resolveThreeExport");function Ar(e={}){let r=e.root??process.cwd(),t=S(r),n={version:e.threeVersion??t.version,capture:e.capture??process.env.THREE_BLOCKS_SHADER_TOOL==="1"};return {name:"three-blocks-shader-provider",setup(o){o.onResolve?.({filter:/^three(?:\/.*)?$/},a=>{let s=j(t,a.path);return s===void 0?void 0:{path:s}}),o.onLoad({filter:/three[\\/]build[\\/]three\.webgpu\.js$/},async a=>{let s=await new Promise((u,l)=>{fs.readFile(a.path,"utf8",(p,f)=>{p?l(p):u(f);});}),c=b(s,n);return c===null?void 0:{contents:c.code,loader:"js"}});}}}i(Ar,"createEsbuildShaderPlugin");function Pr(e={}){let r=x(e);return {name:"three-blocks-shader-provider",enforce:"pre",transform(t,n){if(!m(n))return null;let o=b(t,r);return o===null?null:{code:o.code,map:null}}}}i(Pr,"createRollupShaderPlugin");exports.a=i;exports.b=y;exports.c=Tr;exports.d=xr;exports.e=U;exports.f=jr;exports.g=Ar;exports.h=Pr;
@@ -0,0 +1,78 @@
1
+ import {b as b$1}from'./chunk-ZG3LO3VB.js';import {f,g,c}from'./chunk-WWBW6MPB.js';import {a as a$3,b,f as f$1}from'./chunk-UDMY6S4M.js';import {a as a$2}from'./chunk-WNSGAV6N.js';import {a,k,j as j$1,e,d}from'./chunk-ECQE4D2U.js';import {a as a$1}from'./chunk-7X4DHW36.js';import A from'process';import {createServer}from'http';import {createRequire}from'module';import {lstat,realpath}from'fs/promises';import j from'path';import {pathToFileURL}from'url';var X="three-blocks.shader-capture.runtime.v1";var we="/__three-blocks/shaders/capture",J="/__three-blocks/shaders/telemetry",ge=a.manifest*2,ee=/^[a-z0-9][a-z0-9_-]{0,63}$/u,be=64,Se=3e4;async function Le(n){let e;try{e=createRequire(j.join(n,"package.json")).resolve("vite");}catch(r){throw new Error("Shader capture requires Vite in the target project.",{cause:r})}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$1(Le,"loadProjectCreateServer");var te=class{static{a$1(this,"CaptureInbox");}#e=new Map;#t=new Map;wait(e,t){let r=this.#t.get(e);if(r!==void 0)return this.#t.delete(e),Promise.resolve(r);if(this.#e.has(e))throw new Error(`A shader capture is already waiting for scene "${e}".`);return new Promise((a,s)=>{let o=setTimeout(()=>{this.#e.delete(e),s(new Error(`Shader capture "${e}" timed out after ${t}ms.`));},t);this.#e.set(e,{resolve:a,reject:s,timer:o});})}receive(e){if(!a$2(e)||typeof e.scene!="string"||!ee.test(e.scene))throw new Error("Capture POST has no safe scene key.");if(!this.#t.has(e.scene)&&!this.#e.has(e.scene)&&this.#t.size>=be)throw new Error("Capture POST exceeds the scene inbox limit.");let t=this.#e.get(e.scene);t?(clearTimeout(t.timer),this.#e.delete(e.scene),t.resolve(e)):this.#t.set(e.scene,e);}cancel(e,t){let r=this.#e.get(e);r&&(clearTimeout(r.timer),this.#e.delete(e),r.reject(t));}rejectAll(e){for(let t of this.#e.values())clearTimeout(t.timer),t.reject(e);this.#e.clear(),this.#t.clear();}};async function De(n,e){let t=await Promise.race([e.then(r=>({kind:"capture",value:r})),n.then(()=>({kind:"navigation"}))]);return t.kind==="capture"?t.value:e}a$1(De,"waitForShaderCaptureAcrossNavigation");var re=class{static{a$1(this,"TelemetryHub");}#e=new Map;#t=new Map;markFirstRequest(e){ee.test(e)&&!this.#t.has(e)&&this.#t.set(e,Date.now());}firstRequest(e){return this.#t.get(e)}receive(e){if(!a$2(e)||typeof e.scene!="string"||!ee.test(e.scene))throw new Error("Shader telemetry has no bounded scene key.");if(!this.#e.has(e.scene)&&this.#e.size>=be)throw new Error("Shader telemetry exceeds the scene limit.");this.#e.set(e.scene,e);}read(e){return this.#e.get(e)}clear(e){this.#e.delete(e),this.#t.delete(e);}},$e=a$1(async(n,e,t,r,a)=>{let s=0;for(;n.__threeBlocksParityUsesAnimationLoop!==true&&s<e;)await r(),s+=1;if(n.__threeBlocksParityUsesAnimationLoop===true){let o=Number(n.__threeBlocksParityCompletedFrame||0),d=Number(t),l=Number.isSafeInteger(d)&&d>=o?d:o+e;for(n.__threeBlocksParityTargetFrame=l;Number(n.__threeBlocksParityCompletedFrame||0)<l;)await r();}return await a(),Number(n.__threeBlocksParityCompletedFrame||0)},"settleShaderParityFrames");function ve(n,e){return `(() => {
2
+ const root = globalThis;
3
+ const scene = new URL(location.href).searchParams.get('captureId')
4
+ || 'default';
5
+ const workerCapture = ${JSON.stringify(e??null).replaceAll("<","\\u003c")};
6
+ if (workerCapture) root[Symbol.for('three-blocks.shader-capture.worker-activation.v1')] = { ...workerCapture, scene };
7
+ const randomSeed = (value) => {
8
+ let state = 2166136261;
9
+ for (let index = 0; index < value.length; index++) state = Math.imul(state ^ value.charCodeAt(index), 16777619) >>> 0;
10
+ return state === 0 ? 0x9e3779b9 : state;
11
+ };
12
+ const advanceRandom = (state) => {
13
+ state ^= state << 13;
14
+ state ^= state >>> 17;
15
+ state ^= state << 5;
16
+ return state >>> 0;
17
+ };
18
+ const parityMode = new URL(location.href).searchParams.get('threeBlocksShaderMode');
19
+ if (parityMode === 'live' || parityMode === 'precompiled') {
20
+ root.__threeBlocksParityEpoch = 1700000000000;
21
+ root.__threeBlocksParityTime = 0;
22
+ Date.now = () => root.__threeBlocksParityEpoch + Number(root.__threeBlocksParityTime || 0);
23
+ }
24
+ const randomStreams = new Map();
25
+ Math.random = () => {
26
+ const stackLine = String(new Error().stack || '').split('\\n')[2] || 'unknown';
27
+ const originIndex = stackLine.indexOf(location.origin);
28
+ const callsite = (originIndex >= 0 ? stackLine.slice(0, originIndex) : stackLine).trim() || 'anonymous';
29
+ const next = advanceRandom(randomStreams.get(callsite) ?? randomSeed(scene + '|' + callsite));
30
+ randomStreams.set(callsite, next);
31
+ return next / 4294967296;
32
+ };
33
+ const readiness = { workerReady: false, assetsReady: false, textReady: false, compileEnd: false, firstFrame: false };
34
+ const stats = { buildCalls: 0, renderBuilds: 0, computeBuilds: 0, registeredBuilds: 0, registeredRenderBuilds: 0, registeredComputeBuilds: 0, buildMs: 0, 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: [] };
35
+ const settleParityFrames = ${$e.toString()};
36
+ const settle = (frames, requestedTarget) => settleParityFrames(
37
+ root,
38
+ frames,
39
+ requestedTarget,
40
+ () => new Promise((resolve) => requestAnimationFrame(resolve)),
41
+ () => new Promise((resolve) => setTimeout(resolve, 100)),
42
+ );
43
+ const bridge = { protocolVersion: 1, compatibility: ${JSON.stringify(n)}, transform: ${b}, readiness, stats, settle };
44
+ root.__threeBlocksShaderTools = bridge;
45
+ requestAnimationFrame(() => requestAnimationFrame(() => { readiness.firstFrame = true; }));
46
+ const poll = async () => {
47
+ try {
48
+ const response = await fetch('/__three-blocks/shaders/telemetry?scene=' + encodeURIComponent(scene), { cache: 'no-store' });
49
+ if (response.status !== 204 && response.ok) {
50
+ const payload = await response.json();
51
+ if (payload.protocolVersion !== 1 || payload.compatibility !== bridge.compatibility || payload.transform !== bridge.transform) throw new Error('incompatible shader telemetry');
52
+ Object.assign(stats, payload.stats);
53
+ if (Array.isArray(payload.demands)) bridge.demands = payload.demands;
54
+ if (typeof payload.demandTotal === 'number') bridge.demandTotal = payload.demandTotal;
55
+ readiness.workerReady = true;
56
+ if (payload.settled === true) {
57
+ readiness.assetsReady = true;
58
+ readiness.textReady = true;
59
+ readiness.compileEnd = true;
60
+ }
61
+ const smoke = root.__threeBlocksSmoke && typeof root.__threeBlocksSmoke === 'object' ? root.__threeBlocksSmoke : { protocolVersion: 1, worker: { offscreenCanvas: true, visible: true }, readiness: {} };
62
+ smoke.readiness = { ...(smoke.readiness || {}), ...readiness };
63
+ root.__threeBlocksSmoke = smoke;
64
+ }
65
+ } catch {}
66
+ setTimeout(poll, 40);
67
+ };
68
+ void poll();
69
+ })();`}a$1(ve,"publicBridgeScript");function ke(n,e,t,r,a=false){let s=new URL(n.url??"/","http://three-blocks.invalid"),o=s.pathname;if(a&&n.method==="GET"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.(?:webgpu|webgl)\.json$/u.test(o))return e.statusCode=204,e.end(),true;if(o===J&&n.method==="GET"){let u=s.searchParams.get("scene")??"",p=r.read(u);return p===void 0?(e.statusCode=204,e.end()):(e.statusCode=200,e.setHeader("Content-Type","application/json"),e.end(JSON.stringify(p))),true}let d=o===we,l=o===J;if(!d&&!l)return false;if(n.method!=="POST")return e.statusCode=405,e.end("POST required"),true;let i=[],m=0,c=false;return n.on("data",u=>{m+=u.byteLength,m>ge?c=true:i.push(u);}),n.on("end",()=>{if(c){e.statusCode=413,e.end("capture payload too large");return}try{let u=JSON.parse(Buffer.concat(i).toString("utf8"));l?r.receive(u):t.receive(u),e.statusCode=204,e.end();}catch(u){e.statusCode=400,e.end(u instanceof Error?u.message:String(u));}}),true}a$1(ke,"handleCaptureEndpoint");function Ne(n,e,t,r,a){return {name:"three-blocks:shader-capture-endpoint",transformIndexHtml(){return [{tag:"script",children:ve(r,a),injectTo:"head-prepend"}]},configureServer(s){s.middlewares.use((o,d,l)=>{let m=new URL(o.url??"/","http://three-blocks.invalid").searchParams.get("captureId");m!==null&&e.markFirstRequest(m),!ke(o,d,n,e,t)&&l();});}}}a$1(Ne,"captureEndpointPlugin");function me(n,e,t){let r=new URL(e.url,n);for(let[a,s]of Object.entries(t))r.searchParams.set(a,s);return r.href}a$1(me,"browserUrl");function Ue(n,e,t){let r=new URL(e.url,n);for(let a of ["capture","precompiled"])r.searchParams.delete(a);return r.searchParams.set("captureId",e.key),r.searchParams.set("threeBlocksShaderCapture","1"),r.searchParams.set("threeBlocksShaderMode","precompiled"),t==="webgl"&&r.searchParams.set("webgl","1"),r.searchParams.set("tbStats","1"),r.href}a$1(Ue,"publishedBrowserUrl");async function M(n){let e;try{await Promise.race([n(),new Promise(t=>{e=setTimeout(t,Se);})]);}catch{}finally{e&&clearTimeout(e);}}a$1(M,"closeBrowserResource");async function G(n){let e;try{return await Promise.race([n().catch(()=>null),new Promise(t=>{e=setTimeout(()=>t(null),Se);})])}finally{e!==void 0&&clearTimeout(e);}}a$1(G,"readPageDiagnostic");function Q(n){let e=a$1(()=>{},"resolveFirst"),t=new Promise(i=>{e=i;}),r=a$1(()=>{},"removeBrowserListener"),a={console:[],page:[],first:t,dispose:a$1(()=>r(),"dispose")},s=false,o=a$1(i=>{s||(s=true,e(new Error(i)));},"report"),d=n.context().browser(),l=a$1(()=>o("Shader browser disconnected before observation completed."),"onDisconnected");return d?.on("disconnected",l),r=a$1(()=>{d?.off("disconnected",l);},"removeBrowserListener"),n.on("console",i=>{let m=i.type()==="warning"&&/\[three-blocks\/shaders\].*(?:has no entry|manifest miss|hydration)/iu.test(i.text());if(i.type()!=="error"&&!m||b$1(i.text()))return;let c=i.location().url,u=c.length>0?`${i.text()} (${c})`:i.text();a.console.push(u),o(`Browser console ${m?"warning":"error"}: ${u}`);}),n.on("pageerror",i=>{if(b$1(i.message))return;let m=i.stack||i.message;a.page.push(m),o(`Browser page error: ${m}`);}),n.on("crash",()=>o("Browser page crashed before shader capture completed.")),n.on("close",()=>o("Browser page closed before shader capture completed.")),a}a$1(Q,"collectErrors");function L(n,e,t=false){return typeof n[e]=="boolean"?n[e]:t}a$1(L,"booleanField");function Ie(n){if(!a$2(n))throw new Error("Browser shader stats are unavailable.");let e=a$1((t,r=true)=>{let a=n[t];if(typeof a!="number"||!Number.isFinite(a)||a<0||r&&!Number.isSafeInteger(a))throw new Error(`Browser shader stats.${t} is invalid.`);return a},"read");return {buildCalls:e("buildCalls"),renderBuilds:e("renderBuilds"),computeBuilds:e("computeBuilds"),registeredBuilds:e("registeredBuilds"),registeredRenderBuilds:e("registeredRenderBuilds"),registeredComputeBuilds:e("registeredComputeBuilds"),buildMs:e("buildMs",false),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(n.missedKeys)&&n.missedKeys.every(t=>typeof t=="string")?{missedKeys:n.missedKeys}:{},...f$1(n)}}a$1(Ie,"parseStats");function H(n,e,t,r,a){if(!a$2(n))throw new Error("The page did not expose the public shader devtools bridge.");if(!t&&n.protocolVersion!==1)throw new Error(`Scene "${e.key}" exposed an unsupported shader bridge protocol.`);let s=n.readiness;if(!a$2(s))throw new Error("The shader bridge readiness snapshot is invalid.");let o={workerReady:L(s,"workerReady"),assetsReady:L(s,"assetsReady"),textReady:e.requiresText?L(s,"textReady"):true,compileEnd:L(s,"compileEnd"),firstFrame:L(s,"firstFrame",t)};if(!o.workerReady||!o.assetsReady||!o.textReady||!o.compileEnd)throw new Error(`Scene "${e.key}" did not reach worker/assets/text/compile readiness.`);let d=t?a:n.compatibility,l=t?b:n.transform;if(d!==a||l!==b)throw new Error(`Scene "${e.key}" exposed incompatible shader bridge metadata.`);g(r);let i=Array.isArray(n.demands)?n.demands.filter(a$2).slice(0,64):void 0;return {compatibility:a,transform:l,readiness:o,stats:Ie(n.stats),...i===void 0?{}:{demands:i}}}a$1(H,"parseBridge");async function V(n,e){return n.evaluate(t=>{let r=globalThis;if(!t)return r.__threeBlocksShaderTools??null;let a=r.__threeBlocks,s=r.__threeBlocksTslStats;if(!a||typeof a!="object")return null;let o=a;return {readiness:{workerReady:o.workerReady===true,assetsReady:o.loadEnd===true||o.assetsReady===true,textReady:o.textReady===true,compileEnd:o.compileEnd===true,firstFrame:true},stats:s}},e)}a$1(V,"readBridge");async function Re(n,e){let t=await G(()=>n.evaluate(r=>{let a=globalThis,s=a$1(d=>{let l=a;for(let i of d.split(".")){if(l===null||typeof l!="object"&&typeof l!="function")return;l=Reflect.get(l,i);}return l},"resolveGlobal"),o=null;if(r!==null)try{o=JSON.stringify(s(`${r}Diagnostics`))??null;}catch{o=null;}return JSON.stringify({parityCompletedFrame:Number(a.__threeBlocksParityCompletedFrame??0),diagnostics:o})},e??null));return t===null?{alive:false,signature:""}:{alive:true,signature:t}}a$1(Re,"probePageProgress");async function D(n,e,t,r){let a=n.evaluate(async i=>{let c=globalThis.__threeBlocksShaderTools;if(c&&typeof c=="object"){let g=Reflect.get(c,"settle");if(typeof g=="function"){let S=await g(i.frames,i.targetFrame);return typeof S=="number"&&Number.isSafeInteger(S)?S:0}}if(!i.legacy||!i.modulePath)throw new Error("The public shader bridge does not provide deterministic settle().");let u=await import(i.modulePath);if(!u.store||typeof u.store!="object")throw new Error("Legacy deterministic store is unavailable.");let p=u.store;return p.recordFrameCount=0,p.recordFrameRate=60,p.recordTotalFrames=i.frames,p.recording=true,await new Promise((g,S)=>{let b=Date.now(),f=a$1(()=>{if(p.recording===false)return g();if(Date.now()-b>i.timeoutMs)return S(new Error("Legacy deterministic settle timed out."));setTimeout(f,25);},"poll");f();}),0},{frames:t,targetFrame:r,legacy:e.bridge.legacyLab,modulePath:e.bridge.deterministicModule??null,timeoutMs:e.timeoutMs}),s=F(e),o=false,d,l=(async()=>{let i=Date.now(),m=i,c="";for(;;){let u=s-(Date.now()-i);if(u<=0)throw new Error(`Shader parity settle timed out after ${s}ms.`);let p=e.timeoutMs-(Date.now()-m);if(p<=0){let g=await Re(n,e.readiness.global);if(o)throw new Error("Shader parity settle already resolved.");if(g.alive&&g.signature===c)throw new Error(`Shader parity settle timed out after ${e.timeoutMs}ms without progress (hard cap ${s}ms).`);c=g.signature,m=Date.now();continue}if(await new Promise(g=>{d=setTimeout(g,Math.min(p,u,2500));}),o)throw new Error("Shader parity settle already resolved.")}})();try{return await Promise.race([a,l])}finally{o=true,d!==void 0&&clearTimeout(d),l.catch(()=>{});}}a$1(D,"settlePage");async function fe(n,e,t){e.readiness.selector===void 0&&e.readiness.global===void 0||await Promise.race([n.waitForFunction(r=>{let a=globalThis;if(r.selector!==void 0&&a.document?.querySelector(r.selector)==null)return false;if(r.global===void 0)return true;let s=a;for(let l of r.global.split(".")){if((typeof s!="object"||s===null)&&typeof s!="function")return false;s=Reflect.get(s,l);}if(s===true)return true;if(typeof s!="object"||s===null||typeof Reflect.get(s,"then")!="function")return false;let o=a.__threeBlocksReadinessState,d=o instanceof Map?o:new Map;return o instanceof Map||(a.__threeBlocksReadinessState=d),d.has(s)||(d.set(s,false),Promise.resolve(s).then(()=>d.set(s,true),()=>d.set(s,false))),d.get(s)===true},e.readiness,{timeout:F(e)}),t.first.then(r=>Promise.reject(r))]);}a$1(fe,"waitForConfiguredReadiness");async function pe(n){let e=n.locator("canvas"),r=(await e.evaluateAll(a=>a.map((s,o)=>{let d=s.getBoundingClientRect();return {index:o,area:Math.max(0,d.width)*Math.max(0,d.height)}}))).sort((a,s)=>s.area-a.area)[0];if(r===void 0||r.area<=0)throw new Error("Published page has no visible renderer canvas.");return Buffer.from(await e.nth(r.index).screenshot({type:"png"}))}a$1(pe,"primaryCanvasScreenshot");async function Z(n,e,t,r,a,s,o){let d=Te(r,a,s),l=await c(),i=`(() => {
70
+ const runtime = globalThis[Symbol.for(${JSON.stringify(X)})];
71
+ if (!runtime || typeof runtime.configureThreeBlocksShaderCapture !== 'function') {
72
+ throw new Error('@three-blocks/devtools attached shader capture runtime is incompatible.');
73
+ }
74
+ runtime.configureThreeBlocksShaderCapture(${JSON.stringify(d).replaceAll("<","\\u003c")});
75
+ })();`;await n.addInitScript({content:l,workers:true}),await n.addInitScript({content:i}),await n.addInitScript({content:ve(o,d)}),await n.route("**/*",async m=>{let c=m.request(),u=new URL(c.url()),p=u.pathname;if(c.method()==="GET"&&r!=="precompiled"&&/^\/three-blocks\/shaders\/[a-z0-9][a-z0-9_-]{0,63}\.(?:webgpu|webgl)\.json$/u.test(p)){await m.fulfill({status:204});return}if(p===J&&c.method()==="GET"){let b=t.read(u.searchParams.get("scene")??"");await m.fulfill(b===void 0?{status:204}:{status:200,contentType:"application/json",body:JSON.stringify(b)});return}let g=p===we,S=p===J;if((g||S)&&c.method()==="POST"){let b=c.postDataBuffer()??Buffer.alloc(0);if(b.byteLength>ge){await m.fulfill({status:413,body:"capture payload too large"});return}try{let f=JSON.parse(b.toString("utf8"));S?t.receive(f):e.receive(f),await m.fulfill({status:204});}catch(f){await m.fulfill({status:400,body:f instanceof Error?f.message:String(f)});}return}await m.continue();});}a$1(Z,"configureAttachedContext");var He=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"}),Ve=5e3;function F(n){return Math.max(n.maxTimeoutMs??n.timeoutMs,n.timeoutMs)}a$1(F,"configuredHardCapMs");function Te(n,e,t){return {capture:n==="capture",backend:t,driven:true,forceLive:n!=="precompiled",settleFrames:e.settleFrames,settleTimeoutMs:e.settleTimeoutMs??3e4,...n==="capture"?{deadlineAt:Date.now()+Math.max(1e3,F(e)-Ve)}:{},readiness:e.readiness,transform:b}}a$1(Te,"shaderCaptureConfiguration");async function Ge(n){let e=n,t=await k(e,n,o=>/\.(?:c|m)?js$/u.test(o),16384),r=false,a$1=false,s;for(let o of t){let d=(await j$1(e,o,a.texture,"Static application JavaScript")).data.toString("utf8");if(d.includes("nodeBuilderStateProvider")&&(r=true),d.includes("three-blocks.shader-capture.runtime.v1")&&(a$1=true,s??=o),r&&a$1)break}if(!r||!a$1)throw new Error(`The static build cannot be captured: ${t.length} JavaScript file${t.length===1?"":"s"} under "${n}" ${r?"contain":"lack"} the Three.js shader provider hook and ${a$1?"contain":"lack"} the three-blocks shader runtime. 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$1(Ge,"inspectStaticCaptureTransform");async function Je(n,e$1){let t;try{t=decodeURIComponent(e$1);}catch{return}if(t.includes("\0"))return;let r=t.replace(/^\/+/u,""),a$1=j.resolve(n,r.length===0?"index.html":r);if(!e(n,a$1)||a$1===n||(await d(a$1)&&(await lstat(a$1)).isDirectory()&&(a$1=j.join(a$1,"index.html")),!await d(a$1)&&j.extname(a$1).length===0&&(a$1=j.join(n,"index.html")),!await d(a$1)))return;let s=await j$1(n,a$1,a.texture,"Static application asset");return {data:s.data,file:s.path}}a$1(Je,"staticRequestFile");async function We(n,e$1,t,r){let a=await realpath(n.root),s=await realpath(j.resolve(a,n.serve));if(s===a||!j.isAbsolute(n.serve)&&!e(a,s))throw new Error("--serve must name a built application directory inside the project root.");let o=await Ge(s),d=n.base?.startsWith("/")===true?n.base.replace(/\/+$/u,""):"",l=createServer((m,c)=>{(async()=>{if(ke(m,c,t,r,e$1!=="precompiled"))return;let u=new URL(m.url??"/","http://three-blocks.invalid");if(m.method!=="GET"&&m.method!=="HEAD"){c.statusCode=405,c.end("GET or HEAD required");return}let p=await Je(s,d.length>0&&u.pathname.startsWith(`${d}/`)?u.pathname.slice(d.length):u.pathname);if(p===void 0){c.statusCode=404,c.end("Not found");return}let g=j.extname(p.file).toLowerCase(),S=p.data;c.statusCode=200,c.setHeader("Content-Type",He[g]??"application/octet-stream"),c.setHeader("Content-Length",String(S.byteLength)),c.setHeader("Cache-Control","no-store"),c.end(m.method==="HEAD"?void 0:S);})().catch(u=>{if(c.headersSent)return c.destroy(u instanceof Error?u:void 0);c.statusCode=500,c.end(u instanceof Error?u.message:String(u));});});await new Promise((m,c)=>{l.once("error",c),l.listen(0,"127.0.0.1",()=>{l.off("error",c),m();});});let i=l.address();if(!i||typeof i=="string")throw new Error("Static capture server did not expose an ephemeral TCP address.");return {server:l,baseUrl:`http://127.0.0.1:${i.port}`,transform:o}}a$1(We,"startStaticShaderServer");function qe(n,e,t){return n===e?true:t&&n!==void 0&&n!=="capture"&&e!=="capture"}a$1(qe,"canReuseShaderBrowserSession");function ye(n){let e=n instanceof Error?n.message:String(n);return e.includes("Execution context was destroyed")&&e.includes("navigation")||/^launch: Timeout \d+ms exceeded\./u.test(e)||e.includes("Shader browser disconnected before observation completed.")}a$1(ye,"isRetryableShaderObservationNavigation");var ne=["THREE_BLOCKS_SHADER_TOOL","THREE_BLOCKS_PRECOMPILE_CAPTURE_SERVER"],Ee=0,Pe=[];function Ke(){if(!(Ee++>0)){Pe=ne.map(n=>A.env[n]);for(let n of ne)A.env[n]="1";}}a$1(Ke,"holdShaderToolEnvironment");function ze(){if(!(--Ee>0))for(let[n,e]of ne.entries()){let t=Pe[n];t===void 0?delete A.env[e]:A.env[e]=t;}}a$1(ze,"releaseShaderToolEnvironment");var ae=class{static{a$1(this,"NodeShaderDriver");}#e;#t=new te;#n=new re;#u;#h;#s;#i;#r;#a;#y=false;#l;#m;#f;#c=0;constructor(e){this.#e=e;}#d(){return this.#u?.status??this.#h??{seen:false,applied:false,alreadyPresent:false}}async#p(e,t){if(this.#r?.isConnected()===true)return;let{launchNodeRenderer:r}=await import('@three-blocks/devtools/node');this.#r=await r(),this.#c=0;}async#o(e,t,r){let a;try{return await Promise.race([r(),new Promise((s,o)=>{a=setTimeout(()=>o(new Error(`launch: Timeout ${t.timeoutMs}ms exceeded.`)),t.timeoutMs);})])}catch(s){throw this.#r===e&&(this.#r=void 0),await M(()=>e.close()),s}finally{a!==void 0&&clearTimeout(a);}}async#w(e,t,r){let a=this.#s!==void 0||this.#i!==void 0||this.#e.url!==void 0&&this.#a!==void 0,s=this.#m===t&&(this.#i!==void 0?this.#l===e:qe(this.#l,e,r.bridge.legacyLab));if(a&&s){this.#l=e,await this.#p(r,t);return}if(a&&await this.close(),this.#l=e,this.#m=t,this.#e.url!==void 0){let o=new URL(this.#e.url);if(!["http:","https:"].includes(o.protocol)||o.username||o.password||o.hash)throw new Error("Attached shader URL must be an HTTP(S) URL without credentials or a fragment.");this.#a=o.href,this.#h={seen:true,applied:true,alreadyPresent:false,captureApplied:true,id:"attached-application"},await this.#p(r,t);return}if(this.#e.serve!==void 0)try{let o=await We({root:this.#e.root,runtime:this.#e.runtime,serve:this.#e.serve,...this.#e.base===void 0?{}:{base:this.#e.base},...this.#e.headed===void 0?{}:{headed:this.#e.headed}},e,this.#t,this.#n);this.#i=o.server,this.#h=o.transform,this.#a=o.baseUrl,await this.#p(r,t);return}catch(o){throw await this.close(),o}this.#u=f(this.#e.runtime.three,{disableTimestampQueries:A.env.THREE_BLOCKS_SOFTWARE_WEBGPU==="1",...r.bridge.legacyLab?{}:{capture:{capture:e==="capture",driven:true,forceLive:e!=="precompiled",forceWebGL:t==="webgl",settleFrames:r.settleFrames,settleTimeoutMs:r.settleTimeoutMs??3e4,readiness:r.readiness}}}),Ke(),this.#y=true;try{let o=await Le(this.#e.root);this.#s=await o({root:this.#e.root,logLevel:"error",plugins:[this.#u.plugin,Ne(this.#t,this.#n,e!=="precompiled",a$3(this.#e.runtime.three,t),Te(e,r,t))],server:{host:"127.0.0.1",port:0}}),await this.#s.listen();let d=this.#s.httpServer?.address();if(!d||typeof d=="string")throw new Error("Vite did not expose an ephemeral TCP address.");this.#a=`http://127.0.0.1:${d.port}`,await this.#p(r,t);}catch(o){throw await this.close(),o}}async capture(e,t,r="webgpu"){let a=Date.now();if(await this.#w("capture",r,t),!this.#r||!this.#a)throw new Error("Shader browser driver did not start.");let s=this.#r,o=await this.#o(s,t,()=>s.newContext({viewport:t.viewport,frameIntervalMs:1e3/60}));(this.#e.url!==void 0||this.#e.serve!==void 0)&&await this.#o(s,t,()=>Z(o,this.#t,this.#n,"capture",t,r,a$3(this.#e.runtime.three,r)));let d=await this.#o(s,t,()=>o.newPage()),l=Q(d);this.#n.clear(e.key);let i=F(t),m=this.#t.wait(e.key,i),c=false;i>t.timeoutMs?(async()=>{let f=Math.min(5e3,Math.max(1e3,Math.round(t.timeoutMs/8))),y=Date.now(),v="",w="";for(;!c;){if(await new Promise(E=>setTimeout(E,f)),c)return;let P=this.#n.read(e.key),R=P===void 0?"":JSON.stringify(P);if(R!==v){v=R,y=Date.now();continue}if(Date.now()-y<t.timeoutMs)continue;let T=await Re(d,t.readiness.global);if(c)return;if(!T.alive||T.signature!==w){w=T.signature,y=Date.now();continue}this.#t.cancel(e.key,new Error(`Shader capture "${e.key}" timed out after ${t.timeoutMs}ms without progress (hard cap ${i}ms).`));return}})().catch(()=>{}):void 0;let p=Promise.race([m,l.first.then(f=>Promise.reject(f))]),g$1=a$1(()=>{},"resolveDisconnected"),S=new Promise(f=>{g$1=f;}),b=a$1(()=>g$1(new Error("Shader capture browser disconnected before posting a manifest.")),"onDisconnected");s.on("disconnected",b);try{let f=d.goto(me(this.#a,e,{threeBlocksShaderCapture:"1",capture:"1",captureId:e.key,captureFrames:String(Math.max(4,t.settleFrames)),settleFrames:String(t.settleFrames),...r==="webgl"?{webgl:"1"}:{}}),{waitUntil:"domcontentloaded",timeout:t.timeoutMs}),y=await De(f,Promise.race([p,S.then(w=>Promise.reject(w))]));g(this.#d());let v=[...l.page,...l.console];if(v.length>0)throw new Error(`Capture browser errors:
76
+ - ${v.join(`
77
+ - `)}`);return a$2(y)?{...y,timing:{...a$2(y.timing)?y.timing:{},launch:a,...this.#n.firstRequest(e.key)===void 0?{}:{firstRequest:this.#n.firstRequest(e.key)},posted:Date.now()}}:y}catch(f){let y=f instanceof Error?f:new Error(String(f));this.#t.cancel(e.key,y),await m.catch(()=>{});let v=this.#n.read(e.key);if(y.message.includes("timed out")){let w=await G(()=>d.evaluate(T=>{let E=globalThis,$=E.__threeBlocksShaderTools,Ce=$&&typeof $=="object"?$:void 0,Be=E.document,x=Reflect.get(E,Symbol.for("three-blocks.shader-capture.cache-value.v1")),N=E.location,_e=N!==null&&typeof N=="object"&&typeof Reflect.get(N,"href")=="string"?String(Reflect.get(N,"href")):"http://three-blocks.invalid/",xe=new URL(_e).searchParams.get("captureId")??"default",oe=x!==null&&typeof x=="object"&&typeof Reflect.get(x,"registrations")=="function"?Reflect.apply(Reflect.get(x,"registrations"),x,[xe]):void 0,se=a$1(k=>{let B=E;for(let Me of k.split(".")){if(B===null||typeof B!="object"&&typeof B!="function")return;B=Reflect.get(B,Me);}return B},"resolveGlobal"),ie=null,W=null;if(T!==null){let k=se(T);ie=k===true||k===false?k:k===void 0?"absent":k!==null&&typeof k.then=="function"?"promise":typeof k;try{let B=JSON.stringify(se(`${T}Diagnostics`));W=typeof B=="string"?B.slice(0,2048):null;}catch{W=null;}}return {documentReadyState:Be?.readyState??null,parityTargetFrame:Number(E.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(E.__threeBlocksParityCompletedFrame??0),readiness:Ce?.readiness??null,readinessGlobal:ie,readinessDiagnostics:W,captureCache:x!==null&&typeof x=="object"?{activeScene:Reflect.get(x,"activeScene")??null,registrations:Array.isArray(oe)?oe.slice(0,16).map(k=>k!==null&&typeof k=="object"?{key:Reflect.get(k,"key")??null,kind:Reflect.get(k,"kind")??null}:null):null}:null,threeRuntimeResources:performance.getEntriesByType("resource").map(k=>k.name).filter(k=>k.includes("three.webgpu"))}},t.readiness.global??null)),P=t.readiness.global!==void 0&&w!==null&&w.readinessGlobal!==true,R=w===null?"Capture page did not answer diagnostics before the deadline; its main thread was blocked or gone. ":P?`Application readiness "${t.readiness.global}" never completed (state: ${JSON.stringify(w.readinessGlobal)}${w.readinessDiagnostics===null?"":`, diagnostics: ${w.readinessDiagnostics}`}). `:"";throw new Error(`${R}${y.message} Last capture state for "${e.key}": ${JSON.stringify({page:w,telemetry:v??null,transform:this.#d()})}`)}throw y}finally{c=true,l.dispose(),s.off("disconnected",b),await M(()=>o.close()),this.#c++,(!s.isConnected()||this.#c>=(t.browserRelaunchScenes??8))&&(this.#r===s&&(this.#r=void 0),await M(()=>s.close()),this.#c=0);}}async observe(e,t,r,a,s="webgpu",o=false){for(let d=0;d<2;d++)try{return await this.#g(e,s,t,r,a,o&&t==="precompiled")}catch(l){if(d===0&&ye(l))continue;throw l}throw new Error(`Shader observation retry was exhausted for scene "${e.key}".`)}async#g(e,t,r,a,s,o=false){if(await this.#w(r,t,a),!this.#r||!this.#a)throw new Error("Shader browser driver did not start.");let d=this.#r,l=await this.#o(d,a,()=>d.newContext({viewport:a.viewport}));(this.#e.url!==void 0||this.#e.serve!==void 0)&&await this.#o(d,a,()=>Z(l,this.#t,this.#n,r,a,t,a$3(this.#e.runtime.three,t)));let i=await this.#o(d,a,()=>l.newPage()),m=Q(i);this.#n.clear(e.key);try{await i.goto(me(this.#a,e,{threeBlocksShaderCapture:"1",threeBlocksShaderMode:r,tbOverlay:"0",captureId:e.key,...o?{threeBlocksShaderOracle:"1"}:{},...t==="webgl"?{webgl:"1"}:{}}),{waitUntil:"domcontentloaded",timeout:a.timeoutMs}),await Promise.race([i.waitForFunction(a.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:F(a)}),m.first.then(b=>Promise.reject(b))]),H(await V(i,a.bridge.legacyLab),e,a.bridge.legacyLab,this.#d(),a$3(this.#e.runtime.three,t)),await fe(i,a,m),await Promise.race([i.waitForFunction(a.bridge.legacyLab?"true":"globalThis.__threeBlocksShaderTools?.readiness?.firstFrame === true",void 0,{timeout:F(a)}),m.first.then(b=>Promise.reject(b))]),await D(i,a,1);let c=Buffer.from(await i.screenshot({type:"png",timeout:a.timeoutMs})),u=e.parityFrames??a.parity.frames,p=await D(i,a,u,s),g=Buffer.from(await i.screenshot({type:"png",timeout:a.timeoutMs}));e.parityFrames!==void 0&&u<a.parity.frames&&await D(i,a,a.parity.frames-u);let S=H(await V(i,a.bridge.legacyLab),e,a.bridge.legacyLab,this.#d(),a$3(this.#e.runtime.three,t));return this.#f===void 0&&(this.#f=await i.evaluate(async b=>{if(b==="webgl"){let T=Reflect.get(globalThis,"document").createElement("canvas").getContext("webgl2"),E=T?.getExtension("WEBGL_debug_renderer_info");return {adapter:T&&E?String(T.getParameter(E.UNMASKED_RENDERER_WEBGL)):"WebGL adapter",platform:navigator.platform||navigator.userAgent}}let f=Reflect.get(navigator,"gpu"),y=typeof f=="object"&&f!==null?Reflect.get(f,"requestAdapter"):void 0,v=typeof y=="function"?await Reflect.apply(y,f,[]):void 0,w=typeof v=="object"&&v!==null?Reflect.get(v,"info"):void 0,P=["description","device","architecture","vendor"].flatMap(R=>{let T=typeof w=="object"&&w!==null?Reflect.get(w,R):void 0;return typeof T=="string"&&T.length>0?[T]:[]});return {adapter:[...new Set(P)].join(" \xB7 ")||"WebGPU adapter",platform:navigator.platform||navigator.userAgent}},t)),{scene:e.key,mode:r,execution:"node",...S,frame:p,firstFrameScreenshot:c,screenshot:g,errors:[...m.page,...m.console]}}catch(c){let u=c instanceof Error?c:new Error(String(c));if(/(?:timed?\s*out|timeout)/iu.test(u.message)){let b=this.#n.read(e.key),f=await G(()=>i.evaluate(()=>{let y=globalThis,v=y.__threeBlocksShaderTools,w=v&&typeof v=="object"?v:void 0;return {documentReadyState:y.document?.readyState??null,parityTargetFrame:Number(y.__threeBlocksParityTargetFrame??0),parityCompletedFrame:Number(y.__threeBlocksParityCompletedFrame??0),readiness:w?.readiness??null,threeRuntimeResources:performance.getEntriesByType("resource").map(R=>R.name).filter(R=>R.includes("three.webgpu"))}}));throw new Error(`${u.message} Last ${r} state for "${e.key}": ${JSON.stringify({page:f,telemetry:b??null})}`)}let p=this.#n.read(e.key),S=(a$2(p)&&Array.isArray(p.demands)&&p.demands.length>0?JSON.stringify(p.demands).slice(0,6e3):void 0)??await G(()=>i.evaluate(b=>{let f=globalThis,y=Reflect.get(f,Symbol.for(b)),v=y!==null&&typeof y=="object"?Reflect.get(y,"readThreeBlocksShaderDemands"):void 0,w=typeof v=="function"?Reflect.apply(v,y,[]):void 0,P=f.__threeBlocksShaderTools,R=Array.isArray(w)&&w.length>0?w:P&&typeof P=="object"?Reflect.get(P,"demands"):void 0;return Array.isArray(R)&&R.length>0?JSON.stringify(R).slice(0,6e3):null},X));throw typeof S=="string"?new Error(`${u.message}
78
+ ${r} demands: ${S}`):u}finally{m.dispose(),await M(()=>l.close());}}async observePublished(e,t,r="webgpu"){for(let a=0;a<2;a++)try{return await this.#b(e,r,t)}catch(s){if(a===0&&ye(s))continue;throw s}throw new Error(`Published shader observation retry was exhausted for scene "${e.key}".`)}async#b(e,t,r){if(await this.#w("precompiled",t,r),!this.#r||!this.#a)throw new Error("Shader browser driver did not start.");let a=this.#r,s=await this.#o(a,r,()=>a.newContext({viewport:r.viewport}));(this.#e.url!==void 0||this.#e.serve!==void 0)&&await this.#o(a,r,()=>Z(s,this.#t,this.#n,"precompiled",r,t,a$3(this.#e.runtime.three,t)));let o=await this.#o(a,r,()=>s.newPage()),d=Q(o);this.#n.clear(e.key);try{await o.goto(Ue(this.#a,e,t),{waitUntil:"domcontentloaded",timeout:r.timeoutMs}),await Promise.race([o.waitForFunction(r.bridge.legacyLab?"globalThis.__threeBlocks?.compileEnd === true":"globalThis.__threeBlocksShaderTools?.readiness?.compileEnd === true",void 0,{timeout:F(r)}),d.first.then(u=>Promise.reject(u))]),await fe(o,r,d),H(await V(o,r.bridge.legacyLab),e,r.bridge.legacyLab,this.#d(),a$3(this.#e.runtime.three,t)),await D(o,r,2);let l=await pe(o),i=await D(o,r,120),m=await pe(o),c=H(await V(o,r.bridge.legacyLab),e,r.bridge.legacyLab,this.#d(),a$3(this.#e.runtime.three,t));return {scene:e.key,mode:"precompiled",...c,frame:i,firstFrameScreenshot:l,beforeScreenshot:l,screenshot:m,errors:[...d.page,...d.console]}}finally{d.dispose(),await M(()=>s.close());}}timingEnvironment(){return this.#f??{adapter:`Node ${this.#m==="webgl"?"WebGL adapter":"WebGPU adapter"}`,platform:`${A.platform}/${A.arch}`}}async close(){this.#t.rejectAll(new Error("Shader browser driver closed.")),this.#r&&await M(()=>this.#r?.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 M(()=>this.#s?.close()??Promise.resolve()),this.#i){let r=this.#i;r.closeAllConnections(),await M(()=>new Promise(a=>{r.close(()=>a());}));}this.#r=void 0,this.#s=void 0,this.#i=void 0,this.#a=void 0,this.#u=void 0,this.#h=void 0,this.#l=void 0,this.#m=void 0,this.#f=void 0,this.#c=0,this.#y&&(this.#y=false,ze());}};function ct(n){return new ae(n)}a$1(ct,"createShaderDriver");export{De as a,$e as b,ve as c,qe as d,ye as e,ct as f};
@@ -0,0 +1,23 @@
1
+ import {b,l,a as a$4,i as i$2,h as h$1,s,r,o,q,p}from'./chunk-UDMY6S4M.js';import {a as a$3}from'./chunk-TK566QET.js';import {i,j as j$1,d as d$1,e as e$1,g,b as b$1,f as f$1,l as l$1,k as k$1,c as c$2}from'./chunk-75JSWKB4.js';import {a as a$2,c as c$1}from'./chunk-WNSGAV6N.js';import {j,a as a$1,c,d,k,h,e,i as i$1,f}from'./chunk-ECQE4D2U.js';import {a}from'./chunk-7X4DHW36.js';import {realpath,readdir,readFile,mkdir,lstat,writeFile}from'fs/promises';import je from'os';import F from'path';import {SHADER_ADDRESS_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_HYDRATION_SCHEMA_VERSION}from'three-blocks/shaders';import {createRequire}from'module';var Ge=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".wgsl",".glsl",".vert",".frag",".json",".css"],Je=new Set(Ge),ze=/^(?:three-blocks\.shaders\.json|(?:precompile|three-blocks\.shaders)\.config\.(?:cjs|cts|js|mjs|mts|ts))$/u,Ar=/(?:^|\/)scene\.(?:cjs|cts|js|jsx|mjs|mts|ts|tsx)$/u,_r=/\b(?:export\s+)?(?:async\s+)?function\s+createScene\b|\bcreateScene\s*=\s*(?:async\s*)?\(/u,Fr=/\b(?:[A-Za-z_$][\w$]*\.)*(?:shaders|shaderCache|sceneShaders)\s*\.\s*(?:material|pipeline|compute|container)\s*\(/u,Nr=/\b(import|export)(?!\s*\()\s*(type\b\s*)?(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']/gu,Lr=/\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,Vr=/\b(?:import|export)(?!\s*\()\s*(?:[^"'();]*?\bfrom\s*)?["']([^"']+)["']|\bimport\s*\(\s*["']([^"']+)["']\s*\)/gu,Hr=/^[0-9A-Za-z][0-9A-Za-z.+_-]{0,127}$/u,Ye=4096,Wr="./shaders";function pr(e,t){let n=F.relative(e,t).split(F.sep).join("/");if(n.length===0||/[\u0000-\u001f\u007f]/u.test(n))throw new Error("Semantic input has an unsafe relative path.");return n}a(pr,"portableRelativePath");function Xe(e,t){try{return new TextDecoder("utf-8",{fatal:!0}).decode(e)}catch{throw new Error(`Shader-relevant source ${JSON.stringify(t)} is not valid UTF-8.`)}}a(Xe,"sourceText");function Qe(e,t){let n="",r="code";for(let i=0;i<e.length;i++){let s=e[i]??"",l=e[i+1]??"";if(r==="code"){if(s==="/"&&l==="/"){n+=" ",r="line-comment",i++;continue}if(s==="/"&&l==="*"){n+=" ",r="block-comment",i++;continue}if(s==="'"||s==='"'||s==="`"){r=s==="'"?"single":s==='"'?"double":"template",n+=t?s:" ";continue}n+=s;continue}if(r==="line-comment"){s===`
2
+ `?(n+=`
3
+ `,r="code"):n+=" ";continue}if(r==="block-comment"){s==="*"&&l==="/"?(n+=" ",r="code",i++):n+=s===`
4
+ `?`
5
+ `:" ";continue}let a=r==="single"?"'":r==="double"?'"':"`";if(s==="\\"&&l.length>0){n+=t?`${s}${l}`:" ",i++;continue}n+=t?s:s===`
6
+ `?`
7
+ `:" ",s===a&&(r="code");}return n}a(Qe,"lexicalSource");function Kr(e){let t=new Set,n=Qe(e,true);for(let r of n.matchAll(Nr))r[2]===void 0&&r[3]!==void 0&&t.add(r[3]);for(let r of n.matchAll(Lr))r[1]!==void 0&&t.add(r[1]);return [...t].sort()}a(Kr,"importSpecifiers");function Ur(e){let t=new Set;for(let n of Qe(e,true).matchAll(Vr)){let r=n[1]??n[2];r!==void 0&&t.add(r);}return [...t].sort()}a(Ur,"runtimeSpecifiers");function Sr(e){return (e.split(/[?#]/u,1)[0]??e).replaceAll("\\","/")}a(Sr,"cleanSpecifier");function qr(e,t,n){let r=Sr(t),i;if(r.startsWith("./")||r.startsWith("../"))i=F.posix.normalize(F.posix.join(F.posix.dirname(e),r));else if(r.startsWith("@/"))i=`src/${r.slice(2)}`;else if(r.startsWith("/src/"))i=r.slice(1);else return;if(i===".three-blocks"||i.startsWith(".three-blocks/"))return;let s=F.posix.extname(i).toLowerCase(),l=new Set([i]);if(s.length===0||!Je.has(s)){for(let a of Ge)l.add(`${i}${a}`);for(let a of Ge)l.add(`${i}/index${a}`);}else if([".js",".mjs",".cjs",".jsx"].includes(s)){let a=i.slice(0,-s.length);for(let h of [".ts",".tsx",".mts",".cts"])l.add(`${a}${h}`);}return [...l].find(a=>n.has(a))}a(qr,"resolveProjectImport");function zr(e,t){let n=Qe(t,false);return Ar.test(e)||_r.test(n)||Fr.test(n)}a(zr,"isShaderRoot");async function Oe(e,t){let n=await realpath(e);if(t!==void 0){let d={},f=0;for(let p of t){let O=await j(n,F.join(n,p),a$1.semanticInput,"Declared shader semantic input");if(f+=O.data.byteLength,f>a$1.semanticTotal)throw new Error("Declared shader semantic inputs exceed the total inspection size limit.");d[p]=c(O.data);}return d}let r=new Map,i=F.join(n,"src");if(await d(i))for(let d of await k(n,i,f=>Je.has(F.extname(f).toLowerCase()))){let f=await j(n,d,a$1.semanticInput,"Shader semantic input");r.set(pr(n,d),f.data);}for(let d of await readdir(n,{withFileTypes:true})){if(!d.isFile()||!ze.test(d.name)&&!Je.has(F.extname(d.name).toLowerCase()))continue;let f=await j(n,F.join(n,d.name),a$1.semanticInput,ze.test(d.name)?"Shader configuration input":"Shader semantic input");r.set(d.name,f.data);}if(r.size>Ye)throw new Error(`Shader input discovery exceeds the ${Ye}-file limit.`);let s=new Set,l=new Map;for(let[d,f]of r){if(!d.includes("/")&&ze.test(d)&&s.add(d),!d.startsWith("src/"))continue;let p=Xe(f,d);l.set(d,p),zr(d,p)&&s.add(d);}if(s.size===0)throw new Error("No shader registration or scene source root was found.");let a=new Set,h=[...s].sort();for(;h.length>0;){let d=h.shift();if(d===void 0||a.has(d))continue;let f=r.get(d);if(f===void 0)continue;a.add(d);let p=l.get(d)??Xe(f,d);for(let O of Kr(p)){let P=qr(d,O,r);P!==void 0&&!a.has(P)&&h.push(P);}h.sort();}let o=0,u={};for(let d of [...a].sort()){let f=r.get(d);if(f===void 0)throw new Error(`Shader input ${JSON.stringify(d)} disappeared during inspection.`);if(o+=f.byteLength,o>a$1.semanticTotal)throw new Error("Semantic shader inputs exceed the total inspection size limit.");u[d]=c(f);}return u}a(Oe,"snapshotShaderInputs");function Ze(e){if(typeof e=="string")return e;if(a$2(e))return Ze(e.import)??Ze(e.default)}a(Ze,"conditionalImportTarget");async function hr(e,t){let n=e;for(;;){let r=F.join(n,"node_modules",...t.split("/"),"package.json");if(await d(r)){let s=await h(r,a$1.packageJson,`${t} package.json`),l=JSON.parse(s.data.toString("utf8"));if(!a$2(l)||l.name!==t||typeof l.version!="string"||!Hr.test(l.version))throw new Error(`Installed ${t} package metadata is invalid.`);return {root:F.dirname(s.path),manifest:l}}let i=F.dirname(n);if(i===n)break;n=i;}throw new Error(`Cannot verify the installed ${t} package.`)}a(hr,"findInstalledPackage");async function Gr(e$1,t){if(!a$2(t.exports))throw new Error("Installed three-blocks package has no public exports map.");let n=Ze(t.exports[Wr]);if(n===void 0||!n.startsWith("./"))throw new Error("Installed three-blocks shader export has no import target.");let r=await realpath(e$1),i=[F.resolve(r,n)],s=new Map,l=0;for(;i.length>0;){let h$1=i.shift();if(h$1===void 0)break;let o=await h(h$1,a$1.semanticInput,"Three Blocks shader runtime module");if(!e(r,o.path)||o.path===r)throw new Error("Three Blocks shader runtime closure escapes its package.");let u=pr(r,o.path);if(s.has(u))continue;if(l+=o.data.byteLength,l>a$1.semanticTotal)throw new Error("Three Blocks shader runtime closure exceeds the inspection limit.");s.set(u,c(o.data));let d=Xe(o.data,u);for(let f of Ur(d)){let p=Sr(f);if(!p.startsWith("./")&&!p.startsWith("../"))continue;let O=F.resolve(F.dirname(o.path),p);if(!e(r,O))throw new Error("Three Blocks shader runtime import escapes its package.");i.push(O);}if(i.sort(),s.size+i.length>Ye)throw new Error("Three Blocks shader runtime closure exceeds the file limit.")}let a=[...s].sort((h,o)=>h[0].localeCompare(o[0])).map(([h,o])=>`${h}\0${o}`).join(`
8
+ `);return c(a)}a(Gr,"shaderRuntimeClosure");async function he(e){let[t,n]=await Promise.all([hr(e,"three"),hr(e,"three-blocks")]);return {three:String(t.manifest.version),threeBlocks:String(n.manifest.version),threeBlocksShaderClosure:await Gr(n.root,n.manifest)}}a(he,"readInstalledShaderRuntime");var gr=4096,Yr=createRequire(import.meta.url),yr,M=new Proxy({},{get(e,t){return yr??=Yr("typescript"),Reflect.get(yr,t)}});function ne(e){let t=e;for(;M.isParenthesizedExpression(t)||M.isAsExpression(t)||M.isSatisfiesExpression(t)||M.isNonNullExpression(t);)t=t.expression;return t}a(ne,"unwrap");function Xr(e){if(M.isIdentifier(e)||M.isStringLiteral(e)||M.isNumericLiteral(e))return e.text}a(Xr,"propertyName");function ge(e,t){let n=new Map;for(let r of e.properties){if(!M.isPropertyAssignment(r))throw new Error(`${t} may contain only static property assignments.`);let i=Xr(r.name);if(i===void 0||n.has(i))throw new Error(`${t} contains a computed or duplicate property.`);n.set(i,r.initializer);}return n}a(ge,"properties");function ye(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let n=ne(e);if(!M.isObjectLiteralExpression(n))throw new Error(`${t} must be a static object literal.`);return n}a(ye,"objectLiteral");function we(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let n=ne(e);if(!M.isStringLiteral(n)&&!M.isNoSubstitutionTemplateLiteral(n))throw new Error(`${t} must be a string literal.`);return n.text}a(we,"stringLiteral");function Pe(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let n=ne(e);if(!M.isNumericLiteral(n))throw new Error(`${t} must be a numeric literal.`);return Number(n.text)}a(Pe,"numericLiteral");function wr(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let n=ne(e);if(!M.isArrayLiteralExpression(n))throw new Error(`${t} must be a static array literal.`);return n.elements}a(wr,"arrayLiteral");function Zr(e,t){if(e===void 0)throw new Error(`${t} is missing.`);let n=ne(e);if(n.kind===M.SyntaxKind.NullKeyword)return null;if(!M.isNumericLiteral(n))throw new Error(`${t} must be null or a numeric literal.`);return Number(n.text)}a(Zr,"numericOrNullLiteral");function Qr(e){return e.parseDiagnostics??[]}a(Qr,"parseDiagnostics");function vr(e,t,n,r){let i=M.createSourceFile(t,e,M.ScriptTarget.Latest,true,M.ScriptKind.TS),s=Qr(i);if(s.length>0)throw new Error(`Shader manifest is not valid TypeScript: ${M.flattenDiagnosticMessageText(s[0]?.messageText??"parse error"," ")}`);let l=i.statements.filter(M.isExportAssignment).filter(w=>!w.isExportEquals);if(l.length!==1)throw new Error("Shader manifest must contain exactly one default export.");let a$1=ge(ye(l[0]?.expression,"Shader manifest default export"),"Shader manifest"),h=a$1.get("version");if(h===void 0||!M.isNumericLiteral(ne(h))||Number(ne(h).getText(i))!==3)throw new Error("Shader manifest version must be the numeric literal 3.");if(we(a$1.get("scene"),"Shader manifest scene")!==n)throw new Error(`Shader manifest scene does not match "${n}".`);let o=a$1.get("runtime"),d=(r?.compatibility??(o===void 0?"":we(ge(ye(o,"Shader manifest runtime"),"Shader manifest runtime").get("id"),"Shader manifest runtime id"))).startsWith("three-webgl-");if(r){if(we(a$1.get("three"),"Shader manifest Three.js version")!==r.three||we(a$1.get("threeBlocks"),"Shader manifest Three Blocks version")!==r.threeBlocks)throw new Error("Shader manifest runtime versions do not match its receipt.");let w=ge(ye(a$1.get("runtime"),"Shader manifest runtime"),"Shader manifest runtime");if(we(w.get("id"),"Shader manifest runtime id")!==r.compatibility||Pe(w.get("address"),"Shader manifest address schema")!==r.address||Pe(w.get("recipe"),"Shader manifest recipe schema")!==r.recipe||Pe(w.get("hydration"),"Shader manifest hydration schema")!==r.hydration)throw new Error("Shader manifest runtime compatibility schemas do not match its receipt.")}let f=ge(ye(a$1.get("entries"),"Shader manifest entries"),"Shader manifest entries");if(f.size===0&&!d||f.size>gr)throw new Error(`Shader manifest must contain ${d?"0":"1"}...${gr} entries.`);let p=wr(a$1.get("modules"),"Shader manifest modules").map((w,v)=>{let I=ne(w);if(!M.isStringLiteral(I)&&!M.isNoSubstitutionTemplateLiteral(I))throw new Error(`Shader manifest module ${v} must be a shader string literal.`);if(I.text.length===0)throw new Error(`Shader manifest module ${v} is empty.`);return I.text}),O=wr(a$1.get("states"),"Shader manifest states").map((w,v)=>{let I=ge(ye(w,`Shader manifest state ${v}`),`Shader manifest state ${v}`),$=a((V,g)=>{let T=Zr(I.get(V),`Shader manifest state ${v} ${V}`);if(T===null)return false;let B=p[T];if(B===void 0||!d&&!B.includes(g))throw new Error(`Shader manifest state ${v} ${V} does not reference a ${g} module.`);return true},"moduleAt"),j=$("vertex","@vertex"),_=$("fragment","@fragment"),L=$("compute","@compute");if(L&&(j||_))throw new Error(`Shader manifest state ${v} mixes render and compute stages.`);if(!L&&!j&&!_)throw new Error(`Shader manifest state ${v} contains no shader stage.`);return {vertex:j,fragment:_,compute:L}}),P={render:0,vertex:0,fragment:0,compute:0};for(let[w,v]of f){if(w.length===0||/[\u0000-\u001f\u007f]/.test(w))throw new Error("Shader manifest contains an invalid entry key.");let I=Pe(v,`Shader manifest entry "${w}"`),$=O[I];if($===void 0)throw new Error(`Shader manifest entry "${w}" references an absent state.`);($.vertex||$.fragment)&&(P.render+=1),$.vertex&&(P.vertex+=1),$.fragment&&(P.fragment+=1),$.compute&&(P.compute+=1);}return P}a(vr,"inspectPrecompiledManifest");function et(e,t){return e.render===t.render&&e.vertex===t.vertex&&e.fragment===t.fragment&&e.compute===t.compute}a(et,"sameCoverage");function rt(e){let t=e.some(r=>r.state==="invalid")?"invalid":e.some(r=>r.state==="missing")?"missing":e.some(r=>r.state==="stale")?"stale":"fresh",n=e.filter(r=>r.state===t);return {state:t,reason:t==="fresh"?`${e.length} configured shader scene${e.length===1?" is":"s are"} fresh.`:n.map(r=>`${r.scene} (${r.backend}): ${r.reason}`).join("; ")}}a(rt,"classifyMatrix");function tt(e,t,n){let r=e.tool;if(!r)return "Shader receipt has no public tool compatibility metadata.";if((r.compatibilities?.[n]??r.compatibility)!==t)return "Shader receipt targets a different runtime compatibility contract.";if(r.transform!==b)return "Shader receipt uses a different provider transform version.";if(r.address!==SHADER_ADDRESS_SCHEMA_VERSION||r.recipe!==SHADER_RECIPE_SCHEMA_VERSION||r.hydration!==SHADER_HYDRATION_SCHEMA_VERSION)return "Shader receipt uses incompatible address, recipe, or hydration schemas."}a(tt,"exactToolCompatibility");function nt(e,t){let n=Object.keys(t).filter(s=>Object.hasOwn(e,s)&&e[s]!==t[s]),r=Object.keys(t).filter(s=>!Object.hasOwn(e,s)),i=Object.keys(e).filter(s=>!Object.hasOwn(t,s));return {...n.length>0?{changedInputs:n}:{},...r.length>0?{addedInputs:r}:{},...i.length>0?{removedInputs:i}:{}}}a(nt,"inputChanges");async function Ie(e=process.cwd(),t,n){let r=await i(e),i$2=await j$1(r),s=d$1(n??i$2.backend),l$1=i$2.scenes.flatMap(o=>e$1(o,s).map(u=>({scene:o,backend:u,key:g(o.key,u)}))),a$2=F.join(r,b$1),h=a(()=>({schemaVersion:1,root:r,state:"missing",reason:`${b$1}/meta.json is absent.`,scenes:l$1.map(({scene:o,backend:u})=>({scene:o.key,backend:u,state:"missing",reason:"No committed shader receipt."}))}),"missing");if(!await d(a$2)||!await d(F.join(a$2,"meta.json")))return h();try{let o=await i$1(r,a$2,"Shader artifact directory"),u=await j(o,F.join(o,"meta.json"),a$1.receipt,"Shader receipt"),d=c$1(JSON.parse(u.data.toString("utf8"))),f=await l(o,u.data),p=t??await he(r),O=new Set(i$2.scenes.flatMap(g$1=>e$1(g$1,["webgpu","webgl"]).map(T=>g(g$1.key,T)))),w=Object.keys(d.scenes).filter(g=>!O.has(g));if(w.length>0)throw new Error(`Shader receipt contains unconfigured scenes: ${w.join(", ")}.`);let v=d.runtime.three!==p.three,I=d.runtime.threeBlocksShaderClosure!==p.threeBlocksShaderClosure,$=d.tool?.version!==a$3,j$1=F.join(r,i$2.publicDir??"public"),_=[];for(let{scene:g,backend:T,key:B}of l$1){let S=d.scenes[B];if(!S){_.push({scene:g.key,backend:T,state:"missing",reason:"Scene/backend is absent from the complete receipt matrix."});continue}let k=a$4(p.three,T),x=tt(d,k,T);if(x)throw new Error(`${B}: ${x}`);let C=await j(o,F.join(o,S.artifact),a$1.manifest,"Shader manifest");if(c(C.data)!==S.artifactHash)throw new Error(`Shader artifact checksum differs for scene "${g.key}".`);if(S.asset!==void 0&&S.assetHash!==void 0){let G=await j(j$1,F.join(j$1,S.asset),a$1.manifest,"Static shader manifest");if(c(G.data)!==S.assetHash)throw new Error(`Static shader manifest checksum differs for scene "${g.key}".`)}if(S.bytes!==void 0&&S.bytes!==C.data.byteLength)throw new Error(`Shader artifact byte count differs for scene "${g.key}".`);let z=vr(C.data.toString("utf8"),C.path,g.key,{three:d.runtime.three,threeBlocks:d.runtime.threeBlocks,compatibility:k,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION});if(!et(z,S.coverage))throw new Error(`Shader coverage differs for scene "${g.key}".`);if(T==="webgpu"&&!i$2.allowLiveBuilds&&S.skipped&&S.skipped.render+S.skipped.compute>0)throw new Error(`Scene "${g.key}" contains skipped live builds but allowLiveBuilds is false.`);let m=await Oe(r,g.inputs),E=nt(S.inputs,m),b=(E.changedInputs?.length??0)+(E.addedInputs?.length??0)+(E.removedInputs?.length??0),y=v||I||$||b>0,A=f?.scenes[B],N=A===void 0||f===void 0?void 0:{...A,schemaVersion:f.schemaVersion,measuredAt:f.measuredAt,source:f.source,...f.source==="committed-capture"?{adapter:f.adapter,platform:f.platform}:{}};_.push({scene:g.key,backend:T,state:y?"stale":"fresh",reason:v?"Installed Three.js version differs from the receipt.":I?"Installed three-blocks/shaders runtime closure differs from the receipt.":$?`Receipt was generated by @three-blocks/devtools ${d.tool?.version??"unknown"}.`:b>0?`${b} semantic shader input${b===1?"":"s"} changed.`:"Manifest, runtime, schemas, transform, and semantic inputs match.",coverage:z,...!y&&N!==void 0&&N.builds===z.render+z.compute?{timing:N}:{},...E});}let L=rt(_),V=L.state==="fresh"&&f!==void 0&&_.every(g=>g.timing!==void 0)?f:void 0;return {schemaVersion:1,root:r,...L,scenes:_,runtime:p,receipt:d,...V===void 0?{}:{timing:V}}}catch(o){let u=o instanceof Error?o.message:String(o);return {schemaVersion:1,root:r,state:"invalid",reason:u,scenes:l$1.map(({scene:d,backend:f})=>({scene:d.key,backend:f,state:"invalid",reason:u}))}}}a(Ie,"inspectShaderMatrix");var Tr=".three-blocks/shaders/pending-capture";function st(e){return (e instanceof Error?`${e.name}: ${e.message}`:String(e)).includes("ShaderHydrationError:")}a(st,"isShaderHydrationFailure");async function at(e,t,n){if(t.length===0)return;let r=F.join(e,b$1,"meta.json"),i=await readFile(r);if(c(i)!==c(n))throw new Error("Shader receipt changed before failed scenes could be marked for recapture.");let s=c$1(JSON.parse(i.toString("utf8"))),l=c(n),a=new Set(t),h=c$1({...s,scenes:Object.fromEntries(Object.entries(s.scenes).map(([o,u])=>[o,a.has(o)?{...u,inputs:{...u.inputs,[Tr]:l}}:u]))});await f(r,`${i$2(h)}
9
+ `);}a(at,"markShaderScenesForRecapture");function ot(e,t){return i$2(e)===i$2(t)}a(ot,"equalSnapshot");async function Br(e,t,n,r,i,s,l){let a;for(let h=0;h<s;h++)try{let o=h$1(await e.capture(t,r,n),{scene:t.key,backend:n,runtime:i}),u=n==="webgl"&&o.skipped.every(d=>d.reason.startsWith("WebGL shader precompilation does not support "));if(o.skipped.length>0&&!r.allowLiveBuilds&&!u)throw new Error(`Scene "${t.key}" contains ${o.skipped.length} unregistered live shader build${o.skipped.length===1?"":"s"} while allowLiveBuilds is false.`);return {capture:o,result:{scene:t.key,backend:n,attempts:h+1,coverage:o.coverage,skipped:o.skipped.length,startupBuilds:o.stats.registeredBuilds,startupBuildMs:o.stats.buildMs,...o.timing===void 0?{}:{timing:o.timing}}}}catch(o){a=o,h+1<s&&l?.(t.key,h+2,s,r.timeoutMs,o);}throw new Error(`Shader capture "${t.key}" failed after ${s} attempts: ${a instanceof Error?a.message:String(a)}`)}a(Br,"captureScene");async function Kt(e){let t=performance.now(),n=await realpath(e.root),r=e.config??await j$1(n),i=e.runtime??await he(n),{createShaderDriver:s}=await import('./shader-browser-N5LY2NJX.js'),{launchNodeRenderer:l}=await import('@three-blocks/devtools/node'),a=await l();try{await a.gpuInfo();}catch(p){throw new Error(`No GPU adapter is available to the Node renderer (${p instanceof Error?p.message:String(p)}).`)}finally{await a.close();}let h=new Map,o=[...f$1(r.scenes,[...d$1(e.backend??r.backend)].reverse())],u=new Map,d=[];try{for(let[p,{scene:O,backend:P,key:w}]of o.entries()){let v=h.get(P);v===void 0&&h.set(P,v=s({root:n,runtime:i,serve:e.serve,...e.base===void 0?{}:{base:e.base}})),e.onSceneStart?.(w,p,o.length);let{capture:I,result:$}=await Br(v,O,P,r,i,2,e.onSceneRetry);u.set(`${O.key}.${P}.json`,`${i$2(I.manifest)}
10
+ `),d.push($);}}finally{await Promise.all([...h.values()].map(p=>p.close()));}let f$2=F.join(F.resolve(n,e.serve),"three-blocks","shaders");await mkdir(f$2,{recursive:true});for(let[p,O]of u)await f(F.join(f$2,p),O);return {durationMs:performance.now()-t,scenes:d,files:[...u.keys()].map(p=>F.posix.join(F.relative(n,F.resolve(n,e.serve)).split(F.sep).join("/"),"three-blocks/shaders",p))}}a(Kt,"captureBuiltShaders");async function Ut(e={}){let t=e.root?await realpath(e.root):await i(e.start),n=e.config===void 0?await l$1(t):void 0,r$1=e.config??n?.config??await j$1(t),i$1=e.runtime??await he(t),s$1=d$1(e.backend??r$1.backend),l$2=d$1(r$1.backend),a$1=[...new Set([...l$2,...s$1])],h=[...s$1].reverse(),o$1=[...f$1(r$1.scenes,h)],u,d={},f;if(e.ifStale){let m=await Ie(t,i$1,e.backend??r$1.backend);if(m.state==="fresh"&&m.scenes.every(E=>E.timing!==void 0))return {schemaVersion:1,root:t,skipped:true,reason:m.reason,scenes:[]};if(m.state!=="invalid"&&m.receipt!==void 0){let E=m.state==="fresh";o$1=o$1.filter(({scene:b,backend:y})=>{let A=m.scenes.find(N=>N.scene===b.key&&N.backend===y);return A?.state!=="fresh"||E&&A.timing===void 0}),u=m.receipt;for(let b of m.scenes){if(b.state!=="fresh"||b.timing===void 0)continue;let{builds:y,liveBuildMs:A,precompiledBuildMs:N,avoidedBuildMs:G,runs:H,spreadMs:W}=b.timing;d[g(b.scene,b.backend)]={builds:y,liveBuildMs:A,precompiledBuildMs:N,avoidedBuildMs:G,runs:H,spreadMs:W},b.timing.source==="committed-capture"&&b.timing.adapter!==void 0&&b.timing.platform!==void 0&&(f={adapter:b.timing.adapter,platform:b.timing.platform});}}}let p=performance.now(),O=u!==void 0&&(u.runtime.three!==i$1.three||u.runtime.threeBlocksShaderClosure!==i$1.threeBlocksShaderClosure||u.tool?.version!==a$3)?c(i$2({runtime:u.runtime,tool:u.tool})):void 0,P=a(async()=>new Map(await Promise.all(r$1.scenes.map(async m=>[m.key,await Oe(t,m.inputs)]))),"snapshotInputs"),w=await P(),v=a(async()=>{let m=await P();for(let E of r$1.scenes){let b=w.get(E.key),y=m.get(E.key);if(b===void 0||y===void 0||!ot(b,y))throw new Error(`Semantic shader inputs changed during capture for scene "${E.key}"; the current scene was not committed.`)}},"assertInputsUnchanged"),I=e.driver===void 0,$=e.driver===void 0&&e.driverKind===void 0&&e.serve===void 0&&e.url===void 0?await k$1(t):void 0,j=e.serve??$?.serve,_=e.driverKind??$?.driverKind??(j===void 0?"vite":"static");if(e.url!==void 0&&(e.serve!==void 0||e.driverKind!==void 0))throw new Error("--url cannot be combined with --driver or --serve.");if(_==="vite"&&j!==void 0)throw new Error("--serve requires the static shader driver.");if(_==="static"&&j===void 0&&e.driver===void 0)throw new Error("The static shader driver requires --serve <built-directory>.");let L=e.driver===void 0?await import('./shader-browser-N5LY2NJX.js'):void 0,V=a(()=>L.createShaderDriver({root:t,runtime:i$1,...e.url===void 0?{}:{url:e.url},...j===void 0?{}:{serve:j},...e.headed===void 0?{}:{headed:e.headed}}),"createDriver"),g$1=new Map,T=a(m=>{if(e.driver!==void 0)return e.driver;let E=g$1.get(m);return E===void 0&&(E=V(),g$1.set(m,E)),E},"driverFor"),B=new Map,S=[],k=u!==void 0&&r$1.scenes.every(m=>e$1(m,a$1).every(E=>u?.scenes[g(m.key,E)]!==void 0)),x=u,C,z=e.attempts??2;if(!Number.isSafeInteger(z)||z<1||z>5)throw new Error("Shader capture attempts must be an integer in 1...5.");try{for(let[y,A]of o$1.entries()){let{scene:N,backend:G,key:H}=A,W=T(G);e.onSceneStart?.(H,y,o$1.length);let{capture:Ae,result:_e}=await Br(W,N,G,r$1,i$1,z,e.onSceneRetry);if(B.set(H,Ae),S.push(_e),k&&x!==void 0){await v();let nr=new Map(r$1.scenes.map(Q=>{let ve=e$1(Q,a$1),pe=Q.key===N.key?w.get(Q.key):ve.map(ae=>x?.scenes[g(Q.key,ae)]?.inputs).find(ae=>ae!==void 0);if(pe===void 0)throw new Error(`Shader checkpoint is missing scene "${Q.key}".`);return O!==void 0&&!ve.every(ae=>B.has(g(Q.key,ae)))&&(pe={...pe,[Tr]:O}),[Q.key,pe]}));C=await s({root:t,scenes:r$1.scenes,backends:a$1,captures:new Map([[H,Ae]]),runtime:i$1,inputs:nr,previousReceipt:x,publicDirectory:r$1.publicDir??"public"}),x=C.receipt;}}await v(),C=await s({root:t,scenes:r$1.scenes,backends:a$1,captures:B,runtime:i$1,inputs:w,...u===void 0?{}:{previousReceipt:u},publicDirectory:r$1.publicDir??"public"});let m={...d};for(let y of S)m[g(y.scene,y.backend)]={builds:y.coverage.render+y.coverage.compute,setupMeasured:!1,liveBuildMs:y.startupBuildMs,precompiledBuildMs:0,avoidedBuildMs:y.startupBuildMs,runs:1,spreadMs:0};if(e.commitTiming===!0){let y=f??{adapter:B.values().next().value?.provenance?.adapter??"WebGPU adapter",platform:`${je.platform()}/${je.arch()}`},A=g$1.get("webgpu")??g$1.values().next().value??e.driver;await r(t,m,await(A?.timingEnvironment?.()??y));}else await o(t,m);let E=await readFile(F.join(C.directory,"meta.json")),b=await l(C.directory,E);return {schemaVersion:1,root:t,skipped:!1,reason:`Wrote ${S.length} shader scene${S.length===1?"":"s"}.`,durationMs:performance.now()-p,scenes:S,measurement:{beforeBuilds:S.reduce((y,A)=>y+A.startupBuilds,0),afterBuilds:0,firstFrameDeltaMs:-S.reduce((y,A)=>y+A.startupBuildMs,0),source:"capture-build-phase"},...n===void 0?{}:{configuration:{created:n.created,file:n.file}},written:C,...b===void 0?{}:{timing:b}}}finally{I&&await Promise.all([...g$1.values()].map(m=>m.close()));}}a(Ut,"captureShaders");function dt(e){return ["workerReady","assetsReady",...e.requiresText?["textReady"]:[],"compileEnd","firstFrame"]}a(dt,"requiredReadiness");function $r(e){if(e.length===0)throw new Error("Cannot take the median of an empty shader timing capture.");let t=[...e].sort((s,l)=>s-l),n=Math.floor(t.length/2),r=t[n];if(r===void 0)throw new Error("Shader timing median is unavailable.");if(t.length%2===1)return r;let i=t[n-1];if(i===void 0)throw new Error("Shader timing median pair is unavailable.");return (i+r)/2}a($r,"median");function er(e,t,n,r){if(e.scene!==t.key||e.mode!==n)throw new Error(`Browser observation identity differs for scene "${t.key}".`);if(e.compatibility!==r||e.transform!==b)throw new Error(`Browser observation compatibility differs for scene "${t.key}".`);let i=dt(t).filter(s=>e.readiness[s]!==true);if(i.length>0)throw new Error(`Scene "${t.key}" ${n} observation is missing readiness bits: ${i.join(", ")}.`);if(e.errors.length>0)throw new Error(`Scene "${t.key}" ${n} browser errors:
11
+ - ${e.errors.join(`
12
+ - `)}
13
+ ${n} demands: ${rr(e.demands)}`)}a(er,"assertObservation");async function ct(e,t,n){if(n===void 0)return new Set;try{let r=JSON.parse(await readFile(F.join(e,t.publicDir??"public",n),"utf8"));return new Set(Object.keys(r.fallbacks??{}))}catch{return new Set}}a(ct,"manifestFallbackKeys");function lt(e,t,n,r,i,s){if(t.render>0&&n.stats.registeredRenderBuilds===0)throw new Error(`Scene "${e.key}" live baseline exercised no registered render pipeline.`);if(t.compute>0&&n.stats.registeredComputeBuilds===0)throw new Error(`Scene "${e.key}" live baseline exercised no registered compute kernel.`);Mr(e,t,r,i,s,n.demands);}a(lt,"assertZeroBuild");function rr(e){return !e||e.length===0?"none recorded":e.map(t=>`${String(t.key??"unregistered")}[${String(t.event)}${t.hit===false?":miss":""}|${String(t.target)}${t.object===void 0?"":`@${String(t.object)}`}]`).join(" ").slice(0,4e3)}a(rr,"describeDemands");function Mr(e,t,n,r,i,s){let l=a(()=>`
14
+ Precompiled demands: ${rr(n.demands)}`+(s===void 0?"":`
15
+ Live demands: ${rr(s)}`),"demandEvidence");if(n.stats.registeredRenderBuilds+n.stats.registeredComputeBuilds>r){let a=n.stats.missedKeys??[];throw new Error(`Scene "${e.key}" injected path performed ${n.stats.registeredRenderBuilds} render and ${n.stats.registeredComputeBuilds} compute registered live builds; capture permits ${r}.`+(a.length>0?` Missed keys: ${a.join(", ")}.`:"")+l())}if(n.stats.buildCalls>r)throw new Error(`Scene "${e.key}" injected path performed ${n.stats.buildCalls} total live NodeBuilder build${n.stats.buildCalls===1?"":"s"}; capture permits ${r} skipped live build${r===1?"":"s"}.`);if(t.render>0&&n.stats.injectedRender===0)throw new Error(`Scene "${e.key}" injected no render entries.`);if(t.compute>0&&n.stats.injectedCompute===0)throw new Error(`Scene "${e.key}" injected no compute entries.`);if(n.stats.missed!==0||n.stats.missedRender!==0||n.stats.missedCompute!==0){let a=n.stats.missedKeys??[],h=a.filter(u=>!i.has(u)),o=a.length>0&&n.stats.missed<=r;if(h.length>0||!o)throw new Error(`Scene "${e.key}" injected path reported shader manifest misses.`+(a.length>0?` Missed keys: ${a.join(", ")}.`:"")+(h.length>0&&h.length!==a.length?` Unexpected: ${h.join(", ")}.`:"")+l())}}a(Mr,"assertPrecompiledZeroBuild");async function ut(e,t,n,r,i){let s=F.join(e,c$2);if(await d(s)){let a=await lstat(s);if(a.isSymbolicLink()||!a.isDirectory())throw new Error("Shader parity artifact directory is not a real directory.")}else await mkdir(s,{recursive:true});let l=[`${t}.live.png`,`${t}.precompiled.png`,`${t}.diff.png`];return await Promise.all([n,r,i].map(async(a,h)=>{let o=l[h];if(o===void 0)throw new Error("Parity artifact mapping failed.");let u=F.join(s,o);if(await d(u)){let d=await lstat(u);if(d.isSymbolicLink()||!d.isFile())throw new Error(`Shader parity target is not a regular file: ${o}.`)}await writeFile(u,a,{mode:384});})),l.map(a=>`${c$2}/${a}`)}a(ut,"writeParityFailure");async function ft(e,t){if(!(e instanceof Error)||!e.message.includes(" parity failed for scene "))return e;let n;try{let r=(await t()).stats.stateOracle;r===void 0?n="no hydrated state was checked":r.differences.length===0&&r.equivalent===r.checked?n=`${r.checked}/${r.checked} hydrated states bind the application nodes a live build binds (${r.identical} identical, ${r.recreated} recreated over the same value); no application input is misbound`:n=`${r.checked-r.equivalent}/${r.checked} hydrated states bind other application nodes than a live build of the same key:
16
+ `+r.differences.map(i=>` ${i}`).join(`
17
+ `);}catch(r){n=`unavailable (${r instanceof Error?r.message.split(`
18
+ `,1)[0]:String(r)})`;}return new Error(`${e.message}
19
+ State oracle: ${n}`,{cause:e})}a(ft,"withStateOracle");async function qt(e={}){let t=e.root?await realpath(e.root):await i(e.start),n=e.runtime??await he(t),r$1=e.config??await j$1(t),i$1=d$1(e.backend??r$1.backend),s=f$1(r$1.scenes,[...i$1].reverse()),l=await Ie(t,n,e.backend??r$1.backend);if(l.state!=="fresh")throw new Error(`Shader no-GPU validation is ${l.state}: ${l.reason}`);if(e.skipBrowser)return {schemaVersion:1,root:t,noGpu:l,browser:"skipped",scenes:[]};if(e.parityOnly===true&&e.commitTiming===true)throw new Error("Parity-only shader verification cannot commit timing.");let a$1=e.runs??5;if(!Number.isSafeInteger(a$1)||a$1<1||a$1>100)throw new Error("Shader timing runs must be an integer in 1...100.");let h=await readFile(F.join(t,b$1,"meta.json")),o$1=c$1(JSON.parse(h.toString("utf8")));if(l.receipt===void 0||i$2(o$1)!==i$2(l.receipt))throw new Error("Shader receipt changed after no-GPU validation; restart browser parity verification.");let u=e.driver===void 0,d=e.driver===void 0&&e.driverKind===void 0&&e.serve===void 0&&e.url===void 0?await k$1(t):void 0,f=e.serve??d?.serve,p$1=e.driverKind??d?.driverKind??(f===void 0?"vite":"static");if(e.url!==void 0&&(e.serve!==void 0||e.driverKind!==void 0))throw new Error("--url cannot be combined with --driver or --serve.");if(p$1==="vite"&&f!==void 0)throw new Error("--serve requires the static shader driver.");if(p$1==="static"&&f===void 0&&e.driver===void 0)throw new Error("The static shader driver requires --serve <built-directory>.");let O=e.driver===void 0?await import('./shader-browser-N5LY2NJX.js'):void 0,{compareShaderScreenshots:P}=await import('./shader-parity-7DEPQEDI.js'),w=a(()=>O.createShaderDriver({root:t,runtime:n,...e.url===void 0?{}:{url:e.url},...f===void 0?{}:{serve:f},...e.headed===void 0?{}:{headed:e.headed}}),"createDriver"),v=new Map,I=new Map,$=a((T,B)=>{if(e.driver!==void 0)return e.driver;let S=T.get(B);return S===void 0&&(S=w(),T.set(B,S)),S},"driverFor");await q(t,s.map(T=>T.key),h);let j=[],_=a(()=>j.some(T=>T.live.execution==="node")?{browser:"skipped",native:"passed"}:{browser:"passed"},"executionResult"),L={},V=[],g=new Set;try{for(let[B,S]of s.entries()){let{scene:k,backend:x,key:C}=S;e.onSceneStart?.(C,B,s.length);let z=l.scenes.find(R=>R.scene===k.key&&R.backend===x);if(!z?.coverage)throw new Error(`Fresh receipt has no coverage for "${C}".`);let m=z.coverage;if(m.render+m.compute===0)continue;let E=a$4(n.three,x),b=l.receipt?.scenes[C]?.skipped,y=(b?.render??0)+(b?.compute??0),A=await ct(t,r$1,l.receipt?.scenes[C]?.asset),N=a(async R=>{let J=$(v,x),be=$(I,x),ee=R?"live":"precompiled",ke=R?"precompiled":"live",Ee=R?J:be,Re=R?be:J,ie=await Ee.observe(k,ee,r$1,void 0,x),D=await Re.observe(k,ke,r$1,ie.frame,x),oe=ie.mode==="live"?ie:D,de=ie.mode==="precompiled"?ie:D;er(oe,k,"live",E),er(de,k,"precompiled",E),lt(k,m,oe,de,y,A);let ir=a(async(Pr,sr,ar)=>{let Y=P(sr,ar,r$1.parity.channelTolerance,k.maxDiffRatio??r$1.parity.maxDiffRatio);if(Y.matches)return Y;let Ir=await ut(t,C,sr,ar,Y.diff),jr=Y.nonBlack?`${Y.differentPixels}/${Y.totalPixels} pixels differ (${(Y.diffRatio*100).toFixed(3)}%).`:`rendered output is black (live=${Y.baselineLuminance.toFixed(4)}, precompiled=${Y.precompiledLuminance.toFixed(4)}).`;throw new Error(`Shader ${Pr} parity failed for scene "${k.key}" at completed frames live=${oe.frame}, precompiled=${de.frame}: ${jr} Artifacts: ${Ir.join(", ")}`)},"compare");await ir("first frame",oe.firstFrameScreenshot,de.firstFrameScreenshot);let Or=await ir("settled",oe.screenshot,de.screenshot);return {live:oe,precompiled:de,parity:Or}},"observePair"),G,H,W;if(e.parityOnly===!0)try{if(G=await N(!0),e.stateOracle===!0){let R=(await $(I,x).observe(k,"precompiled",r$1,void 0,x,!0)).stats.stateOracle;if(R!==void 0&&R.differences.length>0)throw new Error(`Shader state parity failed for scene "${k.key}": ${R.checked-R.equivalent}/${R.checked} hydrated states bind other application nodes than a live build of the same key although pixels agree:
20
+ `+R.differences.map(J=>` ${J}`).join(`
21
+ `))}}catch(R){st(R)&&g.add(C);let J=await ft(R,()=>$(I,x).observe(k,"precompiled",r$1,void 0,x,!0));V.push({scene:C,error:J}),e.onSceneError?.(C,J);continue}else {await N(!0);let R=[];for(let D=0;D<a$1;D++)R.push(await N(D%2===0));let J=R[R.length-1];if(J===void 0)throw new Error(`Shader timing produced no runs for scene "${k.key}".`);if(G=J,H=await $(I,x).observePublished(k,r$1,x),er(H,k,"precompiled",E),Mr(k,m,H,y,A),W=k.runtimeMotion?P(H.beforeScreenshot,H.screenshot,r$1.parity.channelTolerance,1):void 0,W&&W.diffRatio<1e-4)throw new Error(`Published scene "${k.key}" stopped animating during its normal 120-frame soak (changed ${W.differentPixels}/${W.totalPixels} canvas pixels).`);let ee=a(D=>D.stats.buildMs+(D.stats.precompiledSetupMs??0)+(D.stats.hydrationMs??0),"observedNodeBuilderMs"),ke=$r(R.map(D=>ee(D.live))),Ee=$r(R.map(D=>ee(D.precompiled))),Re=Math.max(0,ke-Ee),ie=R.map(D=>Math.max(0,ee(D.live)-ee(D.precompiled)));L[C]={builds:m.render+m.compute,setupMeasured:!0,liveBuildMs:ke,precompiledBuildMs:Ee,avoidedBuildMs:Re,runs:a$1,spreadMs:Math.max(...ie.map(D=>Math.abs(D-Re)))};}let{diff:Ae,..._e}=G.parity,{firstFrameScreenshot:nr,screenshot:Q,...ve}=G.live,{firstFrameScreenshot:pe,screenshot:ae,...Cr}=G.precompiled,Fe;if(H!==void 0){let{beforeScreenshot:R,firstFrameScreenshot:J,screenshot:be,...ee}=H;Fe=ee;}j.push({scene:k.key,backend:x,coverage:m,live:ve,precompiled:Cr,...Fe===void 0?{}:{published:Fe},parity:_e,...W===void 0?{}:{runtimeMotion:{differentPixels:W.differentPixels,totalPixels:W.totalPixels,diffRatio:W.diffRatio}}}),await p(t,[C],h);}if(e.parityOnly===!0){if(await at(t,[...g],h),V.length>0)throw new Error(`Shader parity failed for ${V.length}/${s.length} scene/backend pair(s):
22
+ `+V.map(B=>{let S=B.error instanceof Error?B.error.message:String(B.error);return ` - ${B.scene}: ${S}`}).join(`
23
+ `));return {schemaVersion:1,root:t,noGpu:l,..._(),scenes:j}}if(Object.keys(L).length===0)return {schemaVersion:1,root:t,noGpu:l,..._(),scenes:j};if(e.commitTiming===!0){let B={adapter:i$1.length===1&&i$1[0]==="webgl"?"WebGL adapter":"WebGPU adapter",platform:`${je.platform()}/${je.arch()}`},k=await((v.get("webgpu")??v.values().next().value??e.driver)?.timingEnvironment?.()??B),x=await r(t,L,k);return {schemaVersion:1,root:t,noGpu:l,..._(),scenes:j,timing:x.local,committedTiming:x.committed}}let T=await o(t,L);return {schemaVersion:1,root:t,noGpu:l,..._(),scenes:j,timing:T}}finally{u&&await Promise.all([...v.values(),...I.values()].map(T=>T.close()));}}a(qt,"testShaders");export{vr as a,Oe as b,he as c,Ie as d,Kt as e,Ut as f,ft as g,qt as h};
@@ -0,0 +1 @@
1
+ import {e,d as d$1}from'./chunk-WWBW6MPB.js';import {a}from'./chunk-7X4DHW36.js';import {existsSync,readFileSync,readFile}from'fs';import {createRequire}from'module';import d from'path';import {isSupportedThreeVersion,THREE_BLOCKS_SUPPORTED_THREE_RANGE}from'three-blocks/vite';var k="@three-blocks/devtools/webpack-loader";function m(e){if(typeof e=="string")return e===k;if(Array.isArray(e))return e.some(m);if(e===null||typeof e!="object")return false;let r=e;return r.loader===k||m(r.use)}a(m,"webpackRuleUsesShaderLoader");function v(e){let r=y(process.cwd()),n=a(t=>S(r,t),"exact"),o={...e.resolve?.alias,...n("three")===void 0?{}:{three$:n("three")},...n("three/webgpu")===void 0?{}:{"three/webgpu$":n("three/webgpu")},...n("three/tsl")===void 0?{}:{"three/tsl$":n("three/tsl")},"three/addons":d.join(r.root,"examples/jsm"),"three/examples/jsm":d.join(r.root,"examples/jsm")};return {...e,resolve:{...e.resolve,alias:o}}}a(v,"withTargetThreeAliases");function x(e){let r=v(e),n=r.module?.rules??[];return n.some(m)?r:{...r,module:{...r.module,rules:[...n,{enforce:"pre",test:/three[\\/]build[\\/]three\.webgpu\.js$/u,use:[{loader:k}]}]}}}a(x,"withShaderWebpackRule");function K(e){return x(e)}a(K,"withThreeBlocksWebpack");function U(e){let n=e.webpack;return {...e,webpack(o,...t){let s=n?.call(this,o,...t)??o,a=t[0];return a!==null&&typeof a=="object"&&Reflect.get(a,"isServer")===true?v(s):x(s)}}}a(U,"withThreeBlocksNext");function y(e){let r;try{r=createRequire(d.join(d.resolve(e),"package.json")).resolve("three");}catch(s){throw new Error("The shader adapter could not resolve Three.js from the target project.",{cause:s})}let n=d.dirname(r),o,t;for(;;){let s=d.join(n,"package.json");if(existsSync(s)){let l=JSON.parse(readFileSync(s,"utf8"));if(l.name==="three"){o=s,t=l;break}}let a=d.dirname(n);if(a===n)break;n=a;}if(o===void 0)throw new Error(`The shader adapter could not locate Three.js package metadata from ${r}.`);if(typeof t?.version!="string"||t.version.length===0)throw new Error(`The resolved Three.js package has no version: ${o}`);return {root:d.dirname(o),version:t.version,exports:t.exports}}a(y,"resolveThreePackage");function A(e=process.cwd()){return y(e).version}a(A,"resolveShaderAdapterThreeVersion");function R(e){return {version:e.threeVersion??A(e.root),capture:e.capture??process.env.THREE_BLOCKS_SHADER_TOOL==="1"}}a(R,"resolvedOptions");var w=false;function b(e$1,r){return !r.capture&&!isSupportedThreeVersion(r.version)?(w||console.warn(`[three-blocks] Three.js ${r.version} is not a verified revision (${THREE_BLOCKS_SUPPORTED_THREE_RANGE}); shader precompilation is off and scenes compile live.`),w=true,null):e(e$1,r.version,{instrumentCapture:r.capture})}a(b,"transformVerifiedThree");function D(e,r,n={}){return d$1(r)?b(e,R(n)):null}a(D,"transformThreeWebGPUModule");function h(e){if(typeof e=="string")return e;if(Array.isArray(e)){for(let n of e){let o=h(n);if(o!==void 0)return o}return}if(e===null||typeof e!="object")return;let r=e;for(let n of ["browser","import","default"]){let o=h(r[n]);if(o!==void 0)return o}}a(h,"exportTarget");function S(e,r){if(e.exports===null||typeof e.exports!="object")return;let n=e.exports,o=r==="three"?".":`./${r.slice(6)}`,t=h(n[o]);if(t!==void 0)return d.resolve(e.root,t);for(let[s,a]of Object.entries(n)){let l=s.indexOf("*");if(l<0)continue;let c=s.slice(0,l),u=s.slice(l+1);if(!o.startsWith(c)||!o.endsWith(u))continue;let f=o.slice(c.length,o.length-u.length),p=h(a);if(p!==void 0)return d.resolve(e.root,p.replaceAll("*",f))}}a(S,"resolveThreeExport");function J(e={}){let r=e.root??process.cwd(),n=y(r),o={version:e.threeVersion??n.version,capture:e.capture??process.env.THREE_BLOCKS_SHADER_TOOL==="1"};return {name:"three-blocks-shader-provider",setup(t){t.onResolve?.({filter:/^three(?:\/.*)?$/},s=>{let a=S(n,s.path);return a===void 0?void 0:{path:a}}),t.onLoad({filter:/three[\\/]build[\\/]three\.webgpu\.js$/},async s=>{let a=await new Promise((c,u)=>{readFile(s.path,"utf8",(f,p)=>{f?u(f):c(p);});}),l=b(a,o);return l===null?void 0:{contents:l.code,loader:"js"}});}}}a(J,"createEsbuildShaderPlugin");function M(e={}){let r=R(e);return {name:"three-blocks-shader-provider",enforce:"pre",transform(n,o){if(!d$1(o))return null;let t=b(n,r);return t===null?null:{code:t.code,map:null}}}}a(M,"createRollupShaderPlugin");export{k as a,K as b,U as c,A as d,D as e,J as f,M as g};
@@ -1,5 +1,5 @@
1
- import {h}from'./chunk-NDIPQLTU.js';import {b,a as a$1,c,h as h$1,d,f}from'./chunk-ECQE4D2U.js';import {a}from'./chunk-7X4DHW36.js';import {readFile,lstat,readdir,realpath,mkdir}from'fs/promises';import i from'path';import {read,KHR_DF_PRIMARIES_BT709,write}from'ktx-parse';var U=2,ie="ktx2-encoder@0.6.0;@napi-rs/canvas@1.0.9",ae=i.join(".three-blocks","assets"),ue=i.join(ae,"meta.json"),we=i.join(ae,"cache"),Te=256*1024*1024,Ae=64*1024*1024,ee=115e5,te=64,Ee=163,ve=166,Re=167,Se=1000066e3,de=1,le=2,$e=/baseColor|emissive|diffuse|sheenColor|specularColor/u,Me=/normal/iu,Oe=/(?:^|[_\-.])(?:normal|nrm|nor)(?:[_\-.]|map|$)/iu,Ie=/(?:rough|metal|orm\b|occlusion|ambient|[_\-.]ao(?:[_\-.]|$)|height|disp|thick|mask)/iu;function _e(t){return t.some(e=>Me.test(e))?"normal":t.some(e=>$e.test(e))||t.length===0?"color":"data"}a(_e,"presetForTextureSlots");function De(t){let e=i.basename(t);return Oe.test(e)?"normal":Ie.test(e)?"data":"color"}a(De,"presetForImageName");function V(t){let e=i.extname(t).toLowerCase();return e===".glb"?"glb":e===".png"||e===".jpg"||e===".jpeg"||e===".webp"?"image":e===".hdr"?"hdr":null}a(V,"assetKindFor");function P(t,e){let n=i.relative(t,e);return (n!==""&&!n.startsWith("..")&&!i.isAbsolute(n)?n:e).split(i.sep).join("/")}a(P,"portable");var X;function ce(){return X??=Promise.all([import('ktx2-encoder'),import('@napi-rs/canvas')]).then(([t,e])=>({encodeToKTX2:t.encodeToKTX2,canvas:e})),X}a(ce,"loadEncoderTools");function me(t,e){let n=e.quality==="high";return t==="hdr"?{mode:"uastc-hdr",options:{isHDR:true,imageType:"hdr",isUASTC:true,isYFlip:true,generateMipmap:true,needSupercompression:true,hdrQualityLevel:n?2:1}}:t==="color"&&!n?{mode:"etc1s",options:{isUASTC:false,qualityLevel:160,compressionLevel:2,isPerceptual:true,isSRGB:true,generateMipmap:true}}:{mode:"uastc",options:{isUASTC:true,uastcLDRQualityLevel:n?2:1,enableRDO:true,rdoQualityLevel:1,generateMipmap:true,needSupercompression:true,isPerceptual:t==="color",isSRGB:t==="color",isNormalMap:t==="normal"}}}a(me,"encoderOptionsFor");function Le(t,e){let n=read(t),s=n.dataFormatDescriptor[0];if(s===void 0)return t;let r=e==="color"?le:de;return s.transferFunction===r&&(e!=="color"||s.colorPrimaries===KHR_DF_PRIMARIES_BT709)?t:(s.transferFunction=r,e==="color"&&(s.colorPrimaries=KHR_DF_PRIMARIES_BT709),write(n,{keepWriter:true}))}a(Le,"normalizeDfdTransfer");function he(t,e,n,s){let r=read(t),o=r.dataFormatDescriptor[0];if(o===void 0)throw new Error(`${s} produced a KTX2 container without a data format descriptor.`);if(e==="hdr"){if(r.vkFormat!==Se||o.colorModel!==Re)throw new Error(`${s} is not a UASTC HDR container (vkFormat ${r.vkFormat}, color model ${o.colorModel}).`)}else {let c=n==="etc1s"?Ee:ve;if(r.vkFormat!==0||o.colorModel!==c)throw new Error(`${s} is not a ${n} container (vkFormat ${r.vkFormat}, color model ${o.colorModel}).`)}let a=e==="color",u=o.transferFunction;if(a&&u!==le)throw new Error(`${s} must carry the sRGB transfer function; found ${u}.`);if(!a&&u!==de)throw new Error(`${s} must carry the linear transfer function; found ${u}.`);if(Math.max(r.pixelWidth,r.pixelHeight)>=8&&r.levels.length<2)throw new Error(`${s} is missing its mip chain.`);return {width:r.pixelWidth,height:r.pixelHeight,levels:r.levels.length}}a(he,"verifyKtx2");async function ye(t,e,n,s){let{encodeToKTX2:r,canvas:o}=await ce(),a$1=n.maxDimension,{mode:u,options:c}=me(e,n),d=performance.now(),m=false,p=Le(await r(t,{...c,imageDecoder:a(async M=>{let A=await o.loadImage(M),E=A.width,O=A.height;if(E<1||O<1)throw new Error(`${s} has no decodable dimensions.`);let x=Math.min(1,a$1/Math.max(E,O));E*x*O*x>ee&&(x=Math.sqrt(ee/(E*O)));let R=x<1,f=R?Math.max(4,Math.floor(E*x/4)*4):E,y=R?Math.max(4,Math.floor(O*x/4)*4):O,S=o.createCanvas(f,y).getContext("2d");S.imageSmoothingEnabled=true,S.imageSmoothingQuality="high",S.drawImage(A,0,0,f,y);let{data:h}=S.getImageData(0,0,f,y);for(let $=3;$<h.byteLength;$+=4)if(h[$]!==255){m=true;break}return {data:new Uint8Array(h.buffer,h.byteOffset,h.byteLength),width:f,height:y}},"decode")}),e),{width:g,height:v,levels:b}=he(p,e,u,s);return {bytes:p,width:g,height:v,levels:b,hasAlpha:m,mode:u,durationMs:performance.now()-d}}a(ye,"encodeLdrTexture");function Be(t,e){let n=new TextDecoder("latin1").decode(t.subarray(0,Math.min(t.byteLength,4096))),s=/-Y\s+(\d+)\s+\+X\s+(\d+)/u.exec(n);if(s?.[1]===void 0||s[2]===void 0)throw new Error(`${e} is not a supported Radiance .hdr file (missing "-Y <h> +X <w>" resolution).`);return {width:Number(s[2]),height:Number(s[1])}}a(Be,"hdrDimensions");async function ke(t,e,n){let s=Be(t,n);if(Math.max(s.width,s.height)>e.hdrMaxDimension)throw new Error(`${n} is ${s.width}x${s.height}, above the ${e.hdrMaxDimension}px HDR cap; resize the source (HDR resize is not supported yet).`);let{encodeToKTX2:r}=await ce(),{mode:o,options:a}=me("hdr",e),u=performance.now(),c=await r(t,a),{width:d,height:m,levels:T}=he(c,"hdr",o,n);return {bytes:c,width:d,height:m,levels:T,hasAlpha:false,mode:o,durationMs:performance.now()-u}}a(ke,"encodeHdrTexture");function pe(t,e,n,s){let r=0,o=t,a=e;for(let u=0;u<n;u+=1)r+=o*a*s,o=Math.max(1,o>>1),a=Math.max(1,a>>1);return r}a(pe,"uncompressedMipBytes");function q(t,e,n,s){let r=0,o=t,a=e;for(let u=0;u<n;u+=1)r+=Math.ceil(o/4)*Math.ceil(a/4)*s,o=Math.max(1,o>>1),a=Math.max(1,a>>1);return r}a(q,"compressedMipBytes");function fe(t,e){return t==="etc1s"&&!e?8:16}a(fe,"transcodedBlockBytes");async function Fe(t,e,n){let s=n.preset??De(e),r=`Image ${JSON.stringify(i.basename(e))}`,o=await ye(t,s,n,r),a=[`preset ${s} (${n.preset===null?"from filename":"explicit"})`];return s!=="color"&&a.push("linear DFD: consumers must treat this texture as non-color data"),a.push("compressed textures never flip: sample with glTF-style (flipY=false) UVs"),{bytes:o.bytes,metadata:{vramBytesIn:pe(o.width,o.height,o.levels,4),vramBytesOut:q(o.width,o.height,o.levels,fe(o.mode,o.hasAlpha)),textures:[{name:i.basename(e),slots:[],preset:s,mode:o.mode,width:o.width,height:o.height,bytesIn:t.byteLength,bytesOut:o.bytes.byteLength,durationMs:Math.round(o.durationMs)}],notes:a}}}a(Fe,"buildImageAsset");async function Pe(t,e,n){let s=`Environment ${JSON.stringify(i.basename(e))}`,r=await ke(t,n,s);return {bytes:r.bytes,metadata:{vramBytesIn:r.width*r.height*8,vramBytesOut:q(r.width,r.height,r.levels,16),textures:[{name:i.basename(e),slots:["equirectangular"],preset:"hdr",mode:r.mode,width:r.width,height:r.height,bytesIn:t.byteLength,bytesOut:r.bytes.byteLength,durationMs:Math.round(r.durationMs)}],notes:["BC6H on BC-capable devices; transcodes to RGBA16F elsewhere"]}}}a(Pe,"buildHdrAsset");async function Ne(t,e,n,s){let[{Logger:r,NodeIO:o},{ALL_EXTENSIONS:a,KHRTextureBasisu:u},{dedup:c,listTextureSlots:d,meshopt:m,prune:T,weld:p},{MeshoptDecoder:g,MeshoptEncoder:v}]=await Promise.all([import('@gltf-transform/core'),import('@gltf-transform/extensions'),import('./asset-transforms-ZVZ4RD4L.js'),import('meshoptimizer')]);await v.ready,await g.ready;let b=new o().registerExtensions(a).registerDependencies({"meshopt.encoder":v,"meshopt.decoder":g}),M=`GLB ${JSON.stringify(i.basename(e))}`;b.setLogger(new r(r.Verbosity.SILENT));let A=await b.readBinary(t);A.setLogger(new r(r.Verbosity.SILENT));let E=A.getRoot().listTextures();if(E.length>0&&E.every(h=>h.getMimeType()==="image/ktx2")&&A.getRoot().listExtensionsUsed().some(h=>h.extensionName==="EXT_meshopt_compression"))return {bytes:t,metadata:{vramBytesIn:0,vramBytesOut:0,textures:[],notes:["already optimized (KTX2 + meshopt); copied unchanged"]}};s?.("optimizing geometry"),await A.transform(c(),T({keepAttributes:true,keepExtras:true,keepSolidTextures:true}),p(),m({encoder:v,level:"medium"}));let x=[],R=[],f=0,y=0,_=0;for(let h of E){let $=h.getName()||h.getURI()||`texture-${x.length}`,D=h.getImage(),k=h.getMimeType();if(D===null||D.byteLength===0)continue;if(k==="image/ktx2"){R.push(`${$}: already KTX2, kept`);continue}if(!/^image\/(?:png|jpeg|webp)$/u.test(k)){R.push(`${$}: unsupported ${k}, kept`);continue}let z=h.getSize();if(z!==null&&Math.max(z[0],z[1])<te){R.push(`${$}: below ${te}px, kept`);continue}let W=d(h),j=_e(W);s?.(`encoding ${$} (${j})`);let w=await ye(new Uint8Array(D),j,n,`${M} texture ${JSON.stringify($)}`);h.setImage(w.bytes).setMimeType("image/ktx2");let G=h.getURI();G!==""&&h.setURI(G.replace(/\.(?:png|jpe?g|webp)$/iu,".ktx2")),_+=1,f+=pe(w.width,w.height,w.levels,4),y+=q(w.width,w.height,w.levels,fe(w.mode,w.hasAlpha)),x.push({name:$,slots:W,preset:j,mode:w.mode,width:w.width,height:w.height,bytesIn:D.byteLength,bytesOut:w.bytes.byteLength,durationMs:Math.round(w.durationMs)});}_>0&&A.createExtension(u).setRequired(true);let S=await b.writeBinary(A);return await b.readBinary(S),_>0&&R.push("requires a KTX2-wired loader (three-blocks/assets or GLTFLoader.setKTX2Loader)"),{bytes:S,metadata:{vramBytesIn:f,vramBytesOut:y,textures:x,notes:R}}}a(Ne,"buildGlbAsset");function Ce(t,e,n){let s=i.basename(t,i.extname(t));if(e==="glb"){let r=n===null?i.join(i.dirname(t),`${s}.tb.glb`):i.join(n,`${s}.glb`);if(i.resolve(r)===i.resolve(t))throw new Error(`Output would overwrite the input: ${JSON.stringify(t)}. Pass a different output directory.`);return r}return i.join(n??i.dirname(t),`${s}.ktx2`)}a(Ce,"outputPathFor");async function ge(t){let e={schemaVersion:U,tool:{name:"three-blocks-devtools",assetOptimizeVersion:U,encoder:ie},assets:{}},n;try{n=await readFile(t,"utf8");}catch(s){if(b(s)==="ENOENT")return e;throw s}if(n.length>a$1.receipt)return e;try{let s=JSON.parse(n);if(typeof s!="object"||s===null)return e;let r=s;return r.schemaVersion!==U||typeof r.assets!="object"||r.assets===null?e:{...e,assets:{...r.assets}}}catch{return e}}a(ge,"readReceipt");async function Ue(t){let e=[];for(let n of t){let s=i.resolve(n);if((await lstat(s)).isDirectory()){let o=[s],a=0;for(;o.length>0;){let u=o.shift();if(u===void 0)break;let c=(await readdir(u,{withFileTypes:true})).sort((d,m)=>d.name.localeCompare(m.name));for(let d of c){if(a+=1,a>8192)throw new Error("Input directory expansion exceeds the 8192-entry limit.");if(d.isSymbolicLink()||d.name.startsWith("."))continue;let m=i.join(u,d.name);if(d.isDirectory()){d.name!=="three-blocks"&&o.push(m);continue}d.isFile()&&!d.name.endsWith(".tb.glb")&&V(d.name)!==null&&e.push(m);}}}else e.push(s);}if(e.length===0)throw new Error("No optimizable inputs found (.glb, .png, .jpg, .webp, .hdr).");return e}a(Ue,"expandInputs");async function Ve(t){let e=await realpath(t.root),n={maxDimension:ne(t.maxDimension,2048),hdrMaxDimension:ne(t.hdrMaxDimension,4096),quality:t.quality??"default",preset:t.preset??null},s=t.outDir===void 0?null:i.resolve(e,t.outDir);s!==null&&await mkdir(s,{recursive:true});let r=i.join(e,we),o=i.join(e,ue),a$2=c(h({version:U,encoder:ie,...n})),u=await Ue(t.inputs),c$1=[],d$1=[],m=await ge(o);for(let[T,p]of u.entries()){let g=V(p);try{if(g===null)throw new Error(`Unsupported asset type ${JSON.stringify(i.extname(p))}; expected .glb, .png, .jpg, .webp, or .hdr (EXR sources are not supported yet \u2014 convert environments to .hdr).`);t.onProgress?.(`${i.basename(p)} (${T+1}/${u.length})`);let v=g==="glb"?Te:g==="hdr"?Ae:a$1.texture,b=await h$1(p,v,"Asset input"),M=b.path,A=c(b.data),E=c(`${A}\0${a$2}`),O=g==="glb"?"glb":"ktx2",x=i.join(r,`${E}.${O}`),R=i.join(r,`${E}.json`),f$1,y,_=!1;if(t.force!==!0&&await d(x)&&await d(R))f$1=(await h$1(x,v,"Cached asset")).data,y=JSON.parse((await h$1(R,a$1.metadata,"Cached asset metadata")).data.toString("utf8")),_=!0;else {let $=a(k=>t.onProgress?.(`${i.basename(p)}: ${k}`),"progress"),D=g==="glb"?await Ne(b.data,M,n,$):g==="hdr"?await Pe(b.data,M,n):await Fe(b.data,M,n);f$1=D.bytes,y=D.metadata,await f(x,f$1),await f(R,`${JSON.stringify(y,null," ")}
2
- `);}let S=Ce(M,g,s);await mkdir(i.dirname(S),{recursive:!0}),await f(S,f$1);let h=c(f$1);m.assets[P(e,M)]={kind:g,inputSha256:A,output:P(e,S),outputSha256:h,settingsSha256:a$2,bytesIn:b.data.byteLength,bytesOut:f$1.byteLength,vramBytesIn:y.vramBytesIn,vramBytesOut:y.vramBytesOut},c$1.push({input:P(e,M),output:P(e,S),kind:g,cached:_,bytesIn:b.data.byteLength,bytesOut:f$1.byteLength,vramBytesIn:y.vramBytesIn,vramBytesOut:y.vramBytesOut,textures:y.textures,notes:y.notes});}catch(v){d$1.push({input:P(e,p),error:v instanceof Error?v.message:String(v)});}}return c$1.length>0&&await f(o,`${JSON.stringify(m,null," ")}
1
+ import {i as i$1}from'./chunk-UDMY6S4M.js';import {b,a as a$1,c,h,d,f}from'./chunk-ECQE4D2U.js';import {a}from'./chunk-7X4DHW36.js';import {readFile,lstat,readdir,realpath,mkdir}from'fs/promises';import i from'path';import {read,KHR_DF_PRIMARIES_BT709,write}from'ktx-parse';var U=2,ie="ktx2-encoder@0.6.0;@napi-rs/canvas@1.0.9",ae=i.join(".three-blocks","assets"),ue=i.join(ae,"meta.json"),we=i.join(ae,"cache"),Te=256*1024*1024,Ae=64*1024*1024,ee=115e5,te=64,Ee=163,ve=166,Re=167,Se=1000066e3,de=1,le=2,$e=/baseColor|emissive|diffuse|sheenColor|specularColor/u,Me=/normal/iu,Oe=/(?:^|[_\-.])(?:normal|nrm|nor)(?:[_\-.]|map|$)/iu,Ie=/(?:rough|metal|orm\b|occlusion|ambient|[_\-.]ao(?:[_\-.]|$)|height|disp|thick|mask)/iu;function _e(t){return t.some(e=>Me.test(e))?"normal":t.some(e=>$e.test(e))||t.length===0?"color":"data"}a(_e,"presetForTextureSlots");function De(t){let e=i.basename(t);return Oe.test(e)?"normal":Ie.test(e)?"data":"color"}a(De,"presetForImageName");function V(t){let e=i.extname(t).toLowerCase();return e===".glb"?"glb":e===".png"||e===".jpg"||e===".jpeg"||e===".webp"?"image":e===".hdr"?"hdr":null}a(V,"assetKindFor");function P(t,e){let n=i.relative(t,e);return (n!==""&&!n.startsWith("..")&&!i.isAbsolute(n)?n:e).split(i.sep).join("/")}a(P,"portable");var X;function ce(){return X??=Promise.all([import('ktx2-encoder'),import('@napi-rs/canvas')]).then(([t,e])=>({encodeToKTX2:t.encodeToKTX2,canvas:e})),X}a(ce,"loadEncoderTools");function me(t,e){let n=e.quality==="high";return t==="hdr"?{mode:"uastc-hdr",options:{isHDR:true,imageType:"hdr",isUASTC:true,isYFlip:true,generateMipmap:true,needSupercompression:true,hdrQualityLevel:n?2:1}}:t==="color"&&!n?{mode:"etc1s",options:{isUASTC:false,qualityLevel:160,compressionLevel:2,isPerceptual:true,isSRGB:true,generateMipmap:true}}:{mode:"uastc",options:{isUASTC:true,uastcLDRQualityLevel:n?2:1,enableRDO:true,rdoQualityLevel:1,generateMipmap:true,needSupercompression:true,isPerceptual:t==="color",isSRGB:t==="color",isNormalMap:t==="normal"}}}a(me,"encoderOptionsFor");function Le(t,e){let n=read(t),s=n.dataFormatDescriptor[0];if(s===void 0)return t;let r=e==="color"?le:de;return s.transferFunction===r&&(e!=="color"||s.colorPrimaries===KHR_DF_PRIMARIES_BT709)?t:(s.transferFunction=r,e==="color"&&(s.colorPrimaries=KHR_DF_PRIMARIES_BT709),write(n,{keepWriter:true}))}a(Le,"normalizeDfdTransfer");function he(t,e,n,s){let r=read(t),o=r.dataFormatDescriptor[0];if(o===void 0)throw new Error(`${s} produced a KTX2 container without a data format descriptor.`);if(e==="hdr"){if(r.vkFormat!==Se||o.colorModel!==Re)throw new Error(`${s} is not a UASTC HDR container (vkFormat ${r.vkFormat}, color model ${o.colorModel}).`)}else {let c=n==="etc1s"?Ee:ve;if(r.vkFormat!==0||o.colorModel!==c)throw new Error(`${s} is not a ${n} container (vkFormat ${r.vkFormat}, color model ${o.colorModel}).`)}let a=e==="color",u=o.transferFunction;if(a&&u!==le)throw new Error(`${s} must carry the sRGB transfer function; found ${u}.`);if(!a&&u!==de)throw new Error(`${s} must carry the linear transfer function; found ${u}.`);if(Math.max(r.pixelWidth,r.pixelHeight)>=8&&r.levels.length<2)throw new Error(`${s} is missing its mip chain.`);return {width:r.pixelWidth,height:r.pixelHeight,levels:r.levels.length}}a(he,"verifyKtx2");async function ye(t,e,n,s){let{encodeToKTX2:r,canvas:o}=await ce(),a$1=n.maxDimension,{mode:u,options:c}=me(e,n),d=performance.now(),m=false,p=Le(await r(t,{...c,imageDecoder:a(async M=>{let A=await o.loadImage(M),E=A.width,O=A.height;if(E<1||O<1)throw new Error(`${s} has no decodable dimensions.`);let x=Math.min(1,a$1/Math.max(E,O));E*x*O*x>ee&&(x=Math.sqrt(ee/(E*O)));let R=x<1,f=R?Math.max(4,Math.floor(E*x/4)*4):E,y=R?Math.max(4,Math.floor(O*x/4)*4):O,S=o.createCanvas(f,y).getContext("2d");S.imageSmoothingEnabled=true,S.imageSmoothingQuality="high",S.drawImage(A,0,0,f,y);let{data:h}=S.getImageData(0,0,f,y);for(let $=3;$<h.byteLength;$+=4)if(h[$]!==255){m=true;break}return {data:new Uint8Array(h.buffer,h.byteOffset,h.byteLength),width:f,height:y}},"decode")}),e),{width:g,height:v,levels:b}=he(p,e,u,s);return {bytes:p,width:g,height:v,levels:b,hasAlpha:m,mode:u,durationMs:performance.now()-d}}a(ye,"encodeLdrTexture");function Be(t,e){let n=new TextDecoder("latin1").decode(t.subarray(0,Math.min(t.byteLength,4096))),s=/-Y\s+(\d+)\s+\+X\s+(\d+)/u.exec(n);if(s?.[1]===void 0||s[2]===void 0)throw new Error(`${e} is not a supported Radiance .hdr file (missing "-Y <h> +X <w>" resolution).`);return {width:Number(s[2]),height:Number(s[1])}}a(Be,"hdrDimensions");async function ke(t,e,n){let s=Be(t,n);if(Math.max(s.width,s.height)>e.hdrMaxDimension)throw new Error(`${n} is ${s.width}x${s.height}, above the ${e.hdrMaxDimension}px HDR cap; resize the source (HDR resize is not supported yet).`);let{encodeToKTX2:r}=await ce(),{mode:o,options:a}=me("hdr",e),u=performance.now(),c=await r(t,a),{width:d,height:m,levels:T}=he(c,"hdr",o,n);return {bytes:c,width:d,height:m,levels:T,hasAlpha:false,mode:o,durationMs:performance.now()-u}}a(ke,"encodeHdrTexture");function pe(t,e,n,s){let r=0,o=t,a=e;for(let u=0;u<n;u+=1)r+=o*a*s,o=Math.max(1,o>>1),a=Math.max(1,a>>1);return r}a(pe,"uncompressedMipBytes");function q(t,e,n,s){let r=0,o=t,a=e;for(let u=0;u<n;u+=1)r+=Math.ceil(o/4)*Math.ceil(a/4)*s,o=Math.max(1,o>>1),a=Math.max(1,a>>1);return r}a(q,"compressedMipBytes");function fe(t,e){return t==="etc1s"&&!e?8:16}a(fe,"transcodedBlockBytes");async function Fe(t,e,n){let s=n.preset??De(e),r=`Image ${JSON.stringify(i.basename(e))}`,o=await ye(t,s,n,r),a=[`preset ${s} (${n.preset===null?"from filename":"explicit"})`];return s!=="color"&&a.push("linear DFD: consumers must treat this texture as non-color data"),a.push("compressed textures never flip: sample with glTF-style (flipY=false) UVs"),{bytes:o.bytes,metadata:{vramBytesIn:pe(o.width,o.height,o.levels,4),vramBytesOut:q(o.width,o.height,o.levels,fe(o.mode,o.hasAlpha)),textures:[{name:i.basename(e),slots:[],preset:s,mode:o.mode,width:o.width,height:o.height,bytesIn:t.byteLength,bytesOut:o.bytes.byteLength,durationMs:Math.round(o.durationMs)}],notes:a}}}a(Fe,"buildImageAsset");async function Pe(t,e,n){let s=`Environment ${JSON.stringify(i.basename(e))}`,r=await ke(t,n,s);return {bytes:r.bytes,metadata:{vramBytesIn:r.width*r.height*8,vramBytesOut:q(r.width,r.height,r.levels,16),textures:[{name:i.basename(e),slots:["equirectangular"],preset:"hdr",mode:r.mode,width:r.width,height:r.height,bytesIn:t.byteLength,bytesOut:r.bytes.byteLength,durationMs:Math.round(r.durationMs)}],notes:["BC6H on BC-capable devices; transcodes to RGBA16F elsewhere"]}}}a(Pe,"buildHdrAsset");async function Ne(t,e,n,s){let[{Logger:r,NodeIO:o},{ALL_EXTENSIONS:a,KHRTextureBasisu:u},{dedup:c,listTextureSlots:d,meshopt:m,prune:T,weld:p},{MeshoptDecoder:g,MeshoptEncoder:v}]=await Promise.all([import('@gltf-transform/core'),import('@gltf-transform/extensions'),import('./asset-transforms-ZVZ4RD4L.js'),import('meshoptimizer')]);await v.ready,await g.ready;let b=new o().registerExtensions(a).registerDependencies({"meshopt.encoder":v,"meshopt.decoder":g}),M=`GLB ${JSON.stringify(i.basename(e))}`;b.setLogger(new r(r.Verbosity.SILENT));let A=await b.readBinary(t);A.setLogger(new r(r.Verbosity.SILENT));let E=A.getRoot().listTextures();if(E.length>0&&E.every(h=>h.getMimeType()==="image/ktx2")&&A.getRoot().listExtensionsUsed().some(h=>h.extensionName==="EXT_meshopt_compression"))return {bytes:t,metadata:{vramBytesIn:0,vramBytesOut:0,textures:[],notes:["already optimized (KTX2 + meshopt); copied unchanged"]}};s?.("optimizing geometry"),await A.transform(c(),T({keepAttributes:true,keepExtras:true,keepSolidTextures:true}),p(),m({encoder:v,level:"medium"}));let x=[],R=[],f=0,y=0,_=0;for(let h of E){let $=h.getName()||h.getURI()||`texture-${x.length}`,D=h.getImage(),k=h.getMimeType();if(D===null||D.byteLength===0)continue;if(k==="image/ktx2"){R.push(`${$}: already KTX2, kept`);continue}if(!/^image\/(?:png|jpeg|webp)$/u.test(k)){R.push(`${$}: unsupported ${k}, kept`);continue}let z=h.getSize();if(z!==null&&Math.max(z[0],z[1])<te){R.push(`${$}: below ${te}px, kept`);continue}let W=d(h),j=_e(W);s?.(`encoding ${$} (${j})`);let w=await ye(new Uint8Array(D),j,n,`${M} texture ${JSON.stringify($)}`);h.setImage(w.bytes).setMimeType("image/ktx2");let G=h.getURI();G!==""&&h.setURI(G.replace(/\.(?:png|jpe?g|webp)$/iu,".ktx2")),_+=1,f+=pe(w.width,w.height,w.levels,4),y+=q(w.width,w.height,w.levels,fe(w.mode,w.hasAlpha)),x.push({name:$,slots:W,preset:j,mode:w.mode,width:w.width,height:w.height,bytesIn:D.byteLength,bytesOut:w.bytes.byteLength,durationMs:Math.round(w.durationMs)});}_>0&&A.createExtension(u).setRequired(true);let S=await b.writeBinary(A);return await b.readBinary(S),_>0&&R.push("requires a KTX2-wired loader (three-blocks/assets or GLTFLoader.setKTX2Loader)"),{bytes:S,metadata:{vramBytesIn:f,vramBytesOut:y,textures:x,notes:R}}}a(Ne,"buildGlbAsset");function Ce(t,e,n){let s=i.basename(t,i.extname(t));if(e==="glb"){let r=n===null?i.join(i.dirname(t),`${s}.tb.glb`):i.join(n,`${s}.glb`);if(i.resolve(r)===i.resolve(t))throw new Error(`Output would overwrite the input: ${JSON.stringify(t)}. Pass a different output directory.`);return r}return i.join(n??i.dirname(t),`${s}.ktx2`)}a(Ce,"outputPathFor");async function ge(t){let e={schemaVersion:U,tool:{name:"three-blocks-devtools",assetOptimizeVersion:U,encoder:ie},assets:{}},n;try{n=await readFile(t,"utf8");}catch(s){if(b(s)==="ENOENT")return e;throw s}if(n.length>a$1.receipt)return e;try{let s=JSON.parse(n);if(typeof s!="object"||s===null)return e;let r=s;return r.schemaVersion!==U||typeof r.assets!="object"||r.assets===null?e:{...e,assets:{...r.assets}}}catch{return e}}a(ge,"readReceipt");async function Ue(t){let e=[];for(let n of t){let s=i.resolve(n);if((await lstat(s)).isDirectory()){let o=[s],a=0;for(;o.length>0;){let u=o.shift();if(u===void 0)break;let c=(await readdir(u,{withFileTypes:true})).sort((d,m)=>d.name.localeCompare(m.name));for(let d of c){if(a+=1,a>8192)throw new Error("Input directory expansion exceeds the 8192-entry limit.");if(d.isSymbolicLink()||d.name.startsWith("."))continue;let m=i.join(u,d.name);if(d.isDirectory()){d.name!=="three-blocks"&&o.push(m);continue}d.isFile()&&!d.name.endsWith(".tb.glb")&&V(d.name)!==null&&e.push(m);}}}else e.push(s);}if(e.length===0)throw new Error("No optimizable inputs found (.glb, .png, .jpg, .webp, .hdr).");return e}a(Ue,"expandInputs");async function Ve(t){let e=await realpath(t.root),n={maxDimension:ne(t.maxDimension,2048),hdrMaxDimension:ne(t.hdrMaxDimension,4096),quality:t.quality??"default",preset:t.preset??null},s=t.outDir===void 0?null:i.resolve(e,t.outDir);s!==null&&await mkdir(s,{recursive:true});let r=i.join(e,we),o=i.join(e,ue),a$2=c(i$1({version:U,encoder:ie,...n})),u=await Ue(t.inputs),c$1=[],d$1=[],m=await ge(o);for(let[T,p]of u.entries()){let g=V(p);try{if(g===null)throw new Error(`Unsupported asset type ${JSON.stringify(i.extname(p))}; expected .glb, .png, .jpg, .webp, or .hdr (EXR sources are not supported yet \u2014 convert environments to .hdr).`);t.onProgress?.(`${i.basename(p)} (${T+1}/${u.length})`);let v=g==="glb"?Te:g==="hdr"?Ae:a$1.texture,b=await h(p,v,"Asset input"),M=b.path,A=c(b.data),E=c(`${A}\0${a$2}`),O=g==="glb"?"glb":"ktx2",x=i.join(r,`${E}.${O}`),R=i.join(r,`${E}.json`),f$1,y,_=!1;if(t.force!==!0&&await d(x)&&await d(R))f$1=(await h(x,v,"Cached asset")).data,y=JSON.parse((await h(R,a$1.metadata,"Cached asset metadata")).data.toString("utf8")),_=!0;else {let $=a(k=>t.onProgress?.(`${i.basename(p)}: ${k}`),"progress"),D=g==="glb"?await Ne(b.data,M,n,$):g==="hdr"?await Pe(b.data,M,n):await Fe(b.data,M,n);f$1=D.bytes,y=D.metadata,await f(x,f$1),await f(R,`${JSON.stringify(y,null," ")}
2
+ `);}let S=Ce(M,g,s);await mkdir(i.dirname(S),{recursive:!0}),await f(S,f$1);let h$1=c(f$1);m.assets[P(e,M)]={kind:g,inputSha256:A,output:P(e,S),outputSha256:h$1,settingsSha256:a$2,bytesIn:b.data.byteLength,bytesOut:f$1.byteLength,vramBytesIn:y.vramBytesIn,vramBytesOut:y.vramBytesOut},c$1.push({input:P(e,M),output:P(e,S),kind:g,cached:_,bytesIn:b.data.byteLength,bytesOut:f$1.byteLength,vramBytesIn:y.vramBytesIn,vramBytesOut:y.vramBytesOut,textures:y.textures,notes:y.notes});}catch(v){d$1.push({input:P(e,p),error:v instanceof Error?v.message:String(v)});}}return c$1.length>0&&await f(o,`${JSON.stringify(m,null," ")}
3
3
  `),{schemaVersion:1,command:"assets optimize",root:e,results:c$1,failed:d$1,bytesIn:c$1.reduce((T,p)=>T+p.bytesIn,0),bytesOut:c$1.reduce((T,p)=>T+p.bytesOut,0)}}a(Ve,"optimizeAssets");function ne(t,e){if(t===void 0)return e;if(!Number.isInteger(t)||t<64||t>16384)throw new Error("Texture dimension caps must be integers between 64 and 16384.");return t}a(ne,"boundedDimension");function I(t){if(t<1e3)return `${t} B`;if(t<1e6){let n=t/1e3;return `${n>=100?Math.round(n):n.toFixed(1)} kB`}let e=t/1e6;return `${e>=100?Math.round(e):e.toFixed(2)} MB`}a(I,"formatBytes");function re(t,e){if(t===0)return "";let n=Math.round((e-t)/t*100);return n===0?"":` (${n>0?"+":""}${n}%)`}a(re,"percentDelta");function qe(t){let e=[];for(let n of t.results){let s=n.cached?" \xB7 cached":"";e.push(`${n.input} -> ${n.output}`),e.push(` ${I(n.bytesIn)} -> ${I(n.bytesOut)}${re(n.bytesIn,n.bytesOut)}${s}`),n.vramBytesOut>0&&e.push(` VRAM \u2248 ${I(n.vramBytesIn)} -> ${I(n.vramBytesOut)}`);for(let r of n.textures){let o=r.slots.length>0?` [${r.slots.join(", ")}]`:"";e.push(` ${r.name}${o} ${r.preset}/${r.mode} ${r.width}x${r.height} ${I(r.bytesIn)} -> ${I(r.bytesOut)}`);}for(let r of n.notes)e.push(` note: ${r}`);}for(let n of t.failed)e.push(`failed ${n.input}: ${n.error}`);return t.results.length>1&&e.push(`total ${I(t.bytesIn)} -> ${I(t.bytesOut)}${re(t.bytesIn,t.bytesOut)}`),e.join(`
4
4
  `)}a(qe,"formatAssetOptimizeReport");async function We(t,e){let n=await realpath(t),s=i.resolve(n,e);if(!await d(s))return [];let r=[],o=[s],a=0;for(;o.length>0;){let u=o.shift();if(u===void 0)break;let c=(await readdir(u,{withFileTypes:true})).sort((d,m)=>d.name.localeCompare(m.name));for(let d of c){if(a+=1,a>8192)throw new Error("Public asset discovery exceeds the 8192-entry limit.");if(d.isSymbolicLink()||d.name.startsWith("."))continue;let m=i.join(u,d.name);if(d.isDirectory()){if(u===s&&d.name==="three-blocks")continue;o.push(m);continue}if(!d.isFile()||d.name.endsWith(".tb.glb"))continue;let T=V(d.name);(T==="glb"||T==="hdr")&&r.push(m);}}return r.sort()}a(We,"discoverPublicAssets");async function Ge(t){let e=await realpath(t),n=await ge(i.join(e,ue)),s=[];for(let[r,o]of Object.entries(n.assets).sort(([a],[u])=>a.localeCompare(u))){let a=i.resolve(e,r),u=i.resolve(e,o.output),c$1="fresh";if(!await d(a))c$1="missing-input";else if(!await d(u))c$1="missing-output";else {let[d,m]=await Promise.all([readFile(a),readFile(u)]);(c(d)!==o.inputSha256||c(m)!==o.outputSha256)&&(c$1="stale");}s.push({input:r,output:o.output,kind:o.kind,state:c$1});}return {schemaVersion:1,command:"assets status",root:e,state:s.length===0?"empty":s.every(r=>r.state==="fresh")?"fresh":"stale",entries:s}}a(Ge,"inspectAssets");function Je(t){if(t.state==="empty")return "No optimized assets recorded. Run `assets optimize <file|directory>` first.";let e=t.entries.map(n=>`${n.state==="fresh"?"fresh ":n.state.padEnd(14)} ${n.input} -> ${n.output}`);return t.state==="stale"&&e.push("Some assets moved or changed; re-run `assets optimize` on the stale inputs."),e.join(`
5
5
  `)}a(Je,"formatAssetStatusReport");function Ye(){X=void 0;}a(Ye,"resetAssetOptimizeToolsForTests");export{U as a,ae as b,ue as c,_e as d,De as e,Ve as f,qe as g,We as h,Ge as i,Je as j,Ye as k};
@@ -0,0 +1,16 @@
1
+ import {a as a$2}from'./chunk-TK566QET.js';import {e as e$1,g}from'./chunk-75JSWKB4.js';import {a as a$1,c as c$2}from'./chunk-WNSGAV6N.js';import {c,d,f,e,i}from'./chunk-ECQE4D2U.js';import {a}from'./chunk-7X4DHW36.js';import {threeShaderCompatibilityId,parsePrecompiledManifest,SHADER_HYDRATION_SCHEMA_VERSION,SHADER_RECIPE_SCHEMA_VERSION,SHADER_ADDRESS_SCHEMA_VERSION,PRECOMPILED_MANIFEST_VERSION}from'three-blocks/shaders';import {lstat,readFile,unlink,mkdir,readdir}from'fs/promises';import c$1 from'path';function F(e,r="webgpu"){let t=threeShaderCompatibilityId(e,r);if(t!==void 0)return t;throw new Error(`Three.js ${e} is outside the supported shader compatibility contracts.`)}a(F,"shaderCompatibilityForThree");var ge=65,W="timing.local.json",z="timing.json",K="parity.json",T=4096,Se=4096;function we(e){let r=a(i=>{let s=e[i];return typeof s=="number"&&Number.isSafeInteger(s)&&s>=0?s:void 0},"count"),t=r("stateChecked");if(t===void 0||t===0)return {};let n=e.stateDifferences;return {stateOracle:{checked:t,equivalent:r("stateEquivalent")??0,identical:r("stateIdentical")??0,recreated:r("stateRecreated")??0,differences:Array.isArray(n)?n.filter(i=>typeof i=="string").slice(0,40):[]}}}a(we,"parseShaderStateOracle");function U(e,r,t=8192){if(typeof e!="string"||e.length===0||e.length>t||/[\u0000\u007f]/u.test(e))throw new Error(`${r} must be a bounded non-empty string.`);return e}a(U,"boundedString");function u(e,r,t=true){if(typeof e!="number"||!Number.isFinite(e)||e<0||t&&!Number.isSafeInteger(e))throw new Error(`${r} must be a non-negative ${t?"integer":"finite number"}.`);return e}a(u,"nonNegativeNumber");function be(e){if(!a$1(e))throw new Error("Shader capture stats are missing.");let r={buildCalls:u(e.buildCalls,"capture stats.buildCalls"),renderBuilds:u(e.renderBuilds,"capture stats.renderBuilds"),computeBuilds:u(e.computeBuilds,"capture stats.computeBuilds"),registeredBuilds:u(e.registeredBuilds,"capture stats.registeredBuilds"),registeredRenderBuilds:u(e.registeredRenderBuilds,"capture stats.registeredRenderBuilds"),registeredComputeBuilds:u(e.registeredComputeBuilds,"capture stats.registeredComputeBuilds"),buildMs:u(e.buildMs,"capture stats.buildMs",false),syncBuildMs:u(e.syncBuildMs,"capture stats.syncBuildMs",false),asyncBuildElapsedMs:u(e.asyncBuildElapsedMs,"capture stats.asyncBuildElapsedMs",false),precompiledSetupMs:u(e.precompiledSetupMs,"capture stats.precompiledSetupMs",false),maxSyncBuildMs:u(e.maxSyncBuildMs??e.syncBuildMs,"capture stats.maxSyncBuildMs",false),maxPrecompiledSetupMs:u(e.maxPrecompiledSetupMs??e.precompiledSetupMs,"capture stats.maxPrecompiledSetupMs",false),hydrationMs:u(e.hydrationMs??0,"capture stats.hydrationMs",false),maxHydrationMs:u(e.maxHydrationMs??e.hydrationMs??0,"capture stats.maxHydrationMs",false),injected:u(e.injected,"capture stats.injected"),injectedRender:u(e.injectedRender,"capture stats.injectedRender"),injectedCompute:u(e.injectedCompute,"capture stats.injectedCompute"),missed:u(e.missed,"capture stats.missed"),missedRender:u(e.missedRender,"capture stats.missedRender"),missedCompute:u(e.missedCompute,"capture stats.missedCompute"),...Array.isArray(e.missedKeys)&&e.missedKeys.every(t=>typeof t=="string")?{missedKeys:e.missedKeys.slice(0,T)}:{},...we(e)};if(r.renderBuilds+r.computeBuilds!==r.buildCalls||r.registeredRenderBuilds+r.registeredComputeBuilds!==r.registeredBuilds||r.injectedRender+r.injectedCompute!==r.injected||r.missedRender+r.missedCompute!==r.missed||r.registeredBuilds>r.buildCalls||Math.abs(r.syncBuildMs+r.asyncBuildElapsedMs-r.buildMs)>.001||r.maxSyncBuildMs>r.syncBuildMs+.001||r.maxPrecompiledSetupMs>r.precompiledSetupMs+.001||r.maxHydrationMs>r.hydrationMs+.001)throw new Error("Shader capture stats totals are inconsistent.");return r}a(be,"captureStats");function Ee(e){if(!Array.isArray(e)||e.length>T)throw new Error("Shader capture skipped builds are invalid.");return e.map((r,t)=>{if(!a$1(r)||r.kind!=="render"&&r.kind!=="compute")throw new Error(`Shader capture skipped build ${t} is invalid.`);return {kind:r.kind,name:U(r.name,`skipped build ${t} name`,512),reason:U(r.reason,`skipped build ${t} reason`)}})}a(Ee,"skippedBuilds");function Re(e){let r=0,t=0,n=0,i=0;for(let s of Object.values(e.entries)){let o=e.states[s];o!==void 0&&((o.vertex!==null||o.fragment!==null)&&r++,o.vertex!==null&&t++,o.fragment!==null&&n++,o.compute!==null&&i++);}return {render:r,vertex:t,fragment:n,compute:i}}a(Re,"shaderCoverage");function Ve(e,r){if(!a$1(e))throw new Error("Shader capture payload must be an object.");if(e.scene!==r.scene)throw new Error(`Shader capture scene does not match "${r.scene}".`);if(e.protocolVersion!==2)throw new Error("Shader capture protocolVersion must be 2.");let t=r.backend??"webgpu",n=F(r.runtime.three,t);if(e.compatibility!==n)throw new Error(`Shader capture compatibility must be "${n}".`);if(!a$1(e.entries))throw new Error("Shader capture entries must be an object.");if(typeof e.requiresSetup!="boolean")throw new Error("Shader capture requiresSetup must be boolean.");let i=Object.keys(e.entries).length;if(i>T)throw new Error(`Shader capture must contain at most ${T} entries.`);if(!Array.isArray(e.errors)||e.errors.length>Se)throw new Error("Shader capture errors are invalid.");let s=e.errors.map((w,a)=>U(w,`capture error ${a}`,64*1024));if(s.length>0)throw new Error(`Shader capture failed:
2
+ - ${s.join(`
3
+ - `)}`);let o=Ee(e.skipped);if(i===0&&(t!=="webgl"||o.length===0))throw new Error("Shader capture must contain an entry unless WebGL explicitly skipped every live build.");let l=be(e.stats),p=a$1(e.timing)?e.timing:void 0,y=p===void 0?void 0:Object.fromEntries(["launch","firstRequest","readiness","lastBuild","settled","posted"].flatMap(w=>{let a=p[w];if(a===void 0)return [];if(typeof a!="number"||!Number.isFinite(a)||a<0)throw new Error(`Shader capture timing.${w} is invalid.`);return [[w,a]]})),m;if(e.provenance!==void 0){if(!a$1(e.provenance)||typeof e.provenance.userAgent!="string"||e.provenance.userAgent.length>1024||typeof e.provenance.adapter!="string"||e.provenance.adapter.length>1024||!Array.isArray(e.provenance.features)||e.provenance.features.length>256||!e.provenance.features.every(w=>typeof w=="string"&&w.length<=128))throw new Error("Shader capture provenance is invalid.");m={userAgent:e.provenance.userAgent,adapter:e.provenance.adapter,features:[...new Set(e.provenance.features)].sort()};}let R=parsePrecompiledManifest({version:PRECOMPILED_MANIFEST_VERSION,scene:r.scene,three:r.runtime.three,threeBlocks:r.runtime.threeBlocks,runtime:{id:n,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},...e.automatic===void 0?{}:{automatic:e.automatic},requiresSetup:e.requiresSetup,modules:e.modules,nodes:e.nodes,layouts:e.layouts,attributePlans:e.attributePlans,updatePlans:e.updatePlans,requirementPlans:e.requirementPlans,states:e.states,entries:e.entries,...e.fallbacks===void 0?{}:{fallbacks:e.fallbacks}}),S=Re(R);if(l.registeredRenderBuilds<S.render||l.registeredComputeBuilds<S.compute)throw new Error("Shader capture did not live-build every distinct registered render/compute entry.");return {scene:r.scene,backend:t,manifest:R,skipped:o,stats:l,coverage:S,...y===void 0?{}:{timing:y},...m===void 0?{}:{provenance:m}}}a(Ve,"validateShaderCapture");function E(e,r=0){let t=" ".repeat(r),n=" ".repeat(r+1);if(Array.isArray(e))return e.length===0?"[]":e.every(s=>s===null||["number","string","boolean"].includes(typeof s))?JSON.stringify(e):`[
4
+ ${e.map(s=>`${n}${E(s,r+1)}`).join(`,
5
+ `)}
6
+ ${t}]`;if(e!==null&&typeof e=="object"){let s=e,o=Object.keys(s).sort();return o.length===0?"{}":`{
7
+ ${o.map(l=>{let p=s[l];return `${n}${JSON.stringify(l)}: ${E(p,r+1)}`}).join(`,
8
+ `)}
9
+ ${t}}`}let i=JSON.stringify(e);if(i===void 0)throw new Error("Shader artifact contains a non-serializable value.");return i}a(E,"stableStringify");function ke(e){return ["// GENERATED FILE \u2014 do not edit by hand.","// Produced by @three-blocks/devtools.","import type { PrecompiledManifest } from 'three-blocks/shaders';","",`export default ${E(e)} satisfies PrecompiledManifest;`,""].join(`
10
+ `)}a(ke,"serializeShaderManifest");function te(e,r){if(typeof e!="string"||e.length===0||e.length>256||/[\u0000-\u001f\u007f]/u.test(e))throw new Error(`${r} is invalid.`);return e}a(te,"timingLabel");function J(e){if(!a$1(e)||e.schemaVersion!==3||e.source!=="latest-local-capture"&&e.source!=="committed-capture"||typeof e.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(e.receiptHash)||typeof e.measuredAt!="string"||!Number.isFinite(Date.parse(e.measuredAt))||!a$1(e.scenes))throw new Error("Shader timing is invalid.");let r={};for(let[n,i]of Object.entries(e.scenes)){if(n.length===0||n.length>128||!a$1(i))throw new Error("Shader timing scene is invalid.");let s={builds:u(i.builds,`timing ${n}.builds`),setupMeasured:i.setupMeasured===true,liveBuildMs:u(i.liveBuildMs,`timing ${n}.liveBuildMs`,false),precompiledBuildMs:u(i.precompiledBuildMs,`timing ${n}.precompiledBuildMs`,false),avoidedBuildMs:u(i.avoidedBuildMs,`timing ${n}.avoidedBuildMs`,false),runs:u(i.runs,`timing ${n}.runs`),spreadMs:u(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}".`);r[n]=s;}if(Object.keys(r).length===0)throw new Error("Shader timing contains no scenes.");let t={schemaVersion:3,receiptHash:e.receiptHash,measuredAt:e.measuredAt,scenes:r};return e.source==="latest-local-capture"?{...t,source:"latest-local-capture"}:{...t,source:"committed-capture",adapter:te(e.adapter,"Shader timing adapter"),platform:te(e.platform,"Shader timing platform")}}a(J,"parseShaderTiming");function O(e){return /^[a-z0-9][a-z0-9_-]{0,63}(?:\.webgl)?$/u.test(e)}a(O,"validParityScene");function ne(e){return typeof e=="string"&&Number.isFinite(Date.parse(e))}a(ne,"validParityTimestamp");function G(e){if(!a$1(e))throw new Error("Shader parity evidence is invalid.");if(e.schemaVersion===1){if(typeof e.receiptHash!="string"||!/^[a-f0-9]{64}$/u.test(e.receiptHash)||!ne(e.verifiedAt)||!Array.isArray(e.scenes)||e.scenes.length===0||e.scenes.length>64||!e.scenes.every(n=>typeof n=="string"&&O(n)))throw new Error("Shader parity evidence is invalid.");return {schemaVersion:1,receiptHash:e.receiptHash,verifiedAt:e.verifiedAt,scenes:[...new Set(e.scenes)].sort()}}if(e.schemaVersion!==2||!a$1(e.scenes))throw new Error("Shader parity evidence is invalid.");let r=Object.entries(e.scenes);if(r.length===0||r.length>64)throw new Error("Shader parity evidence is invalid.");let t={};for(let[n,i]of r.sort(([s],[o])=>s.localeCompare(o))){if(!O(n)||!a$1(i)||typeof i.fingerprint!="string"||!/^[a-f0-9]{64}$/u.test(i.fingerprint)||!ne(i.verifiedAt))throw new Error("Shader parity evidence is invalid.");if(i.execution!==void 0&&i.execution!=="node"&&i.execution!=="browser")throw new Error("Shader parity execution is invalid.");t[n]={fingerprint:i.fingerprint,verifiedAt:i.verifiedAt,...i.execution===void 0?{}:{execution:i.execution}};}return {schemaVersion:2,scenes:t}}a(G,"parseShaderParityEvidence");function ce(e,r){let t=e.scenes[r];if(t===void 0)throw new Error(`Shader receipt has no scene "${r}" for parity evidence.`);return c(E({runtime:{three:e.runtime.three,threeBlocks:e.runtime.threeBlocks,threeBlocksShaderClosure:e.runtime.threeBlocksShaderClosure},...e.tool===void 0?{}:{tool:e.tool},scene:t}))}a(ce,"shaderSceneParityFingerprint");async function $(e,r,t,n){let i=c$1.join(e,t);try{if(!await d(i))return;let s=await lstat(i);if(s.isSymbolicLink()||!s.isFile()||s.size>1024*1024)return;let o=J(JSON.parse(await readFile(i,"utf8")));return o.source===n&&o.receiptHash===c(r)?o:void 0}catch{return}}a($,"readShaderTimingFile");async function He(e,r){let t=await $(e,r,W,"latest-local-capture");return t?.source==="latest-local-capture"?t:void 0}a(He,"readShaderLocalTiming");async function De(e,r){return await $(e,r,W,"latest-local-capture")??await $(e,r,z,"committed-capture")}a(De,"readShaderTiming");async function ue(e,r){let t=c$1.join(e,K);try{if(!await d(t))return;let n=await lstat(t);if(n.isSymbolicLink()||!n.isFile()||n.size>1024*1024)return;let i=G(JSON.parse(await readFile(t,"utf8"))),s=c$2(JSON.parse(Buffer.from(r).toString("utf8"))),o={};if(i.schemaVersion===1)return;for(let[l,p]of Object.entries(i.scenes))p.execution!=="node"||s.scenes[l]===void 0||p.fingerprint!==ce(s,l)||(o[l]=p);return Object.keys(o).length===0?void 0:{schemaVersion:2,scenes:o}}catch{return}}a(ue,"readShaderParityEvidence");async function Ne(e,r){let t=await $(e,r,z,"committed-capture");return t?.source==="committed-capture"?t:void 0}a(Ne,"readShaderCommittedTiming");async function pe(e,r,t){let n=await _(e),i=c$1.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 o=await readFile(i),l=new Date().toISOString(),p=Object.fromEntries(Object.entries(r).sort(([R],[S])=>R.localeCompare(S))),y=J({schemaVersion:3,receiptHash:c(o),measuredAt:l,source:"latest-local-capture",scenes:p});if(await f(c$1.join(n,W),`${E(y)}
11
+ `),t===void 0)return {local:y};let m=J({schemaVersion:3,receiptHash:c(o),measuredAt:l,source:"committed-capture",adapter:t.adapter,platform:t.platform,scenes:p});return await f(c$1.join(n,z),`${E(m)}
12
+ `),{local:y,committed:m}}a(pe,"writeShaderTimings");async function Le(e,r){return (await pe(e,r)).local}a(Le,"writeShaderLocalTiming");async function ve(e,r,t){if(r.length===0||r.length>64||r.some(S=>!O(S)))throw new Error("Shader parity evidence must contain 1...64 valid scene keys.");let n=await _(e),i=c$1.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 o=await readFile(i);if(t!==void 0&&c(o)!==c(t))throw new Error("Shader receipt changed during renderer parity verification; completed observations were not attached to the new receipt.");let l=c$2(JSON.parse(o.toString("utf8"))),p=await ue(n,o),y=new Date().toISOString(),m={...p?.scenes};for(let S of [...new Set(r)].sort())m[S]={execution:"node",fingerprint:ce(l,S),verifiedAt:y};let R=G({schemaVersion:2,scenes:m});return await f(c$1.join(n,K),`${E(R)}
13
+ `),R}a(ve,"writeShaderParityEvidence");async function Fe(e,r,t){if(r.length===0||r.length>64||r.some(m=>!O(m)))throw new Error("Shader parity invalidation must contain 1...64 valid scene keys.");let n=await _(e),i=await readFile(c$1.join(n,"meta.json"));if(c(i)!==c(t))throw new Error("Shader receipt changed before prior parity evidence could be invalidated.");let s=await ue(n,i);if(s===void 0)return;let o=new Set(r),l=Object.fromEntries(Object.entries(s.scenes).filter(([m])=>!o.has(m))),p=c$1.join(n,K);if(Object.keys(l).length===0){await unlink(p).catch(m=>{if(!a$1(m)||m.code!=="ENOENT")throw m});return}let y=G({schemaVersion:2,scenes:l});await f(p,`${E(y)}
14
+ `);}a(Fe,"removeShaderParityEvidence");async function qe(e,r,t){let n=await pe(e,r,t);if(n.committed===void 0)throw new Error("Committed shader timing was not written.");return {local:n.local,committed:n.committed}}a(qe,"writeShaderTimingTwins");async function ie(e){if(!await d(e)){await mkdir(e);return}let r=await lstat(e);if(r.isSymbolicLink()||!r.isDirectory())throw new Error(`Shader artifact path is not a real directory: ${e}.`)}a(ie,"assertDirectory");async function _(e){let r=c$1.resolve(e),t=c$1.join(r,".three-blocks");await ie(t);let n=c$1.join(t,"shaders");return await ie(n),n}a(_,"artifactRoot");async function Ue(e$2){let r=await _(e$2.root),t=e$2.backends??["webgpu"],n=Object.fromEntries(t.map(a=>[a,F(e$2.runtime.three,a)])),i$1=c$1.resolve(e$2.root),s=c$1.resolve(i$1,e$2.publicDirectory??"public");if(!e(i$1,s)||s===i$1)throw new Error("Shader public directory must stay inside the project root.");let o=c$1.join(s,"three-blocks","shaders");await mkdir(o,{recursive:true}),await i(i$1,o,"Shader static-asset directory");let l={},p=[];for(let a of [...e$2.scenes].sort((b,M)=>b.key.localeCompare(M.key))){let b=e$2.inputs.get(a.key);if(b===void 0)throw new Error(`Shader input matrix is missing scene "${a.key}".`);for(let M of e$1(a,t)){let B=g(a.key,M),k=e$2.captures.get(B);if(k===void 0){let f=e$2.previousReceipt?.scenes[B];if(f===void 0)continue;let D=await readFile(c$1.join(r,f.artifact));if(c(D)!==f.artifactHash)throw new Error(`Preserved shader artifact checksum differs for "${B}".`);if(f.asset!==void 0&&f.assetHash!==void 0){let N=await readFile(c$1.join(s,f.asset));if(c(N)!==f.assetHash)throw new Error(`Preserved static shader manifest checksum differs for "${B}".`)}l[B]={...f,backend:M,inputs:Object.fromEntries(Object.entries(b).sort(([N],[me])=>N.localeCompare(me)))},p.push(f.artifact),f.asset!==void 0&&p.push(c$1.relative(i$1,c$1.join(s,f.asset)).split(c$1.sep).join("/"));continue}if(k.scene!==a.key||k.backend!==M||k.manifest.scene!==a.key)throw new Error(`Capture matrix scene/backend "${B}" is inconsistent.`);let I=`${a.key}.${M}.ts`,V=ke(k.manifest);await f(c$1.join(r,I),V),p.push(I);let H=`three-blocks/shaders/${a.key}.${M}.json`,Y=`${E(k.manifest)}
15
+ `;await f(c$1.join(s,H),Y),p.push(c$1.relative(i$1,c$1.join(s,H)).split(c$1.sep).join("/"));let X=k.skipped.filter(f=>f.kind==="render").length,le=k.skipped.length-X;l[B]={backend:M,artifact:I,artifactHash:c(V),asset:H,assetHash:c(Y),inputs:Object.fromEntries(Object.entries(b).sort(([f],[D])=>f.localeCompare(D))),coverage:k.coverage,bytes:Buffer.byteLength(V),skipped:{render:X,compute:le}};}}let y=[...e$2.captures.values()].find(a=>a.provenance!==void 0)?.provenance??e$2.previousReceipt?.runtime.capture,m={schemaVersion:2,runtime:{...e$2.runtime,...y===void 0?{}:{capture:y}},tool:{name:"@three-blocks/devtools",version:a$2,compatibility:n[t[0]??"webgpu"],compatibilities:n,transform:ge,address:SHADER_ADDRESS_SCHEMA_VERSION,recipe:SHADER_RECIPE_SCHEMA_VERSION,hydration:SHADER_HYDRATION_SCHEMA_VERSION},scenes:l},R=new Set(p);for(let a of await readdir(r,{withFileTypes:true}))if(!(!/\.(?:webgpu|webgl)\.ts$/u.test(a.name)||R.has(a.name))){if(a.isSymbolicLink()||!a.isFile())throw new Error(`Orphan shader artifact is not a regular file: ${a.name}.`);await unlink(c$1.join(r,a.name));}let S=new Set(e$2.scenes.flatMap(a=>e$1(a,t).map(b=>`${a.key}.${b}.json`))),w=new Set(Object.values(e$2.previousReceipt?.scenes??{}).map(a=>a.asset===void 0?void 0:c$1.posix.basename(a.asset)).filter(a=>a!==void 0));try{let a=c$2(JSON.parse(await readFile(c$1.join(r,"meta.json"),"utf8")));for(let b of Object.values(a.scenes))b.asset!==void 0&&w.add(c$1.posix.basename(b.asset));}catch{}for(let a of await readdir(o,{withFileTypes:true}))if(!(!a.name.endsWith(".json")||S.has(a.name))&&w.has(a.name)){if(a.isSymbolicLink()||!a.isFile())throw new Error(`Orphan shader static asset is not a regular file: ${a.name}.`);await unlink(c$1.join(o,a.name));}return await f(c$1.join(r,"meta.json"),`${E(m)}
16
+ `),p.push("meta.json"),{directory:r,receipt:m,files:p}}a(Ue,"writeShaderArtifacts");export{F as a,ge as b,W as c,z as d,K as e,we as f,Re as g,Ve as h,E as i,ke as j,He as k,De as l,ue as m,Ne as n,Le as o,ve as p,Fe as q,qe as r,Ue as s};