@three-blocks/devtools 1.0.0-alpha.176.g8ff8a72e6369

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 (51) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +76 -0
  3. package/NOTICE +32 -0
  4. package/README.md +254 -0
  5. package/dist/browser/environment-bake.js +1 -0
  6. package/dist/browser/shader-capture.d.ts +45 -0
  7. package/dist/browser/shader-capture.js +3 -0
  8. package/dist/browser-smoke-76626IZQ.js +254 -0
  9. package/dist/chunk-26FK4CRS.js +6 -0
  10. package/dist/chunk-4EHPYBKA.cjs +1 -0
  11. package/dist/chunk-5L2VS3BN.js +2 -0
  12. package/dist/chunk-76WRV5MZ.js +7 -0
  13. package/dist/chunk-EI7MMDWY.js +1 -0
  14. package/dist/chunk-HOZDD6PW.js +2 -0
  15. package/dist/chunk-HRYYNBVC.js +3 -0
  16. package/dist/chunk-INDAJN42.js +94 -0
  17. package/dist/chunk-JMS5NTP7.js +3 -0
  18. package/dist/chunk-ME3X2KFY.js +14 -0
  19. package/dist/chunk-NE7SC2BX.js +2 -0
  20. package/dist/chunk-SCJNCGMF.js +17 -0
  21. package/dist/chunk-UDUICSME.js +1 -0
  22. package/dist/chunk-VGJ3V4QQ.js +78 -0
  23. package/dist/chunk-ZDNZCQUQ.js +2 -0
  24. package/dist/chunk-ZKK6E42X.js +1 -0
  25. package/dist/chunk-ZT6T2W4B.js +2 -0
  26. package/dist/cli.js +24 -0
  27. package/dist/environment-bake-5P4IAL4O.js +4 -0
  28. package/dist/index.d.ts +1183 -0
  29. package/dist/index.js +272 -0
  30. package/dist/shader-autowire-DCODBFMX.js +18 -0
  31. package/dist/shader-browser-65V22LLL.js +1 -0
  32. package/dist/shader-browser-JII6ZFCW.js +2 -0
  33. package/dist/shader-capture-server.d.ts +272 -0
  34. package/dist/shader-capture-server.js +19 -0
  35. package/dist/shader-config-4EXO5DKK.js +2 -0
  36. package/dist/shader-parity-QXJWR6OZ.js +1 -0
  37. package/dist/shader-parity-XPKQQK26.js +2 -0
  38. package/dist/shader-project-runner-GUR3LTYS.js +5 -0
  39. package/dist/shader-transform-CUkZn5Oa.d.ts +55 -0
  40. package/dist/shader-watch-QHTNTSZE.js +2 -0
  41. package/dist/shader-workflow-U4G565EB.js +2 -0
  42. package/dist/status-DV2BYZHR.js +2 -0
  43. package/dist/text-atlas-BHPSDU7C.js +2 -0
  44. package/dist/transform.cjs +1 -0
  45. package/dist/transform.d.ts +62 -0
  46. package/dist/transform.js +1 -0
  47. package/dist/webpack-loader.cjs +1 -0
  48. package/dist/webpack-loader.d.ts +17 -0
  49. package/dist/webpack-loader.js +1 -0
  50. package/fonts/OFL-1.1.txt +93 -0
  51. package/package.json +113 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # @three-blocks/devtools
2
+
3
+ ## 1.0.0-alpha.176.g8ff8a72e6369
4
+
5
+ - ci: keep alpha readiness release-scoped (`8ff8a72e6369`).
6
+
7
+ This changelog is generated from Changesets.
8
+
9
+ ## 0.1.0
10
+
11
+ - Initial WebGPU shader precompilation and verification toolchain.
package/LICENSE ADDED
@@ -0,0 +1,76 @@
1
+ Required Notice: Copyright (c) 2025-2026 Three Blocks — https://threejs-blocks.com
2
+ Required Notice: AI/ML training and dataset use are not licensed; text-and-data-mining rights reserved (EU 2019/790 Art. 4(3)). See NOTICE.
3
+
4
+ # PolyForm Noncommercial License 1.0.0
5
+
6
+ <https://polyformproject.org/licenses/noncommercial/1.0.0>
7
+
8
+ ## Acceptance
9
+
10
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
11
+
12
+ ## Copyright License
13
+
14
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
15
+
16
+ ## Distribution License
17
+
18
+ The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
19
+
20
+ ## Notices
21
+
22
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
23
+
24
+ > Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
25
+
26
+ ## Changes and New Works License
27
+
28
+ The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
29
+
30
+ ## Patent License
31
+
32
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
33
+
34
+ ## Noncommercial Purposes
35
+
36
+ Any noncommercial purpose is a permitted purpose.
37
+
38
+ ## Personal Uses
39
+
40
+ Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
41
+
42
+ ## Noncommercial Organizations
43
+
44
+ Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
45
+
46
+ ## Fair Use
47
+
48
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
49
+
50
+ ## No Other Rights
51
+
52
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
53
+
54
+ ## Patent Defense
55
+
56
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
57
+
58
+ ## Violations
59
+
60
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
61
+
62
+ ## No Liability
63
+
64
+ ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
65
+
66
+ ## Definitions
67
+
68
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
69
+
70
+ **You** refers to the individual or entity agreeing to these terms.
71
+
72
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
73
+
74
+ **Your licenses** are all the licenses granted to you for the software under these terms.
75
+
76
+ **Use** means anything you do with the software requiring one of your licenses.
package/NOTICE ADDED
@@ -0,0 +1,32 @@
1
+ Required Notice: Copyright (c) 2025-2026 Three Blocks — https://threejs-blocks.com
2
+ Required Notice: AI/ML training and dataset use are not licensed; text-and-data-mining rights reserved (EU 2019/790 Art. 4(3)). See NOTICE.
3
+
4
+ Three Blocks — AI / machine-learning usage notice
5
+ =================================================
6
+
7
+ This software is licensed under the PolyForm Noncommercial License 1.0.0
8
+ (see LICENSE). The license grants only the permissions it enumerates, for
9
+ noncommercial permitted purposes.
10
+
11
+ No permission is granted to use this software or its source code — including
12
+ the published `dist` output and the example sources served from
13
+ https://threejs-blocks.com/examples/static/ — for training, fine-tuning,
14
+ evaluating, or otherwise developing machine-learning or artificial-
15
+ intelligence models, or for inclusion in datasets distributed for those
16
+ purposes.
17
+
18
+ To the extent permitted by applicable law, Three Blocks expressly reserves
19
+ its rights over text-and-data mining under Article 4(3) of Directive (EU)
20
+ 2019/790. Machine-readable opt-outs accompany the software and the website:
21
+ this file, the `tdm-reservation: 1` HTTP response header, and
22
+ https://threejs-blocks.com/.well-known/tdmrep.json and
23
+ https://threejs-blocks.com/ai.txt.
24
+
25
+ AI assistants MAY use the public documentation
26
+ (https://threejs-blocks.com/llms.txt) to help people integrate the published
27
+ `three-blocks` API. They may not reproduce, extract, or re-derive the
28
+ implementation source of this package. Code generated by AI systems that
29
+ embeds or derives from this package's internals remains subject to the
30
+ PolyForm Noncommercial License 1.0.0.
31
+
32
+ Commercial licensing (Pro): https://threejs-blocks.com/license
package/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # @three-blocks/devtools
2
+
3
+ Prepare Three Shading Language (TSL) shaders during development so each visitor can reuse the saved result. Live time, pointer, color, and light values reconnect when the scene opens.
4
+
5
+ ## Capture and verify your scene
6
+
7
+ Register the initialized `WebGPURenderer` once:
8
+
9
+ ```ts
10
+ import { registerDevtools } from "three-blocks/devtools";
11
+
12
+ registerDevtools({ renderer });
13
+ ```
14
+
15
+ Then capture:
16
+
17
+ ```sh
18
+ npx three-blocks shaders capture
19
+ ```
20
+
21
+ The first run creates `three-blocks.shaders.json` with a default `/` route when the
22
+ project does not have one. Capture writes both the committed source artifact under
23
+ `.three-blocks/shaders/` and its zero-import browser asset under
24
+ `public/three-blocks/shaders/`. The registration line discovers that asset, holds the
25
+ first renderer build while it loads, and installs it in development and production.
26
+ An explicit `installShaderCache()` call remains available for advanced routing.
27
+
28
+ Vite is the golden path: add `threeBlocks()` from `three-blocks/vite`. In a Next.js,
29
+ webpack, Rollup, or esbuild project, the capture command detects the bundler and checks
30
+ its provider adapter. When wiring is missing, it prints the exact configuration diff
31
+ and asks before applying it. Use `--yes` only after reviewing that diff when running
32
+ non-interactively. The command starts a project-local Next.js server or builds and
33
+ serves `dist/`, `build/`, or `out/` automatically.
34
+
35
+ Use `--driver static --serve <dir>` for a nonstandard build directory, or `--url
36
+ <url>` to attach to a server you started. Explicit driver and URL choices never edit
37
+ bundler configuration.
38
+
39
+ The overlay changes from **Live** to **Precompiled** after a fresh capture loads. It shows the skipped TSL builds and the project-specific **TSL build time saved** when `timing.local.json` matches the current capture. Shader-relevant edits mark both the capture and its timing stale, so the app builds live until you capture again.
40
+
41
+ `WebGLRenderer` stays on live shader building. `WebGPURenderer` also uses the live path when it selects a WebGL fallback.
42
+
43
+ ### Three.js r185 compatibility patch
44
+
45
+ Every adapter applies the same version-gated patch to `three/build/three.webgpu.js` in memory. It never writes `node_modules`. The r185 patch contains four independent changes:
46
+
47
+ - [#34068](https://github.com/mrdoob/three.js/pull/34068) adds the node-builder debug callback used by capture.
48
+ - [#34069](https://github.com/mrdoob/three.js/pull/34069) gives named node buffers deterministic labels.
49
+ - [#34070](https://github.com/mrdoob/three.js/pull/34070) adds the public node-builder state provider used by hydration.
50
+ - The local `compileAsync()` patch collects pipeline promises across one compile pass, yields after 8 ms work slices, then awaits the pipelines together. It captures each WebGPU error-scope promise before concurrent pipelines settle so the scopes remain balanced.
51
+
52
+ Each change has exact source anchors and fails closed on drift or partial application. Current captures require precompiled manifest version `3` and shader receipt transform version `3`; recapture older artifacts instead of editing them.
53
+
54
+ Delete an upstream backport when the supported Three.js release contains it. Reevaluate the local batching patch against each release. See [Maintain Three.js WebGPU compatibility](../../docs/maintenance/three-webgpu-release-compatibility.md) for markers, removal conditions, and verification.
55
+
56
+ ### Manual bundler adapters
57
+
58
+ These are the manual equivalents of the diff that `shaders capture` offers.
59
+
60
+ esbuild:
61
+
62
+ ```js
63
+ import { createEsbuildShaderPlugin } from "@three-blocks/devtools/transform";
64
+
65
+ await build({
66
+ // ...
67
+ plugins: [createEsbuildShaderPlugin({ root: process.cwd() })],
68
+ });
69
+ ```
70
+
71
+ Rollup:
72
+
73
+ ```js
74
+ import { createRollupShaderPlugin } from "@three-blocks/devtools/transform";
75
+
76
+ export default {
77
+ // ...
78
+ plugins: [createRollupShaderPlugin({ root: process.cwd() })],
79
+ };
80
+ ```
81
+
82
+ webpack:
83
+
84
+ ```js
85
+ import { withThreeBlocksWebpack } from "@three-blocks/devtools/transform";
86
+
87
+ export default withThreeBlocksWebpack({
88
+ // ...
89
+ });
90
+ ```
91
+
92
+ Next.js:
93
+
94
+ ```ts
95
+ import type { NextConfig } from "next";
96
+ import { withThreeBlocksNext } from "@three-blocks/devtools/transform";
97
+
98
+ const nextConfig: NextConfig = {
99
+ // Your existing webpack callback is composed, not replaced.
100
+ };
101
+
102
+ export default withThreeBlocksNext(nextConfig);
103
+ ```
104
+
105
+ The adapters always install the production provider hook. They add capture
106
+ instrumentation only when `THREE_BLOCKS_SHADER_TOOL=1`; a tool-managed build or server
107
+ sets that automatically. For a manually started webpack or Next.js server, set the
108
+ variable yourself and run `shaders capture --url http://localhost:3000`.
109
+
110
+ ## Reference
111
+
112
+ The public command surface is `npx three-blocks`. This package also exposes the direct `three-blocks-devtools` binary for package-local and repository maintenance.
113
+
114
+ All commands support `--json` (stable machine output; human output stays line-oriented and
115
+ uncolored when piped). Static status validates `three-blocks.json`, committed shader
116
+ manifests, installed compatibility versions, the installed public `three-blocks/shaders`
117
+ runtime closure, and independently discovered shader-relevant source inputs. Runtime
118
+ evidence (worker, codecs, HMR) comes from the last `browser smoke` run and is reported as
119
+ a dated verification, never as live state.
120
+
121
+ ### Precompile WebGPU shaders
122
+
123
+ ```bash
124
+ three-blocks-devtools shaders status --check # no browser or GPU
125
+ three-blocks-devtools shaders capture --if-stale # isolated GPU context per scene
126
+ three-blocks-devtools shaders test --parity-only # one fast zero-build + pixel pair
127
+ three-blocks-devtools shaders test # parity + timing + published-page soak
128
+ three-blocks-devtools shaders test --skip-browser --mode strict
129
+ # CI freshness/schema gate
130
+ three-blocks-devtools shaders watch --debounce 250
131
+ ```
132
+
133
+ Projects may declare the complete capture matrix in `three-blocks.shaders.json`:
134
+
135
+ ```json
136
+ {
137
+ "schemaVersion": 1,
138
+ "scenes": [
139
+ { "key": "default", "url": "/?scene=default" },
140
+ { "key": "text", "url": "/?scene=text", "requiresText": true }
141
+ ],
142
+ "settleFrames": 60,
143
+ "timeoutMs": 240000,
144
+ "viewport": { "width": 1024, "height": 640 },
145
+ "parity": { "frames": 90, "channelTolerance": 8, "maxDiffRatio": 0.01 },
146
+ "readiness": { "global": "__THREE_BLOCKS_READY__" },
147
+ "publicDir": "public",
148
+ "allowLiveBuilds": true
149
+ }
150
+ ```
151
+
152
+ Readiness is optional. Its global may be `true` or a promise; a selector is also
153
+ supported. With no override, the engine waits for its settled-frame and first-frame
154
+ contract and assumes nothing about application DOM.
155
+
156
+ This workflow is the main purpose of `@three-blocks/devtools`. Capture uses a version-gated r185 transform supplied by the selected bundler adapter. The transform journals real
157
+ render and compute `NodeBuilder` states, resolves stable keys through the public
158
+ `three-blocks/shaders` cache, exposes loopback readiness/telemetry, and uploads a typed payload.
159
+ The generated application owns no capture harness or patcher, and this tool never writes to
160
+ `node_modules`. A Three.js version or transform-anchor mismatch fails closed.
161
+
162
+ All configured scenes must pass before the tool replaces deterministic
163
+ `.three-blocks/shaders/<scene>.webgpu.ts` modules; `meta.json` is the last commit marker. It records
164
+ runtime/tool/schema versions, a `threeBlocksShaderClosure` hash, shader-relevant app-source hashes,
165
+ bytes, stage coverage, and skipped render/compute builds. App hashing begins at scene modules and
166
+ real shader registrations and follows only local runtime imports. Unrelated modules, type-only
167
+ imports, and DOM copy are not freshness inputs. Relevant source changes during capture abort the
168
+ commit. `watch` is explicitly opt-in and permits
169
+ only one running capture plus one coalesced rerun; failures preserve the prior committed receipt.
170
+ Explicit stable keys remain the clearest choice for complex, conditional capture matrices.
171
+ When an otherwise unregistered application or Three-internal build is first observed,
172
+ capture assigns it a deterministic scene-scoped key and records that automatic namespace
173
+ in the manifest. Set `allowLiveBuilds: false` when a project intentionally requires any
174
+ build that still cannot be addressed to fail capture.
175
+
176
+ `shaders test` first repeats the no-GPU matrix inspection. Its browser gate then proves that the
177
+ live baseline builds every registered render pipeline and compute kernel, while the fresh path
178
+ performs zero registered builds, covers render and compute injection independently, reports no
179
+ misses, reaches first-frame readiness, renders non-black output, and matches deterministic pixels.
180
+ Successful scenes are checkpointed immediately against their scene receipt and the shared
181
+ runtime/tool contract, so a later failure can resume at the missing scene. `--parity-only` runs
182
+ one live/precompiled pair without timing warmups, repeats, or the published-page soak. The default
183
+ mode retains those slower measurements and production-page checks. A parity observation that
184
+ returns no result is capped at 10 seconds.
185
+ On parity failure it writes live, precompiled, and diff PNGs under
186
+ `.three-blocks/shaders/parity/`.
187
+
188
+ ### Verify a browser integration
189
+
190
+ ```bash
191
+ three-blocks-devtools browser smoke --route / --json
192
+ three-blocks-devtools browser smoke --hmr src/offscreen/meshes/Scene.ts
193
+ ```
194
+
195
+ The smoke gate loads the project's real Vite config on an ephemeral loopback port. It requires
196
+ the visible OffscreenCanvas worker plus `workerReady`, `assetsReady`, and `compileEnd`; it also
197
+ requires `textReady` when the Vite text configuration is enabled. Every configured Draco and
198
+ KTX2 route is fetched, the lazy Meshopt decoder is initialized, page and console errors fail the
199
+ run, and both the WebGPU screenshot and readable 2D panels are checked for an all-black frame.
200
+
201
+ The command reads the starter's built-in readiness check. Application tutorials describe the visible **Starting**, **Ready**, **Precompiled**, and **Live** states instead of this maintainer contract. Contributors can inspect the exact protocol in the [maintainer browser-verification reference](../../docs/maintenance/browser-verification.md).
202
+
203
+ `--hmr <project-relative-module>` emits a synthetic watcher change through Vite for an already
204
+ loaded scene module. It runs the real HMR graph without writing or touching source and verifies
205
+ that the browser acknowledges the update while lifecycle readiness remains stable.
206
+
207
+ Only the two documented ambient diagnostics exported in `DOCUMENTED_BROWSER_NOISE` are filtered:
208
+ Three Inspector's invalid `extensions.json` response and Chromium's experimental WebGPU notice.
209
+
210
+ ### Bake environment lighting
211
+
212
+ ```bash
213
+ three-blocks-devtools environment bake --size 256
214
+ three-blocks-devtools environment bake --output src/assets/environment/studio.pmrem.ktx2 --json
215
+ ```
216
+
217
+ The browser entry renders Three.js `RoomEnvironment` through WebGPU and exports the PMREM CubeUV
218
+ atlas. Node validates RGBA16F topology, zstd-compresses at a deterministic level, decodes every
219
+ level byte-for-byte, records the final SHA-256 checksum, and transactionally replaces the KTX2
220
+ and JSON metadata pair. Size, time, upload, path, and file bounds are enforced. `--no-zstd` is an
221
+ explicit compatibility opt-out.
222
+
223
+ Both GPU commands accept `--root <path>` for integration workspaces that intentionally do
224
+ not carry generated-project metadata. Normal generated projects are discovered automatically.
225
+
226
+ ### Ship it
227
+
228
+ Commit `.three-blocks/shaders/` and the generated public manifests, then add one
229
+ GPU-less CI command:
230
+
231
+ ```sh
232
+ npx three-blocks shaders test --skip-browser --mode strict
233
+ ```
234
+
235
+ Use `--reporter json` for CI annotations. Run the full `shaders test` in an optional
236
+ WebGPU lane. Production selects the hydration-only `three-blocks/devtools` condition:
237
+ overlay and stats implementation bytes are absent, while the bounded
238
+ `three-blocks/shaders` runtime remains. Opt into its local production console receipt
239
+ with `threeBlocks({ stats: { production: true } })`; no telemetry leaves the app.
240
+
241
+ Text artifacts remain `missing` or `invalid` until configured glyph coverage, checksums,
242
+ orientation, and KTX2 decode round-trip validation succeed. No command performs account or
243
+ entitlement checks.
244
+
245
+ ## License
246
+
247
+ Free for personal and noncommercial projects. Commercial projects are covered
248
+ by the Pro plan's lifetime license — each project you start while your plan is
249
+ active is licensed forever, for the versions released while it was active. No
250
+ runtime gating.
251
+
252
+ This package uses the [PolyForm Noncommercial 1.0.0 license](./LICENSE). Keep
253
+ the Required Notice when redistributing it; full commercial terms are at
254
+ [threejs-blocks.com/license](https://threejs-blocks.com/license).
@@ -0,0 +1 @@
1
+ import*as n from'three/webgpu';import {RoomEnvironment}from'three/addons/environments/RoomEnvironment.js';import {KTX2Exporter}from'three/addons/exporters/KTX2Exporter.js';var R=Object.defineProperty;var E=(e,o)=>R(e,"name",{value:o,configurable:true});function l(){let e=Number(new URLSearchParams(location.search).get("size")??256);if(!Number.isSafeInteger(e)||e<16||e>1024||(e&e-1)!==0)throw new Error(`RoomEnvironment cube size must be a power of two in 16...1024; received ${String(e)}.`);return e}E(l,"readCubeSize");async function _(){let e=document.querySelector("#three-blocks-environment-baker");if(!e)throw new Error("RoomEnvironment bake canvas is missing.");let o=l(),r=new n.WebGPURenderer({canvas:e,antialias:false}),t,a,i;try{await r.init(),t=new RoomEnvironment,a=new n.PMREMGenerator(r),i=a.fromScene(t,0,.1,100,{size:o});let m=await new KTX2Exporter().parse(r,i),s=await fetch("/__three-blocks/devtools/environment-bake/upload",{method:"POST",body:m,headers:{"content-type":"image/ktx2","x-three-revision":n.REVISION}});if(!s.ok)throw new Error(`RoomEnvironment upload failed: HTTP ${s.status} ${await s.text()}`);globalThis.__THREE_BLOCKS_ROOM_ENVIRONMENT_BAKE__={ok:!0};}finally{i?.dispose(),a?.dispose(),t?.dispose(),r.dispose();}}E(_,"bake");_().catch(e=>{let o=e instanceof Error?e.stack??e.message:String(e);globalThis.__THREE_BLOCKS_ROOM_ENVIRONMENT_BAKE__={ok:false,error:o},console.error(e);});
@@ -0,0 +1,45 @@
1
+ interface ShaderCaptureReadiness {
2
+ readonly selector?: string;
3
+ readonly global?: string;
4
+ }
5
+ interface ShaderCaptureRuntimeConfiguration {
6
+ readonly capture: boolean;
7
+ readonly forceLive: boolean;
8
+ readonly settleFrames: number;
9
+ /** Maximum visible settle time after readiness before capture posts, regardless of late builds. */
10
+ readonly settleTimeoutMs?: number;
11
+ /** Pause the settle countdown while an interactive capture tab is hidden. */
12
+ readonly visibilityGuard?: boolean;
13
+ /** Overlay-capture session identity. Omitted by the driven browser capture. */
14
+ readonly captureId?: string;
15
+ /** Browser storage key cleared after a successful overlay capture POST. */
16
+ readonly sessionKey?: string;
17
+ /** Per-dev-server token sent as an HTTP header by overlay capture. */
18
+ readonly token?: string;
19
+ readonly readiness?: ShaderCaptureReadiness;
20
+ readonly transform: number;
21
+ }
22
+
23
+ /**
24
+ * Structural mirror of runtime `bindingKindOf`. The capture bundle is injected into
25
+ * `three.webgpu.js`, so importing the runtime value here would create a module cycle.
26
+ */
27
+ declare function capturedBindingKind(value: object): string;
28
+
29
+ type UnknownRecord = Record<string, unknown>;
30
+ declare function configureThreeBlocksShaderCapture(next: ShaderCaptureRuntimeConfiguration): void;
31
+ declare function activeShaderCaptureScene(): string;
32
+ /**
33
+ * Capture-runtime copy of the devtools timing seam. This module is injected as a
34
+ * standalone browser script and therefore cannot import three-blocks/devtools.
35
+ */
36
+ declare function wrapThreeBlocksCaptureTimedBuild(builder: UnknownRecord, key: 'build' | 'buildAsync', record?: (elapsedMs: number) => void, clock?: () => number, onBuilt?: () => void): void;
37
+ /** Called immediately after Three creates a live NodeBuilder, before setup/build. */
38
+ declare function instrumentThreeBlocksShaderBuilder(builderValue: unknown, rendererValue: unknown, targetValue?: unknown): void;
39
+ /** Called after the #34068 builder callback observes a successful real build. */
40
+ declare function recordThreeBlocksShaderBuild(builderValue: unknown, rendererValue: unknown): void;
41
+ /** Called at the top of r185 getForRender/getForCompute before provider lookup. */
42
+ declare function prepareThreeBlocksShaderRenderer(rendererValue: unknown, namespaceValue?: unknown, revisionValue?: unknown): void;
43
+ declare function pageLoadingIsComplete(root: UnknownRecord, readiness?: ShaderCaptureReadiness): boolean;
44
+
45
+ export { activeShaderCaptureScene, capturedBindingKind, configureThreeBlocksShaderCapture, instrumentThreeBlocksShaderBuilder, pageLoadingIsComplete, prepareThreeBlocksShaderRenderer, recordThreeBlocksShaderBuild, wrapThreeBlocksCaptureTimedBuild };
@@ -0,0 +1,3 @@
1
+ var Pt=Object.defineProperty;var l=(e,t)=>Pt(e,"name",{value:t,configurable:true});var Ae="three-webgpu-r185-v1",et=["fragmentNode","vertexNode","colorNode","positionNode","normalNode","opacityNode","alphaTestNode","backdropNode","backdropAlphaNode","emissiveNode","metalnessNode","roughnessNode","clearcoatNode","clearcoatRoughnessNode","transmissionNode","thicknessNode","iorNode","outputNode","mrtNode","depthNode","castShadowNode","receivedShadowNode","maskNode","envNode"];var z=["_renderContexts","_renderContexts"],P=Object.freeze({renderContextMrt:"three-r185-render-context-mrt",renderContextInput:"three-r185-render-context-input",skinningEvent:"three-r185-skinning-event",morphUpdateEvent:"three-r185-morph-update-event",maxMip:"three-r185-max-mip",morphTargetTexture:"three-r185-morph-target-texture"});function Te(e){let t=/^(.*)-([^-]+)-(-?\d+)$/u.exec(e);if(t?.[1]===void 0||t[2]===void 0||t[3]===void 0)return;let n=Number(t[3]);if(Number.isSafeInteger(n))return {attachmentState:t[1],mrtState:t[2],callDepth:n}}l(Te,"parseThreeR185RenderContextKey");function tt(e){return e==="185"||e===185}l(tt,"supportsThreeR185Revision");function Ot(e){let t=e.constructor;return (typeof t=="function"||typeof t=="object"&&t!==null)&&typeof Reflect.get(t,"name")=="string"?String(Reflect.get(t,"name")):"unknown"}l(Ot,"constructorName");function je(e){let t=e,n=l(i=>t[i]===true,"flag"),r=typeof t.textureNode=="object"&&t.textureNode!==null||typeof t.nodeUniform=="object"&&t.nodeUniform!==null;return n("isNodeUniformsGroup")?"NodeUniformsGroup":n("isUniformsGroup")?"UniformsGroup":n("isNodeUniformBuffer")?"NodeUniformBuffer":n("isUniformBuffer")?"UniformBuffer":n("isStorageBuffer")?r?"NodeStorageBuffer":"StorageBuffer":n("isSampledCubeTexture")?r?"NodeSampledCubeTexture":"SampledCubeTexture":n("isSampledTexture3D")?"NodeSampledTexture3D":n("isSampled3DTexture")?"Sampled3DTexture":n("isSampledArrayTexture")?r?"NodeSampledArrayTexture":"SampledArrayTexture":n("isSampledTexture")?r?"NodeSampledTexture":"SampledTexture":n("isSampler")?r?"NodeSampler":"Sampler":typeof t.kind=="string"?t.kind:Ot(e)}l(je,"capturedBindingKind");var nt="three-blocks.shader-capture.runtime.v1";var Ft=Symbol.for("three-blocks.shader-capture.cache.v1"),Dt=Symbol.for("three-blocks.shader-capture.cache-value.v1"),$e="/__three-blocks/shaders/capture",oe="/__three-blocks/shaders/telemetry",Re=4096,Kt=4,Ht=65536,zt=1e3,Gt=/^[a-z0-9][a-z0-9_-]{0,63}$/u,qt=new Set(["cameraProjectionMatrix","cameraProjectionMatrixInverse","cameraViewMatrix","cameraWorldMatrix","cameraNormalMatrix","cameraPosition"]),rt=["lightPosition","lightTargetPosition","lightViewPosition","lightShadowMatrix"],Wt=new Set(["_texture","_width","_height","_maxMip","_matrixUniform","_flipYUniform"]),Jt={bias:"shadowBias",intensity:"shadowIntensity",normalBias:"shadowNormalBias",radius:"shadowRadius",blurSamples:"shadowBlurSamples",mapSize:"shadowMapSize"},x={buildCalls:0,renderBuilds:0,computeBuilds:0,registeredBuilds:0,registeredRenderBuilds:0,registeredComputeBuilds:0,buildMs:0,injected:0,injectedRender:0,injectedCompute:0,missed:0,missedRender:0,missedCompute:0,missedKeys:[]},A={capture:false,forceLive:false,settleFrames:60,readiness:{},transform:1},St=new WeakMap,ot=new WeakSet,it=new WeakSet,Ue=new WeakMap,Pe=new Set,wt=new WeakMap,pe=[],ge=[],st=new WeakMap,at=new WeakMap,ct=new WeakMap,D,ce=0,Ce=false,se=false,K="default",J,Y,W=false,Oe=0,de,dt=false,B,_,me={},ne,re=false;function he(e){return /^.+\/input-[a-zA-Z0-9_-]+-\d{4}$/u.test(e)}l(he,"isAutomaticInputContainerKey");function p(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}l(p,"isRecord");function Le(e,t=new Set){if(e===null||typeof e!="object"||t.has(e))return;if(t.add(e),Array.isArray(e)){for(let r of e){let i=Le(r,t);if(i)return i}return}let n=e;for(let r of ["key","container"]){let i=n[r];if(typeof i=="string"&&he(i))return i}for(let r of Object.values(n)){let i=Le(r,t);if(i)return i}}l(Le,"automaticInputContainerReference");function Ie(e,t=new Set){if(e===null||typeof e!="object"||t.has(e))return;if(t.add(e),Array.isArray(e)){for(let s of e){let o=Ie(s,t);if(o)return o}return}let n=e,r=n.container,i=n.path;if(typeof r=="string"&&Array.isArray(i)){let s=i.filter(o=>typeof o=="string");if(r==="@renderer"&&s.includes(z[0])||r==="@object"&&s.includes("_renderer"))return `${r}.${s.join(".")}`}for(let s of Object.values(n)){let o=Ie(s,t);if(o)return o}}l(Ie,"transientRendererReference");function ye(e){return p(e)&&e.isNode===true}l(ye,"isNode");function N(e){if(p(e)&&typeof e.getSelf=="function"){let t=e.getSelf();return ye(t)?t:void 0}return ye(e)?e:void 0}l(N,"nodeFrom");function ut(e){let t=new Map;if(e.isNode!==true)return t;t.set(e,[]);let n=[e];for(let r=0;r<n.length;r++){let i=n[r];if(!i||typeof i.getSerializeChildren!="function")continue;let s=t.get(i)??[],o=0;for(let c of i.getSerializeChildren()){let a=N(c.childNode);if(a&&!t.has(a)&&(t.set(a,[...s,o]),n.push(a)),o++,o>Re)throw new Error("Shader node graph exceeds the capture child limit.")}}return t}l(ut,"indexNodeGraph");function Nt(e){if(e.k==="owned"){let t=Nt(e.owner);return t===e.owner?e:{...e,owner:t}}if(e.k==="container"&&e.key==="@renderer"&&e.path.length>=4&&e.path[0]===z[0]&&e.path[1]===z[1]&&e.path.at(-1)==="mrt"){let t=e.path[2],n=typeof t=="string"?Te(t):void 0;if(n!==void 0){let r=At(n.attachmentState);return {k:"recipe",id:P.renderContextMrt,version:1,input:{attachmentState:n.attachmentState,callDepth:n.callDepth,...r===void 0?{}:{samples:r}}}}}return e}l(Nt,"stableRenderContextAddress");function At(e){let t=e.split(":");if(t.length!==6)return;let n=Number(t[3]);return Number.isSafeInteger(n)&&n>=0?n:void 0}l(At,"renderAttachmentSamples");function Yt(e,t){let n=p(e)?e:{},r={isDepthTexture:n.isDepthTexture===true,isRenderTargetTexture:n.isRenderTargetTexture===true,isDataTexture:n.isDataTexture===true,isData3DTexture:n.isData3DTexture===true,isCubeTexture:n.isCubeTexture===true,format:typeof n.format=="number"?n.format:null,type:typeof n.type=="number"?n.type:null,compareFunction:typeof n.compareFunction=="number"?n.compareFunction:null};typeof n.name=="string"&&n.name.length>0&&(r.name=n.name),typeof n.colorSpace=="string"&&n.colorSpace.length>0&&(r.colorSpace=n.colorSpace);let i=At(t);return i!==void 0&&(r.samples=i),r}l(Yt,"textureResourceSignature");function Xt(e,t){if(e.k!=="inputNode"||e.value.container!=="@renderer")return e;let n=e.value.path;if(n.length<4||n[0]!==z[0]||n[1]!==z[1]||typeof n[2]!="string")return e;let r=Te(n[2]);if(r===void 0)return e;let i=n[3]==="depthTexture"&&n.length===4?"depthTexture":n[3]==="textures"&&n.length===5&&Number.isSafeInteger(n[4])?"texture":void 0;if(i===void 0)return e;let{k:s,value:o,...c}=e;return {k:"recipe",id:P.renderContextInput,version:1,input:{attachmentState:r.attachmentState,callDepth:r.callDepth,mrt:r.mrtState!=="default",resource:i,...i==="texture"?{index:Number(n[4])}:{},texture:Yt(t,r.attachmentState),node:c}}}l(Xt,"stableRenderContextInputAddress");function R(e){if(!p(e))return typeof e;let t=e.constructor;return (typeof t=="function"||p(t))&&typeof t.name=="string"?t.name:"unknown"}l(R,"constructorName");function ft(e){if(!p(e))return R(e);let t=p(e.image)?e.image:void 0;return [R(e),typeof e.uuid=="string"?`uuid=${e.uuid}`:"",typeof e.name=="string"&&e.name?`name=${e.name}`:"",e.isRenderTargetTexture===true?"renderTarget":"",e.isPMREMTexture===true?"pmrem":"",t&&typeof t.width=="number"&&typeof t.height=="number"?`${t.width}x${t.height}`:"",typeof e.format=="number"?`format=${e.format}`:"",typeof e.type=="number"?`type=${e.type}`:""].filter(Boolean).join("/")}l(ft,"textureLabel");function ue(e,t){return typeof e=="string"&&e.length>0?e.slice(0,512):t}l(ue,"boundedLabel");function Zt(){return typeof performance=="object"&&typeof performance.now=="function"?performance.now():Date.now()}l(Zt,"now");function Tt(e){return p(e)&&typeof e.then=="function"}l(Tt,"promiseLike");function Qt(e){A={capture:e.capture===true,forceLive:e.forceLive===true,settleFrames:Number.isSafeInteger(e.settleFrames)&&e.settleFrames>=0?e.settleFrames:60,settleTimeoutMs:Number.isSafeInteger(e.settleTimeoutMs)&&Number(e.settleTimeoutMs)>=1e3?Number(e.settleTimeoutMs):3e4,visibilityGuard:e.visibilityGuard===true,...typeof e.captureId=="string"?{captureId:e.captureId}:{},...typeof e.sessionKey=="string"?{sessionKey:e.sessionKey}:{},...typeof e.token=="string"?{token:e.token}:{},readiness:{...typeof e.readiness?.selector=="string"?{selector:e.readiness.selector}:{},...typeof e.readiness?.global=="string"?{global:e.readiness.global}:{}},transform:e.transform},ne=void 0,re=false,J=void 0,Y=void 0,W=false,Oe=0,de=void 0,_=void 0,Reflect.set(globalThis,Ft,n=>{p(n)&&lt(n);});let t=Reflect.get(globalThis,Dt);p(t)&&lt(t),(A.capture||jt())&&en();}l(Qt,"configureThreeBlocksShaderCapture");function jt(){let e=Reflect.get(globalThis,"location"),t=p(e)?Reflect.get(e,"search"):void 0;if(typeof t!="string")return false;let n=new URLSearchParams(t),r=n.get("threeBlocksShaderMode");return n.get("capture")==="1"||r==="live"||r==="precompiled"}l(jt,"drivenShaderSession");function He(){return A.capture||A.forceLive||jt()}l(He,"shaderSessionActive");function lt(e){if(B=e,!A.capture)return;let t=Ct(),n=e.automaticRegistrationPrefix,r=typeof n=="function"?Reflect.apply(n,e,[t]):void 0;typeof r=="string"&&(_=r);}l(lt,"adoptCaptureCache");function Vt(e){if(!A.capture||B===void 0)return;let t=B.automaticRegistrationPrefix,n=typeof t=="function"?Reflect.apply(t,B,[e]):void 0;if(typeof n=="string"){_=n;return}let r=B.enableAutomaticRegistration;if(typeof r=="function"){_="auto";try{Reflect.apply(r,B,[{scene:e,prefix:_}]);}catch(i){throw _=void 0,i}}}l(Vt,"ensureCaptureAutomaticRegistration");function en(){if(dt)return;let e=globalThis,t=e.requestAnimationFrame;if(typeof t!="function")return;dt=true;let n=0,r=0,i=false,s=new Map,o=l(()=>{i||s.size===0||(i=true,Reflect.apply(t,e,[()=>{i=false;let c=[...s.values()];s.clear();let a=n++*(1e3/60);for(let d of c)try{d(a);}catch(u){queueMicrotask(()=>{throw u});}o();}]));},"schedule");Reflect.set(e,"requestAnimationFrame",c=>{let a=++r;return s.set(a,c),o(),a}),Reflect.set(e,"cancelAnimationFrame",c=>{s.delete(c);});}l(en,"installDeterministicRaf");function I(e,t){if(!B)return;let n=B[e];return typeof n=="function"?Reflect.apply(n,B,t):void 0}l(I,"cacheCall");function Ct(){if(B&&typeof B.activeScene=="string"&&B.activeScene!=="default")return B.activeScene;let e=Reflect.get(globalThis,"location"),t=p(e)?Reflect.get(e,"search"):void 0,n=typeof t=="string"?new URLSearchParams(t).get("captureId"):null;return n!==null&&Gt.test(n)?n:B&&typeof B.activeScene=="string"?B.activeScene:"default"}l(Ct,"activeShaderCaptureScene");function X(){return Ct()}l(X,"activeScene");function ae(e,t,n,r){let i=I(e==="compute"?"registrationForCompute":"registrationForRender",e==="compute"?[t,n]:[t,n,r]);return (!p(i)||typeof i.key!="string")&&(Vt(n),i=I(e==="compute"?"registrationForCompute":"registrationForRender",e==="compute"?[t,n]:[t,n,r])),p(i)&&typeof i.key=="string"?i:void 0}l(ae,"sceneRegistration");function tn(e){return e.key}l(tn,"capturedRegistrationKey");function ze(e,t){let n=t==="compute"?e.object:e.material;return n!==null&&typeof n=="object"?n:void 0}l(ze,"builderTarget");function xt(e){return e.material===null||e.material===void 0?"compute":"render"}l(xt,"buildKind");function xe(e){if(!p(e))return;let t={};for(let n of ["uuid","id","name","type"]){let r=e[n];typeof r=="string"?t[n]=ue(r,""):(typeof r=="number"&&Number.isFinite(r)||typeof r=="boolean")&&(t[n]=r);}return Object.keys(t).length===0?void 0:t}l(xe,"objectIdentity");function nn(e,t,n,r){if(ge.length>=Re)return;let i=e==="compute"?t.object:t.material,s=ue(p(i)?i.name??i.type:void 0,"unknown"),o=I("registrations",[n]),c=xe(i),a=p(r)?xe(r.material):void 0;ge.push({kind:e,name:s,reason:e==="compute"?`unregistered compute "${s}"`:`unregistered material "${s}"`,...c===void 0?{}:{target:c},...a===void 0?{}:{renderObjectMaterial:a},...Array.isArray(o)?{registrations:o.slice(0,16).flatMap(d=>{if(!p(d))return [];let u=xe(d.target);return [{...typeof d.key=="string"?{key:ue(d.key,"")}:{},...typeof d.kind=="string"?{kind:ue(d.kind,"")}:{},...u??{},sameTarget:d.target===i,...p(r)?{sameRenderObjectMaterial:d.target===r.material}:{}}]})}:{}});}l(nn,"addSkipped");function pt(e,t,n=s=>{x.buildMs+=s;},r=Zt,i){let s=e[t];typeof s=="function"&&Reflect.set(e,t,l(function(...c){let a=r(),d;try{d=Reflect.apply(s,this,c);}catch(u){throw n(r()-a),u}return Tt(d)?Promise.resolve(d).then(u=>(n(r()-a),i?.(),u),u=>{throw n(r()-a),u}):(n(r()-a),i?.(),d)},"timedBuild"));}l(pt,"wrapThreeBlocksCaptureTimedBuild");function vt(e,t,n){if(!He()||!p(e)||!p(t)||ot.has(e))return;ot.add(e);let r=X(),i=I("containers",[r]);Ue.set(e,new Set(Array.isArray(i)?i.filter(b=>p(b)&&typeof b.key=="string").map(b=>String(b.key)):[]));let s=p(n)&&p(n.material)?n:void 0,o=s?"render":xt(e),c=o==="render"&&s?be("render",s):ze(e,o);c&&(s&&wt.set(e,s),ae(o,c,X(),s));let a=[];St.set(e,a);let d=e.getUniformFromNode;typeof d=="function"&&Reflect.set(e,"getUniformFromNode",l(function(j,g,f,m){let y=Reflect.apply(d,this,[j,g,f,m]),k=N(j),S=typeof f=="string"?f:this.shaderStage;if(k&&typeof g=="string"&&(S==="vertex"||S==="fragment"||S==="compute")){let v=p(y)&&typeof y.name=="string"?y.name:typeof m=="string"?m:null;a.push({node:k,type:g,stage:S,name:v,...typeof k.id=="number"?{nid:k.id}:{}});}return y},"captureUniform"));let u=l(()=>{it.has(e)||(it.add(e),Bt(e,t));},"recordBuild");pt(e,"build",void 0,void 0,u),pt(e,"buildAsync",void 0,void 0,u);}l(vt,"instrumentThreeBlocksShaderBuilder");function te(e){return Object.assign(Object.create(Object.getPrototypeOf(e)),e)}l(te,"cloneCaptureRecord");function rn(e){let t=Object.create(e);for(let o of ["object","material","scene","camera","lightsNode","context","vertexShader","fragmentShader","computeShader","observer","hardwareClipping","updateNodes","updateBeforeNodes","updateAfterNodes"]){let c=e[o];Reflect.set(t,o,o==="material"&&p(c)?te(c):Array.isArray(c)?[...c]:c);}let n=typeof e.getAttributesArray=="function"?Reflect.apply(e.getAttributesArray,e,[]):[],r=Array.isArray(n)?n.map(o=>p(o)?te(o):o):[];Reflect.set(t,"getAttributesArray",()=>r);let i=typeof e.getBindings=="function"?Reflect.apply(e.getBindings,e,[]):[],s=Array.isArray(i)?i.map(o=>{if(!p(o))return o;let c=te(o),a=Array.isArray(o.bindings)?o.bindings.map(d=>{if(!p(d))return d;let u=te(d);return Array.isArray(d.uniforms)&&Reflect.set(u,"uniforms",d.uniforms.map(b=>p(b)?te(b):b)),u}):[];return Reflect.set(c,"bindings",a),c}):[];return Reflect.set(t,"getBindings",()=>s),t}l(rn,"snapshotBuilderState");function Bt(e,t){if(!He()||A.capture&&se||!p(e)||!p(t))return;x.buildCalls++,Y=Date.now(),W=false;let n=xt(e);n==="compute"?x.computeBuilds++:x.renderBuilds++;let r=X();K=r;let i=Ue.get(e)??new Set,s=I("containers",[r]);if(Array.isArray(s))for(let d of s)p(d)&&typeof d.key=="string"&&he(d.key)&&!i.has(d.key)&&Pe.add(d.key);Ue.delete(e);let o=ze(e,n),c=n==="render"?wt.get(e)??(p(e.object)?e.object:void 0):void 0,a=o?ae(n,o,r,c):void 0;if(a){x.registeredBuilds++,n==="compute"?x.registeredComputeBuilds++:x.registeredRenderBuilds++;let d=tn(a);if(pe.length<Re){let u=rn(e),b={scene:r,key:d,kind:n,builder:u,renderer:t,...c?{renderObject:c}:{},journal:[...St.get(e)??[]]};pe.push(b);}}else nn(n,e,r,c);Et();}l(Bt,"recordThreeBlocksShaderBuild");function be(e,t){return e==="compute"?t!==null&&typeof t=="object"?t:void 0:p(t)&&t.material!==null&&typeof t.material=="object"?t.material:void 0}l(be,"targetForProvider");function gt(e,t,n){if(A.capture&&se)return;let r=X();K=r;let i=be(e,t),s=e==="render"&&p(t)?t:void 0,o=i?ae(e,i,r,s):void 0;n!=null?(x.injected++,e==="compute"?x.injectedCompute++:x.injectedRender++):o&&(x.missed++,e==="compute"?x.missedCompute++:x.missedRender++,x.missedKeys.length<Re&&!x.missedKeys.includes(o.key)&&x.missedKeys.push(o.key)),A.capture||Et();}l(gt,"recordProviderResult");function on(e){let t=e.debug;if(!p(t))return;let n=t.onNodeBuilderCreated,r=ct.get(e);if(n===r)return;let i=typeof n=="function"?n:void 0,s=l(function(c,a){i!==void 0&&Reflect.apply(i,this,[c,a]),vt(c,e,a);},"captureNodeBuilder");ct.set(e,s),t.onNodeBuilderCreated=s;}l(on,"installCaptureBuilderCallback");function sn(e,t,n){if(!p(e))return;if(n!==void 0&&!tt(n))throw new Error(`@three-blocks/devtools supports Three.js 0.185.x capture; received revision ${JSON.stringify(n)}.`);if(!He())return;if(p(t)&&t!==me&&(me=t,fe=void 0),on(e),A.forceLive){let a=at.get(e);a||(a={__threeBlocksCaptureForceLive:true,getForRender(d){let u=be("render",d);u&&ae("render",u,X(),p(d)?d:void 0);},getForCompute(d){let u=be("compute",d);u&&ae("compute",u,X());}},at.set(e,a)),e.nodeBuilderStateProvider=a;return}let r=e.nodeBuilderStateProvider;if(!p(r))return;let i=st.get(r);if(i){e.nodeBuilderStateProvider=i;return}if(r.__threeBlocksCaptureWrapper===true)return;let s=r.getForRender,o=r.getForCompute;if(typeof s!="function"||typeof o!="function")return;let c={__threeBlocksCaptureWrapper:true,getForRender(a,d){let u=Reflect.apply(s,r,[a,d]);return gt("render",a,u),u},getForCompute(a,d){let u=Reflect.apply(o,r,[a,d]);return gt("compute",a,u),u}};st.set(r,c),e.nodeBuilderStateProvider=c;}l(sn,"prepareThreeBlocksShaderRenderer");var an=Object.freeze({configureThreeBlocksShaderCapture:Qt,instrumentThreeBlocksShaderBuilder:vt,prepareThreeBlocksShaderRenderer:sn,recordThreeBlocksShaderBuild:Bt});Reflect.set(globalThis,Symbol.for(nt),an);function cn(e){return N(e)}l(cn,"unwrapTsl");var fe;function L(){if(fe)return fe;let e=new Map;for(let[t,n]of Object.entries(me)){let r=cn(n);r&&!e.has(r)&&e.set(r,t);}return fe=e,e}l(L,"tslMap");function dn(e,t){if(!(!t||!p(e._nodes)||typeof e._nodes.getEnvironmentNode!="function"))return N(Reflect.apply(e._nodes.getEnvironmentNode,e._nodes,[t]))}l(dn,"sceneEnvironmentNode");var mt=new WeakMap;function un(e,t,n){let r=Reflect.get(e,"getLightNodes");if(typeof r!="function")return [];let i=Reflect.get(t,"getDataFromNode");if(typeof i=="function"){let c=Reflect.apply(i,t,[e]),a=p(c)?c.lightNodes:void 0;if(Array.isArray(a))return a.map(N).filter(d=>d!==void 0)}let o=Reflect.apply(r,e,[{renderer:n,context:{materialLightings:[]},getDataFromNode(c){let a=mt.get(c);return a||(a={},mt.set(c,a)),a}}]);return Array.isArray(o)?o.map(N).filter(c=>c!==void 0):[]}l(un,"lightNodes");function ht(e,t){let n=Reflect.get(me,e);return typeof n=="function"?N(Reflect.apply(n,void 0,[t])):void 0}l(ht,"lightUniform");function ve(e){if(!e)return [];let t=[],n=Reflect.get(e,"traverse");return typeof n=="function"&&Reflect.apply(n,e,[r=>{r!==null&&typeof r=="object"&&Reflect.get(r,"isLight")===true&&t.push(r);}]),t}l(ve,"sceneLights");function fn(e){if(!e)return [];let t=[],n=Reflect.get(e,"traverse");return typeof n=="function"&&Reflect.apply(n,e,[r=>{r!==null&&typeof r=="object"&&t.push(r);}]),t}l(fn,"sceneObjects");function ln(e){return !(Reflect.get(e,"isNode")===true||Reflect.get(e,"isObject3D")===true||Reflect.get(e,"isTexture")===true||Reflect.get(e,"isMaterial")===true||ArrayBuffer.isView(e)||e instanceof ArrayBuffer||e instanceof Set||e instanceof Promise)}l(ln,"isScannable");function pn(e,t,n,r=()=>false,i=false){let s=new Set,o=[{value:e,path:[],depth:0}];for(let c=0;c<o.length;c++){let a=o[c];if(!a||s.has(a.value)||a.depth>Kt)continue;let{value:d,path:u,depth:b}=a;s.add(d);let j=Array.isArray(d)?Array.from(d,(g,f)=>[f,g]):d instanceof Map?[...d.entries()].filter(g=>typeof g[0]=="string"||typeof g[0]=="number").map(([g,f])=>[`map:${String(g)}`,f]):Object.keys(d).map(g=>[g,Reflect.get(d,g)]);for(let[g,f]of j){if(f===null||typeof f!="object")continue;let m=[...u,g];if(!r(m))if(ye(f)){let y=N(f);y&&t(y,m),i&&o.push({value:y??f,path:m,depth:b+1});}else n(f,m),ln(f)&&o.push({value:f,path:m,depth:b+1});}}}l(pn,"scanContainer");function gn(e){if(new Uint8Array(new Uint16Array([258]).buffer)[0]!==2)throw new Error("Shader capture requires a little-endian host.");let t=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),n=t.toBase64;if(typeof n=="function")return n.call(t);let r="",i=32768;for(let s=0;s<t.length;s+=i)r+=String.fromCharCode(...t.subarray(s,s+i));return btoa(r)}l(gn,"bytesToBase64");function yt(e){if(typeof e=="number"&&Number.isFinite(e)||typeof e=="boolean")return e;if(p(e)){for(let[t,n]of [["isVector2","v2"],["isVector3","v3"],["isVector4","v4"],["isColor","c"],["isMatrix3","m3"],["isMatrix4","m4"]])if(e[t]===true&&typeof e.toArray=="function"){let r=Reflect.apply(e.toArray,e,[]);if(Array.isArray(r)&&r.every(i=>typeof i=="number"&&Number.isFinite(i)))return {t:n,a:r}}}}l(yt,"serializeValueItem");function bt(e){if(Array.isArray(e)){let r=e.map(yt);return r.every(i=>i!==void 0)?{t:"arr",items:r}:void 0}let t=yt(e);if(t!==void 0)return t;if(p(e)&&e.isTexture===true&&e.image==null&&e.isRenderTargetTexture!==true&&e.version===0&&(e.name===""||e.name===void 0))return {t:"tex"};if(!p(e)||e.isDataTexture!==true||!p(e.image))return;let n=e.image.data;if(!(!ArrayBuffer.isView(n)||typeof Reflect.get(n,"length")!="number"||Number(Reflect.get(n,"length"))>Ht))return {t:"dtex",arrayType:R(n),data:gn(n),width:typeof e.image.width=="number"?e.image.width:0,height:typeof e.image.height=="number"?e.image.height:0,format:typeof e.format=="number"?e.format:0,type:typeof e.type=="number"?e.type:0,minFilter:typeof e.minFilter=="number"?e.minFilter:0,magFilter:typeof e.magFilter=="number"?e.magFilter:0,wrapS:typeof e.wrapS=="number"?e.wrapS:0,wrapT:typeof e.wrapT=="number"?e.wrapT:0,name:typeof e.name=="string"?e.name:""}}l(bt,"serializeStaticValue");function mn(e){if(!(Object.hasOwn(e,"update")||Object.hasOwn(e,"updateBefore")||Object.hasOwn(e,"updateAfter"))){if(Reflect.get(e,"isStorageTextureNode")===true)return "storageTexture";if(Reflect.get(e,"isStorageBufferNode")===true)return "storage";switch(R(e)){case "BufferNode":return "buffer";case "BufferAttributeNode":return "bufferAttribute";case "Texture3DNode":return "texture3D";case "CubeTextureNode":return "cubeTexture";case "TextureNode":return "texture";case "UniformArrayNode":return "uniformArray";case "UniformNode":return "uniform";case "PMREMNode":return "pmremTexture";default:return}}}l(mn,"inputClass");function Rt(e,t){let n=R(e);return n!==R(t)||["TextureNode","Texture3DNode","CubeTextureNode"].includes(n)||!!N(Reflect.get(e,"compareNode"))!=!!N(Reflect.get(t,"compareNode"))||Reflect.get(e,"access")!==Reflect.get(t,"access")?false:R(e)==="BufferAttributeNode"?["bufferType","bufferStride","bufferOffset","usage","instanced"].every(r=>Reflect.get(e,r)===Reflect.get(t,r)):true}l(Rt,"hasEquivalentSharedInputShape");function hn(e){if(e.k==="inputNode")return e.value;if(e.k==="container")return {container:e.key,path:[...e.path,"value"]};if(e.k==="anchor"&&e.path.length===0)return {container:"@material",path:[e.slot,"value"]}}l(hn,"sharedTextureValueLocation");function yn(e){if(e?.k==="container")return {container:e.key,path:e.path};if(e?.k==="anchor"&&e.path.length===0)return {container:"@material",path:[e.slot]}}l(yn,"sharedTextureNodeLocation");function kt(e,t){if(e.isDataArrayTexture!==true||e.format!==1023||e.type!==1015||!p(e.image)||e.image.data===null||typeof e.image.data!="object"||R(e.image.data)!=="Float32Array")return false;let n=t.morphAttributes,r=t.attributes;if(!p(n)||!p(r)||!p(r.position))return false;let i=Array.isArray(n.position)?n.position:[],s=Array.isArray(n.normal)?n.normal:[],o=Array.isArray(n.color)?n.color:[],c=i.length>0?i:s.length>0?s:o;if(c.length===0)return false;let a=r.position.count;if(!Number.isSafeInteger(a)||Number(a)<0)return false;let d=o.length>0?3:s.length>0?2:1,u=Number(a)*d,b=1;return u>4096&&(b=Math.ceil(u/4096),u=4096),e.image.width===u&&e.image.height===b&&e.image.depth===c.length&&Reflect.get(e.image.data,"length")===u*b*4*c.length}l(kt,"isThreeR185MorphTargetTexture");function Fe(e,t=new Set){if(e===null||typeof e!="object"||t.has(e))return false;if(t.add(e),Array.isArray(e))return e.some(r=>Fe(r,t));let n=e;return n.k==="recipe"?true:Object.values(n).some(r=>Fe(r,t))}l(Fe,"addressUsesRecipe");var De=class{static{l(this,"RecipeCollisionIndex");}#t=new Map;register(t,n,r,i){if(!Fe(t)||t.k==="recipe"&&t.id===P.skinningEvent)return;let s=JSON.stringify(t),o=this.#t.get(s);if(o!==void 0&&o.source!==n)throw new Error(`Shader recipe collision between "${o.shaderKey}" (${o.usage}) and "${r}" (${i}) for ${s}. Register the live resources in distinct stable application containers or make their structural recipe signatures unique.`);o===void 0&&this.#t.set(s,{source:n,shaderKey:r,usage:i});}};function G(e){return e.includes("_inspector")||e.includes("_renderer")||e.includes("_lastRenderer")||e.includes("renderer")||e.some(t=>typeof t=="string"&&t.startsWith("_cached"))}l(G,"applicationContainerPathIsTransient");var Ke=class{static{l(this,"CaptureClassifier");}#t;#a;#e=new Map;#c=new Map;#n=new Map;#d=new Map;#o=[];#s=[];#l=0;constructor(t,n){this.#t=t,this.#a=n;let r=t.kind==="compute"?ye(t.target)?[{slot:"compute",node:t.target}]:[]:et.flatMap(g=>{let f=N(Reflect.get(t.target,g));return f?[{slot:g,node:f}]:[]});for(let g of r)this.#r(g.node,{k:"anchor",key:t.key,slot:g.slot,path:[]});let i=N(t.builder.lightsNode);this.#s.length=0;let s=this.#s;if(i){let g=un(i,t.builder,t.renderer);this.#o.push(`lights=${g.length}`);for(let f=0;f<g.length;f++){let m=g[f];if(!m)continue;let y={k:"lightNode",light:f};this.#r(m,y);let k=Reflect.get(m,"light");if(Reflect.get(m,"isAnalyticLightNode")===true){let S=N(Reflect.get(m,"baseColorNode")),v=S??N(Reflect.get(m,"colorNode"));v&&this.#e.set(v,{k:"owned",owner:y,path:[S!==void 0||k!==null&&typeof k=="object"&&Reflect.get(k,"castShadow")===true?"baseColorNode":"colorNode"]});}if(k!==null&&typeof k=="object")for(let S of rt){s[f]=k;let v=ht(S,k);this.#o.push(`${f}/${S}=${v?`${R(v)}:${R(Reflect.get(v,"value"))}:${String(Reflect.get(v,"updateType"))}`:"missing"}`),v&&this.#r(v,{k:"lightUniform",fn:S,light:f});}}}else this.#o.push("lights=missing");let o=t.builder.scene!==null&&typeof t.builder.scene=="object"?t.builder.scene:null;for(let[g,f]of ve(o).entries()){if(s.includes(f))continue;let m=s.length+g;for(let y of rt){let k=ht(y,f);k&&this.#r(k,{k:"lightUniform",fn:y,light:m,sceneLight:g});}}let c=dn(t.renderer,o);c&&this.#r(c,{k:"sceneEnv"});let a=l((g,f,m,y=false)=>{this.#n.has(f)||this.#n.set(f,{container:g,path:[]}),pn(f,(k,S)=>this.#r(k,{k:"container",key:g,path:S}),(k,S)=>{this.#n.has(k)||this.#n.set(k,{container:g,path:S});},m,y);},"scan");if(t.kind==="render")for(let g of Object.getOwnPropertyNames(t.target)){let f=N(Reflect.get(t.target,g));f&&!this.#e.has(f)&&this.#e.set(f,{k:"container",key:"@material",path:[g]});}let d=I("containers",[t.scene]),u=Array.isArray(d)?d.find(g=>p(g)&&typeof g.key=="string"&&g.key.includes("/resource-batched-text-")):void 0;if(p(u)&&typeof u.key=="string"&&u.target!==null&&typeof u.target=="object"&&a(u.key,u.target,G,true),Array.isArray(d)){for(let g of d)if(g!==u&&p(g)&&typeof g.key=="string"&&g.target!==null&&typeof g.target=="object"){let f=g.key;if(he(f)||Pe.has(f))continue;a(f,g.target,G,true);}}if(t.kind==="render"){a("@material",t.target,k=>k.some(S=>typeof S=="string"&&S.startsWith("_")),true),t.renderObject&&a("@renderObject",t.renderObject,k=>k.length===1&&k[0]!=="context");let g=Reflect.get(t.renderer,"getMRT"),f=Reflect.get(t.builder,"context"),y=(p(f)?N(f.mrt):void 0)??(typeof g=="function"?N(Reflect.apply(g,t.renderer,[])):void 0);t.renderObject&&y&&this.#r(y,{k:"container",key:"@renderObject",path:["context","mrt"]});}let b=t.builder.object;b!==null&&typeof b=="object"&&a("@object",b,g=>G(g)||t.kind==="compute"&&g.some(f=>typeof f=="string"&&f.startsWith("_")),t.kind==="compute"),o&&a("@scene",o,G);for(let[g,f]of fn(o).entries())a(`@sceneObject:${g}`,f,G);a("@renderer",t.renderer,g=>g.length>=1&&g[0]==="_inspector"||g.length===2&&g[0]==="_nodes"&&g[1]==="nodeBuilderCache");let j=I("containers",[t.scene]);if(Array.isArray(j)){for(let g of j)if(p(g)&&typeof g.key=="string"&&g.target!==null&&typeof g.target=="object"){let f=g.key;if(he(f)||Pe.has(f))continue;a(f,g.target,G,true);}}}#i(t,n,r,i){let s=Reflect.get(t,"value"),o=this.#c.get(t)??i??(r.k==="recipe"&&r.id===P.renderContextInput&&s!==null&&typeof s=="object"?s:t);return this.#c.set(t,o),this.#a.register(r,o,this.#t.key,n),r}#r(t,n){!this.#e.has(t)&&!L().has(t)&&this.#e.set(t,n);for(let[r,i]of ut(t))r===t||this.#e.has(r)||L().has(r)||this.#e.set(r,{k:"owned",owner:n,path:i});}#u(t){if(R(t)!=="ReferenceNode")return;let n=Reflect.get(t,"property"),r=Reflect.get(t,"uniformType");if(typeof n!="string"||n.length===0||typeof r!="string"||r.length===0)return;let i=Reflect.get(t,"object"),s=i!==null&&typeof i=="object"?this.#n.get(i):void 0;if(i!==null&&typeof i=="object"&&s===void 0)return;let o=N(Reflect.get(t,"group")),c=o?L().get(o):void 0;if(o&&c===void 0)return;let a=Reflect.get(t,"count");if(a!==null&&(!Number.isSafeInteger(a)||Number(a)<0))return;let d=Reflect.get(t,"name");return {k:"reference",property:n,uniformType:r,...a===null?{}:{count:Number(a)},...s===void 0?{}:{object:s},...c===void 0?{}:{group:c},...typeof d=="string"&&d.length>0?{name:d}:{}}}#f(t){if(R(t)!=="EventNode"||Reflect.get(t,"eventType")!=="object")return;let n=this.#t.builder.object,r=Reflect.get(t,"callback"),i=typeof r=="function"?Function.prototype.toString.call(r):"";if(!p(n)||!i.includes("morphTargetsRelative")||!i.includes("morphTargetInfluences")||!i.includes(".reduce")||!i.includes(".update"))return;let s=n.morphTargetInfluences,o=n.geometry;if(!Array.isArray(s)||!p(o))return;let c=o.morphAttributes;if(!p(c))return;let a=Array.isArray(c.position)?c.position:[],d=Array.isArray(c.normal)?c.normal:[],u=Array.isArray(c.color)?c.color:[],b=a.length>0?a:d.length>0?d:u;if(b.length===0||b.length!==s.length)return;let j=this.#t.journal.some(m=>{let y=Reflect.get(m.node,"value");return R(m.node)==="TextureNode"&&m.type==="texture"&&m.stage==="vertex"&&Reflect.get(m.node,"sampler")===false&&p(y)&&kt(y,o)}),g=this.#t.journal.flatMap((m,y)=>R(m.node)==="UniformArrayNode"?[`${y}:${m.type}/${m.stage}:same=${Reflect.get(m.node,"array")===s}:length=${Array.isArray(Reflect.get(m.node,"array"))?Reflect.get(m.node,"array").length:"na"}`]:[]);if(this.#o.push(`morph=${String(Reflect.get(n,"name")??"")}:targets=${b.length}:influences=${s.length}:texture=${j}:arrays=[${g.join(",")}]`),!j)return;let f=this.#t.journal.flatMap((m,y)=>{let k=Reflect.get(m.node,"array");if(R(m.node)!=="UniformArrayNode"||m.type!=="buffer"||m.stage!=="vertex"||k!==s&&(!Array.isArray(k)||k.length!==s.length))return [];let S=this.#t.journal[y-1];return S===void 0||R(S.node)!=="UniformNode"||S.type!=="float"||S.stage!=="vertex"||typeof Reflect.get(S.node,"value")!="number"||!Number.isFinite(Reflect.get(S.node,"value"))?[]:[{base:S.node,influences:m.node,count:s.length}]});return f.length===1?f[0]:void 0}#p(t){if(R(t)!=="EventNode"||Reflect.get(t,"eventType")!=="object")return;let n=this.#t.builder.object,r=Reflect.get(t,"callback"),i=typeof r=="function"?Function.prototype.toString.call(r):"";if(p(n)&&n.isSkinnedMesh===true&&i.includes("skeleton"))return {k:"recipe",id:P.skinningEvent,version:1};let s=this.#f(t);if(s){let o=this.#e.get(s.base),c=this.#e.get(s.influences);return o===void 0||c===void 0?void 0:{k:"recipe",id:P.morphUpdateEvent,version:1,input:{base:o,influences:c,count:s.count}}}}#g(t){if(R(t)!=="MaxMipLevelNode")return;let n=N(Reflect.get(t,"textureNode"));if(!n)return;let r=this.classify(n,"max-mip texture owner");return {k:"recipe",id:P.maxMip,version:1,input:r}}#m(t){if(R(t)!=="TextureNode"||Reflect.get(t,"sampler")!==false)return;let n=Reflect.get(t,"value"),r=this.#t.builder.object,i=p(r)?r.geometry:void 0;if(!(!p(r)||!p(n)||!p(i)||this.#n.has(n)||Reflect.get(r,"morphTexture")===n||!kt(n,i)))return {k:"recipe",id:P.morphTargetTexture,version:1}}noteUpdateNode(t){if(this.#e.has(t))return;let n=this.#f(t);if(n){let s=Reflect.get(n.influences,"elementType");this.#e.set(n.influences,{k:"inputNode",nodeClass:"uniformArray",value:{container:"@object",path:["morphTargetInfluences"]},access:null,uniformType:typeof s=="string"?s:null});}if(R(t)==="PMREMNode"){let s=this.classify(t,"PMREM update node ownership");for(let o of ["_texture","_width","_height","_maxMip"]){let c=N(Reflect.get(t,o));c&&this.#e.set(c,{k:"owned",owner:s,path:[o]});}return}let r;if(Reflect.get(t,"isMaterialReferenceNode")===true){let s=Reflect.get(t,"property"),o=Reflect.get(t,"uniformType"),c=Reflect.get(t,"referenceType"),a=typeof o=="string"||o===null?o:c;typeof s=="string"&&(typeof a=="string"||a===null)&&(r={k:"materialCache",property:s,type:a});}else r=this.#u(t);if(r===void 0){["TextureNode","Texture3DNode","CubeTextureNode"].includes(R(t))&&(r=this.classify(t,"texture update node ownership"));let s=r===void 0&&Reflect.get(t,"isTextureNode")===true?bt(Reflect.get(t,"value")):void 0;if(p(s)&&s.t==="tex"&&this.classify(t,"update node ownership"),r===void 0)return}this.#e.set(t,r);let i=N(Reflect.get(t,"node"));i&&this.#e.set(i,{k:"owned",owner:r,path:["node"],prime:"reference"});}shouldOmitUpdateNode(t){return R(t)==="InspectorNode"?true:R(t)==="EventNode"&&Reflect.get(t,"eventType")==="frame"&&p(this.#t.builder.object)&&Reflect.get(this.#t.builder.object,"isInstancedMesh")===true}#h(t){let n=this.#t.builder.scene!==null&&typeof this.#t.builder.scene=="object"?this.#t.builder.scene:null,r=this.#s.map((o,c)=>({light:o,address:{light:c}}));for(let[o,c]of ve(n).entries())this.#s.includes(c)||r.push({light:c,address:{light:this.#s.length+o,sceneLight:o}});if(r.length===0)return;if(Reflect.get(t,"isReferenceNode")===true){let o=Reflect.get(t,"object"),c=Reflect.get(t,"property");if(o===null||typeof o!="object"||typeof c!="string")return;let a=Jt[c],d=c==="near"?"shadowCameraNear":c==="far"?"shadowCameraFar":void 0;for(let u of r){let b=Reflect.get(u.light,"shadow");if(!(b===null||typeof b!="object")){if(a!==void 0&&b===o)return {k:"lightUniform",fn:a,...u.address};if(d!==void 0&&Reflect.get(b,"camera")===o)return {k:"lightUniform",fn:d,...u.address}}}return}if(Reflect.get(t,"isUniformNode")!==true)return;let i=Reflect.get(t,"update");if(typeof i!="function"||typeof Reflect.get(t,"value")!="number")return;let s=l(()=>{try{Reflect.apply(i,t,[{}]);}catch{}},"invoke");for(let o of r){let c=Reflect.get(o.light,"shadow"),a=c!==null&&typeof c=="object"?Reflect.get(c,"camera"):void 0;if(!(a===null||typeof a!="object"))for(let d of ["shadowCameraNear","shadowCameraFar"]){let u=d==="shadowCameraNear"?"near":"far",b=Reflect.get(a,u);if(typeof b!="number")continue;let j=b+12345.625,g=false;try{Reflect.set(a,u,j),s(),g=Reflect.get(t,"value")===j;}finally{Reflect.set(a,u,b),s();}if(g)return {k:"lightUniform",fn:d,...o.address}}}}classify(t,n){let r=Reflect.get(t,"name");if(typeof r=="string"&&qt.has(r))return {k:"namedRenderUniform",name:r};let i=this.#e.get(t);if(i)return this.#i(t,n,Nt(i));let s=this.#u(t);if(s)return this.#e.set(t,s),s;let o=this.#p(t);if(o)return this.#e.set(t,o),this.#i(t,n,o);let c=this.#g(t);if(c)return this.#e.set(t,c),this.#i(t,n,c);let a=this.#m(t);if(a){this.#e.set(t,a);let h=Reflect.get(t,"value");return this.#i(t,n,a,h!==null&&typeof h=="object"?h:t)}let d=N(Reflect.get(t,"referenceNode")),u=d!==void 0?this.#e.get(d):void 0;if(n.startsWith("uniform ")&&u!==void 0)return this.#e.set(t,u),u;let b=this.#t.builder.scene!==null&&typeof this.#t.builder.scene=="object"?this.#t.builder.scene:null,j=Reflect.get(t,"light");if(j!==null&&typeof j=="object"){let h=ve(b).indexOf(j);if(h>=0){let w={k:"lightNode",light:h,sceneLight:h};return Reflect.get(t,"isShadowBaseNode")===true?{k:"owned",owner:w,path:["shadowNode"]}:w}}let g=Reflect.get(t,"value"),f=Reflect.get(t,"array");if(g!==null&&typeof g=="object"||f!==null&&typeof f=="object")for(let[h,w]of this.#e){if(h===t)continue;let T=g!==null&&typeof g=="object"&&Reflect.get(h,"value")===g,C=f!==null&&typeof f=="object"&&Reflect.get(h,"array")===f;if(!(!T&&!C)){if(Rt(h,t))return this.#e.set(t,w),w;if(T&&["TextureNode","Texture3DNode","CubeTextureNode"].includes(R(t))){let $=hn(w);if($!==void 0){this.#n.set(g,$);break}}}}if(g!==null&&typeof g=="object")for(let[h,w]of L()){if(Reflect.get(h,"isViewportNode")!==true)continue;let T=N(Reflect.get(h,"_output"));if(T===void 0||Reflect.get(T,"value")!==g||!Rt(T,t))continue;let C={k:"owned",owner:{k:"tsl",name:w},path:["_output"]};return this.#e.set(t,C),C}let m=L().get(t);if(m)return {k:"tsl",name:m};for(let[h,w]of this.#e)for(let T of Object.getOwnPropertyNames(h))if(Reflect.get(h,T)===t){if((w.k==="inputNode"||w.k==="inputValue"||w.k==="recipe")&&!Wt.has(T))continue;let C={k:"owned",owner:w,path:[T]};return this.#e.set(t,C),C}for(let[h,w]of L()){for(let T of Object.getOwnPropertyNames(h))if(Reflect.get(h,T)===t)return {k:"owned",owner:{k:"tsl",name:w},path:[T]};for(let[T,C]of ut(h))if(T===t)return {k:"owned",owner:{k:"tsl",name:w},path:C}}if(R(t)==="ViewportTextureNode"){let h={k:"inputValue",nodeClass:"viewportMipTexture",json:{viewport:this.#l++}};return this.#e.set(t,h),h}if(R(t)==="PassMultipleTextureNode"){let h=N(Reflect.get(t,"passNode")),w=Reflect.get(t,"textureName"),T=Reflect.get(t,"previousTexture")===true?"_previousTextureNodes":"_textureNodes",C=h?this.#e.get(h)??[...this.#e].find(([F])=>N(F)===h)?.[1]:void 0,$=h?Reflect.get(h,T):void 0,V=p($)&&typeof w=="string"?N(Reflect.get($,w)):void 0;if(C&&typeof w=="string"&&V){let F={k:"owned",owner:C,path:[T,w]};return this.#e.set(t,F),F}this.#o.push(`passTexture=${R(h)}/${String(w)}/${T} owner=${C?JSON.stringify(C):"missing"} collection=${R($)} canonical=${R(V)}`);}let y=mn(t);if(y){let h=y==="uniformArray"?Reflect.get(t,"array"):Reflect.get(t,"value"),w=Reflect.get(t,"access"),T=y==="uniformArray"?Reflect.get(t,"elementType"):y==="storage"||y==="buffer"||y==="bufferAttribute"?Reflect.get(t,"bufferType"):Reflect.get(t,"uniformType"),C=typeof w=="string"?w:null,$=typeof T=="string"?T:null,V=N(Reflect.get(t,"group"))??N(Reflect.get(t,"groupNode")),F=V?L().get(V):void 0,qe=F?{group:F}:{},Se=Reflect.get(t,"bufferCount"),We=y==="storage"||y==="buffer"?{bufferCount:Number.isSafeInteger(Se)&&Number(Se)>=0?Number(Se):0,...y==="storage"?{atomic:Reflect.get(t,"isAtomic")===true,pbo:Reflect.get(t,"isPBO")===true}:{}}:{},ee=h!==null&&typeof h=="object"?this.#n.get(h):void 0;if(!ee&&h!==null&&typeof h=="object"){let U=Reflect.get(h,"array");U!==null&&typeof U=="object"&&(ee=this.#n.get(U));}let Je=y==="bufferAttribute"?{stride:Number.isSafeInteger(Reflect.get(t,"bufferStride"))?Number(Reflect.get(t,"bufferStride")):0,offset:Number.isSafeInteger(Reflect.get(t,"bufferOffset"))?Number(Reflect.get(t,"bufferOffset")):0,usage:Number.isSafeInteger(Reflect.get(t,"usage"))?Number(Reflect.get(t,"usage")):0,instanced:Reflect.get(t,"instanced")===true||h!==null&&typeof h=="object"&&(Reflect.get(h,"isInstancedBufferAttribute")===true||Reflect.get(h,"isInstancedInterleavedBuffer")===true)||ee?.path.includes("instanceMatrix")===true||ee?.path.includes("instanceColor")===true}:{},Ye=["texture","cubeTexture","texture3D"].includes(y)&&N(Reflect.get(t,"compareNode"))?{comparison:true}:{},Xe=["texture","cubeTexture"].includes(y)?yn(u):void 0,Ze=Xe??ee,$t=Xe===void 0?y:`${y}Reference`,we=Reflect.get(t,"name"),Qe=typeof we=="string"&&we.length>0?{name:we}:{},H=Ze?{k:"inputNode",nodeClass:$t,value:Ze,access:C,uniformType:$,...Qe,...qe,...We,...Je,...Ye}:void 0;if(!H){let U=bt(h);U!==void 0&&(H={k:"inputValue",nodeClass:y,json:U,access:C,uniformType:$,...Qe,...qe,...We,...Je,...Ye});}if(H){let U=JSON.stringify(H),Ne=this.#d.get(U)??0;this.#d.set(U,Ne+1);let Ut=Ne===0?H:{...H,n:Ne},Ve=Xt(Ut,h);return this.#e.set(t,Ve),this.#i(t,n,Ve,h!==null&&typeof h=="object"?h:t)}}let k=this.#h(t);if(k)return this.#e.set(t,k),this.#i(t,n,k);let S=l(h=>R(h)===R(t)&&R(Reflect.get(h,"value"))===R(Reflect.get(t,"value"))&&Reflect.get(h,"updateType")===Reflect.get(t,"updateType"),"comparable"),v=[...L()].filter(([h])=>S(h)).slice(0,8).map(([,h])=>h),ke=[...this.#e].filter(([h])=>S(h)).slice(0,8).map(([h,w])=>`${JSON.stringify(w)}@${ft(Reflect.get(h,"value"))}`),M=p(Reflect.get(t,"value"))?Reflect.get(Reflect.get(t,"value"),"uuid"):void 0,Z=typeof M=="string"?[...this.#e].filter(([h])=>p(Reflect.get(h,"value"))&&Reflect.get(Reflect.get(h,"value"),"uuid")===M).slice(0,12).map(([h,w])=>`${R(h)}:${JSON.stringify(w)}`):[],Q=I("containers",[this.#t.scene]),_t=Array.isArray(Q)?Q.slice(0,64).flatMap(h=>{if(!p(h)||typeof h.key!="string"||!p(h.target))return [];let w=h.target,T=Object.keys(w).filter(C=>Reflect.get(w,C)===Reflect.get(t,"value"));return [`${h.key}/${R(w)}${T.length>0?`:${T.join(",")}`:""}`]}):[],Ge=R(t)==="EventNode"?Reflect.get(t,"callback"):void 0,Mt=typeof Ge=="function"?Function.prototype.toString.call(Ge).replaceAll(/\s+/gu," ").slice(0,320):void 0,E=this.#t.builder.object;throw new Error(`Cannot address ${R(t)}${typeof r=="string"&&r?` "${r}"`:""} used by ${n} for shader key "${this.#t.key}". Node metadata: value=${R(Reflect.get(t,"value"))}, update=${typeof Reflect.get(t,"update")=="function"?Reflect.get(t,"update").name||"anonymous":"none"}, updateType=${String(Reflect.get(t,"updateType"))}.`+(y?` Input metadata: class=${y}, value=${R(Reflect.get(t,"value"))}, access=${String(Reflect.get(t,"access"))}, uniformType=${String(Reflect.get(t,"uniformType"))}.`:"")+` Similar semantic inputs: tsl=[${v.join(", ")}], paths=[${ke.join(", ")}].`+(p(Reflect.get(t,"value"))&&Reflect.get(Reflect.get(t,"value"),"isTexture")===true?` Texture value: ${ft(Reflect.get(t,"value"))}.`:"")+(Z.length>0?` Same-texture paths: [${Z.join(", ")}].`:"")+` Classifier diagnostics: ${this.#o.join("; ")}. Registered containers: [${_t.join(", ")}].`+(Reflect.get(t,"isStorageBufferNode")===true?` Storage metadata: type=${String(Reflect.get(t,"bufferType"))}, count=${String(Reflect.get(t,"bufferCount"))}, value=${R(Reflect.get(t,"value"))}.`:"")+(R(t)==="MaterialReferenceNode"?` Material reference metadata: flag=${String(Reflect.get(t,"isMaterialReferenceNode"))}, property=${String(Reflect.get(t,"property"))}, uniformType=${String(Reflect.get(t,"uniformType"))}.`:"")+(R(t)==="EventNode"?` Event metadata: type=${String(Reflect.get(t,"eventType"))}, object=${R(E)}, objectName=${p(E)?String(E.name??""):""}, instanced=${p(E)&&E.isInstancedMesh===true}, skinned=${p(E)&&E.isSkinnedMesh===true}, morphs=${p(E)&&Array.isArray(E.morphTargetInfluences)?E.morphTargetInfluences.length:0}, callback=${Mt??"none"}.`:""))}};function Be(e){return Array.isArray(e)?e.map(N).filter(t=>t!==void 0):[]}l(Be,"nodeArray");function bn(e,t,n){let r=t.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&"),i=new RegExp(`struct\\s+${r}Struct\\s*\\{([\\s\\S]*?)\\};`,"u"),s=[e.vertexShader,e.fragmentShader,e.computeShader].filter(a=>typeof a=="string"),o;for(let a of s){let d=i.exec(a)?.[1];if(d!==void 0&&(o=[...d.matchAll(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*:/gmu)].map(u=>u[1]).filter(u=>u!==void 0),o.length>0))break}if(!o||o.length===0)return;let c=new Map(n.map(a=>[a.name,a.type]));if(!o.some(a=>!c.has(a)))return o.map(a=>({name:a,type:c.get(a)}))}l(bn,"wgslUniformLayout");var Rn=[{directive:/(?:^|\n)\s*enable\s+subgroups\s*;/u,feature:"subgroups"},{directive:/(?:^|\n)\s*enable\s+subgroups[-_]f16\s*;/u,feature:"subgroups-f16"},{directive:/(?:^|\n)\s*enable\s+f16\s*;/u,feature:"shader-f16"},{directive:/(?:^|\n)\s*enable\s+clip_distances\s*;/u,feature:"clip-distances"},{directive:/(?:^|\n)\s*enable\s+dual_source_blending\s*;/u,feature:"dual-source-blending"}];function kn(e){let t=[];for(let n of Rn)e.some(r=>r!==null&&n.directive.test(r))&&t.push(n.feature);return t}l(kn,"shaderRequirements");function Sn(e,t){let n=new Map,r=new Set,i=[];for(let s of e){let o=t(s.node,`uniform ${s.name??"<generated>"}`),c=JSON.stringify(o),a=n.get(c);a===void 0&&(a=new Map,n.set(c,a));let d=a.get(s.nid);d===void 0&&(d=a.size,a.set(s.nid,d));let u=`${c}\0${d}\0${s.stage}`;r.has(u)||(r.add(u),i.push({address:o,instance:d,type:s.type,stage:s.stage,name:s.name}));}return i}l(Sn,"reduceJournal");function wn(e,t){if(t==="NodeStorageBuffer"||t==="StorageBuffer"){let n=e.access;return typeof n=="string"?{access:n}:{}}if(t.includes("Sampled")){let n=e.store===true,r=e.access;return {store:n,...n&&typeof r=="string"?{access:r}:{}}}return {}}l(wn,"capturedBindingAccess");function Nn(e,t){let n=ze(e.builder,e.kind);if(!n)throw new Error(`Shader key "${e.key}" has no live build target.`);let r=new Ke({...e,target:n},t),i=Be(e.builder.updateNodes),s=Be(e.builder.updateBeforeNodes),o=Be(e.builder.updateAfterNodes);for(let f of [...i,...s,...o])r.noteUpdateNode(f);let c=Sn(e.journal,(f,m)=>r.classify(f,m)),a=typeof e.builder.getAttributesArray=="function"?Reflect.apply(e.builder.getAttributesArray,e.builder,[]):[],d=Array.isArray(a)?a.map((f,m)=>{if(!p(f)||typeof f.name!="string"||typeof f.type!="string")throw new Error(`Shader attribute ${m} is invalid.`);let y=N(f.node);return {name:f.name,type:f.type,node:y?r.classify(y,`attribute ${f.name}`):null}}):[],u=typeof e.builder.getBindings=="function"?Reflect.apply(e.builder.getBindings,e.builder,[]):[],b=Array.isArray(u)?u.map((f,m)=>{if(!p(f)||!Array.isArray(f.bindings))throw new Error(`Shader bind group ${m} is invalid.`);return {name:typeof f.name=="string"?f.name:`group-${m}`,bindings:f.bindings.map((y,k)=>{if(!p(y)||typeof y.name!="string")throw new Error(`Shader binding ${m}/${k} is invalid.`);let S=je(y),v;if(S==="NodeUniformsGroup"){if(!Array.isArray(y.uniforms))throw new Error(`Shader uniform group ${m}/${k} has no member list.`);let ke=y.uniforms.map((M,Z)=>{if(!p(M)||typeof M.name!="string"||typeof M.getType!="function")throw new Error(`Shader uniform ${m}/${k}/${Z} is invalid.`);let Q=Reflect.apply(M.getType,M,[]);if(typeof Q!="string")throw new Error(`Shader uniform ${m}/${k}/${Z} has no stable type.`);return {name:M.name,type:Q}});v=bn(e.builder,y.name,c)??ke;}return {name:y.name,kind:S,...wn(y,S),...v===void 0?{}:{uniforms:v}}})}}):[],j=p(e.builder.observer)?{hasNode:e.builder.observer.hasNode===true,hasAnimation:e.builder.observer.hasAnimation===true}:null,g=l(f=>typeof e.builder[f]=="string"?e.builder[f]:null,"shader");return {key:e.key,vertexShader:g("vertexShader"),fragmentShader:g("fragmentShader"),computeShader:g("computeShader"),declarations:c,attributes:d,bindGroups:b,updateNodes:i.filter(f=>!r.shouldOmitUpdateNode(f)).map(f=>r.classify(f,"updateNodes")),updateBeforeNodes:s.filter(f=>!r.shouldOmitUpdateNode(f)).map(f=>r.classify(f,"updateBeforeNodes")),updateAfterNodes:o.filter(f=>!r.shouldOmitUpdateNode(f)).map(f=>r.classify(f,"updateAfterNodes")),requirements:kn([g("vertexShader"),g("fragmentShader"),g("computeShader")]),observer:j,hardwareClipping:e.builder.hardwareClipping===true}}l(Nn,"entryFromSnapshot");function q(e){return (e??"").replace(/\b(nodeUniform|nodeVar|nodeVarying|nodeAttribute|NodeBuffer_|nodeCode)\d+\b/gu,"$1#").split(`
2
+ `).sort().join(`
3
+ `)}l(q,"canonicalShader");var O=class{static{l(this,"CapturePool");}values=[];#t=new Map;intern(t,n=JSON.stringify(t)){let r=this.#t.get(n);return r===void 0&&(r=this.values.length,this.#t.set(n,r),this.values.push(t)),r}};function An(e){let t=new O,n=new O,r=new O,i=new O,s=new O,o=new O,c=new O,a={};for(let d of Object.keys(e).sort()){let u=e[d];if(u===void 0)continue;let b=l(m=>m===null?null:t.intern(m,m),"moduleAt"),j=u.declarations.map(m=>[n.intern(m.address),m.instance,m.type,m.stage,m.name]),g=u.requirements.length===0?void 0:o.intern(u.requirements),f={vertex:b(u.vertexShader),fragment:b(u.fragmentShader),compute:b(u.computeShader),declarations:j,layout:r.intern(u.bindGroups),attributes:i.intern(u.attributes.map(m=>({name:m.name,type:m.type,node:m.node===null?null:n.intern(m.node)}))),updates:[s.intern(u.updateNodes.map(m=>n.intern(m))),s.intern(u.updateBeforeNodes.map(m=>n.intern(m))),s.intern(u.updateAfterNodes.map(m=>n.intern(m)))],...g===void 0?{}:{requirements:g},observer:u.observer,hardwareClipping:u.hardwareClipping};a[d]=c.intern(f);}return {modules:t.values,nodes:n.values,layouts:r.values,attributePlans:i.values,updatePlans:s.values,requirementPlans:o.values,states:c.values,entries:a}}l(An,"poolCaptureEntries");function Tn(e,t){let n={},r=[],i=new De;for(let s of pe.filter(o=>o.scene===e))try{let o=Nn(s,i),c=Le(o);if(c)throw new Error(`Shader key "${o.key}" captured the automatic input container "${c}". Automatically discovered input containers are capture-only; register a stable application container or retain the value under the material/compute root.`);let a=Ie(o);if(a)throw new Error(`Shader key "${o.key}" captured the transient renderer path "${a}". Renderer contexts must use a semantic recipe, and renderer back-references are never stable replay roots.`);let d=n[o.key];d?(q(d.vertexShader)!==q(o.vertexShader)||q(d.fragmentShader)!==q(o.fragmentShader)||q(d.computeShader)!==q(o.computeShader))&&r.push(`Shader key "${o.key}" produced conflicting structures in one capture.`):n[o.key]=o;}catch(o){r.push(o instanceof Error?o.stack??o.message:String(o));}return {protocolVersion:2,compatibility:Ae,scene:e,..._===void 0?{}:{automatic:{prefix:_}},...An(n),skipped:[...ge],errors:r,stats:{...x},timing:{...J===void 0?{}:{readiness:J},...Y===void 0?{}:{lastBuild:Y},settled:Date.now()},provenance:t}}l(Tn,"buildPayload");async function jn(){let e=globalThis,t=p(e.navigator)?e.navigator:{},n=pe.find(u=>u.scene===K)?.renderer,r=p(n?.backend)?n.backend:{},i=p(r.device)?r.device:{},s=p(i.adapterInfo)?i.adapterInfo:void 0;if(s===void 0&&p(t.gpu)&&typeof t.gpu.requestAdapter=="function"){let u=await Promise.race([Promise.resolve(Reflect.apply(t.gpu.requestAdapter,t.gpu,[])).catch(()=>{}),new Promise(b=>setTimeout(()=>b(void 0),zt))]);p(u)&&(s=p(u.info)?u.info:u);}let o=["description","device","architecture","vendor"].flatMap(u=>{let b=s?.[u];return typeof b=="string"&&b.length>0?[b]:[]}),c=i.features,d=typeof(c!==null&&typeof c=="object"?Reflect.get(c,Symbol.iterator):void 0)=="function"?[...c].filter(u=>typeof u=="string").sort():[];return {userAgent:typeof t.userAgent=="string"?t.userAgent:"unknown browser",adapter:[...new Set(o)].join(" \xB7 ")||"WebGPU adapter",features:d}}l(jn,"captureProvenance");function Ee(e){if(A.captureId===void 0)return;let t=Reflect.get(globalThis,"dispatchEvent"),n=Reflect.get(globalThis,"CustomEvent");if(!(typeof t!="function"||typeof n!="function"))try{let r=Reflect.construct(n,["three-blocks:shader-capture",{detail:{...e,active:!0}}]);Reflect.apply(t,globalThis,[r]);}catch{}}l(Ee,"publishOverlayCaptureState");async function ie(e,t){let n=A.captureId!==void 0,r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",...A.token===void 0?{}:{"X-Three-Blocks-Capture-Token":A.token}},body:JSON.stringify(n?{captureId:A.captureId,payload:t}:t)});if(!r.ok){let i=await r.text().catch(()=>""),s=i;try{let o=JSON.parse(i);p(o)&&typeof o.error=="string"&&(s=o.error);}catch{}throw n&&Ee({stage:"error",scene:K,error:s||`Shader devtools endpoint ${e} returned HTTP ${r.status}.`}),new Error(s||`Shader devtools endpoint ${e} returned HTTP ${r.status}.`)}if(n&&e===oe&&p(t)&&Ee(t),n&&e===$e){let i=await r.json().catch(()=>{}),s=p(i)&&Number.isSafeInteger(i.pipelines)?Number(i.pipelines):0;Ee({stage:"complete",scene:K,pipelines:s});}if(e===$e&&A.sessionKey!==void 0)try{let i=Reflect.get(globalThis,"sessionStorage"),s=p(i)?i.removeItem:void 0;typeof s=="function"&&Reflect.apply(s,i,[A.sessionKey]);}catch{}}l(ie,"postJson");async function _e(){await ie(oe,le(true,"writing")),A.capture&&!se&&(await ie($e,Tn(K,await jn())),se=true,ce++,D&&clearTimeout(D),D=void 0);}l(_e,"reportSettled");function Me(e){console.error("[three-blocks] shader capture report failed",e);}l(Me,"reportSettledFailure");function le(e,t=e?"writing":"building"){return {protocolVersion:1,compatibility:Ae,transform:A.transform,scene:K,settled:e,stage:t,stats:{...x},timing:{...J===void 0?{}:{readiness:J},...Y===void 0?{}:{lastBuild:Y},...e?{settled:Date.now()}:{}},..._===void 0?{}:{automatic:{prefix:_}},skipped:[...ge]}}l(le,"telemetryPayload");function Cn(e,t){let n=e;for(let r of t.split(".")){if(!p(n)&&typeof n!="function")return;n=Reflect.get(n,r);}return n}l(Cn,"readinessGlobalValue");function xn(e,t=A.readiness){if(t.selector!==void 0){let n=Reflect.get(e,"document");if(!p(n))return false;let r=Reflect.get(n,"querySelector");if(typeof r!="function"||Reflect.apply(r,n,[t.selector])===null)return false}if(t.global!==void 0){let n=Cn(e,t.global);return n===true?true:Tt(n)?(n!==ne&&(ne=n,re=false,Promise.resolve(n).then(()=>{ne===n&&(re=true);},r=>{ne===n&&(re=false),console.error(`[three-blocks] shader readiness global ${t.global} rejected`,r);})),re):false}return true}l(xn,"pageLoadingIsComplete");function Et(){if(A.capture&&se)return;Ce||(Ce=true,queueMicrotask(()=>{Ce=false,ie(oe,le(false)).catch(()=>{});})),D&&clearTimeout(D);let e=++ce,t=globalThis,n=t.requestAnimationFrame;if(typeof n=="function"&&A.settleFrames>0){let i=A.settleFrames,s=l(()=>{if(e!==ce)return;if(!xn(t)){Reflect.apply(n,t,[s]);return}let o=Date.now();J??=o,de??=o;let c=Reflect.get(t,"document"),a=Reflect.get(globalThis,Symbol.for("three-blocks.shader-capture.worker-visible.v1")),d=A.visibilityGuard&&(p(c)&&c.hidden===true||a===false),u=Math.max(0,o-de);if(de=o,d){W||(W=true,ie(oe,le(false,"hidden")).catch(()=>{})),Reflect.apply(n,t,[s]);return}if(Oe+=Math.min(u,250),W||(W=true,ie(oe,le(false,"settling")).catch(()=>{})),Oe>=(A.settleTimeoutMs??3e4)){_e().catch(Me);return}if(i--,i<=0){_e().catch(Me);return}Reflect.apply(n,t,[s]);},"frame");Reflect.apply(n,t,[s]);return}let r=Math.max(250,Math.min(3e4,A.settleFrames*(1e3/60)));D=setTimeout(()=>{D=void 0,e===ce&&_e().catch(Me);},r);}l(Et,"scheduleSettledReport");export{Ct as activeShaderCaptureScene,je as capturedBindingKind,Qt as configureThreeBlocksShaderCapture,vt as instrumentThreeBlocksShaderBuilder,xn as pageLoadingIsComplete,sn as prepareThreeBlocksShaderRenderer,Bt as recordThreeBlocksShaderBuild,pt as wrapThreeBlocksCaptureTimedBuild};