@forgeax/engine-runtime 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/__tests__/create-renderer-gpu-pass-timing.unit.test.d.ts +2 -0
- package/dist/__tests__/create-renderer-gpu-pass-timing.unit.test.d.ts.map +1 -0
- package/dist/__tests__/helpers/tilemap-assets.d.ts.map +1 -1
- package/dist/__tests__/lights-preservation.fixup.test.d.ts +2 -0
- package/dist/__tests__/lights-preservation.fixup.test.d.ts.map +1 -0
- package/dist/__tests__/material-texture-dimension-mismatch.unit.test.d.ts +2 -0
- package/dist/__tests__/material-texture-dimension-mismatch.unit.test.d.ts.map +1 -0
- package/dist/__tests__/render-error-exhaustive.test-d.d.ts.map +1 -1
- package/dist/__tests__/texture-dimensions.browser.test.d.ts +2 -0
- package/dist/__tests__/texture-dimensions.browser.test.d.ts.map +1 -0
- package/dist/__tests__/volumetric-fog-record-recovery.integration.test.d.ts +2 -0
- package/dist/__tests__/volumetric-fog-record-recovery.integration.test.d.ts.map +1 -0
- package/dist/createRenderer.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +3 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +30 -30
- package/src/__tests__/active-camera.unit.test.ts +6 -8
- package/src/__tests__/asset-registry.recursive.spec.ts +13 -19
- package/src/__tests__/asset.unit.test.ts +28 -25
- package/src/__tests__/basis-catalog-dispatch.integration.test.ts +10 -9
- package/src/__tests__/clamp-to-last.e2e.browser.test.ts +2 -2
- package/src/__tests__/components.test-d.ts +10 -3
- package/src/__tests__/components.unit.test.ts +13 -7
- package/src/__tests__/compressed-texture-physical-extent.integration.test.ts +12 -10
- package/src/__tests__/create-renderer-assembly.integration.test.ts +24 -0
- package/src/__tests__/create-renderer-gpu-pass-timing.unit.test.ts +32 -0
- package/src/__tests__/createRenderer.browser-no-webgpu.test.ts +66 -0
- package/src/__tests__/dawn/hello-sprite-nineslice-section.dawn.test.ts +11 -4
- package/src/__tests__/dawn/instances-shadow.dawn.test.ts +15 -2
- package/src/__tests__/dawn/material-alpha.dawn.test.ts +2 -3
- package/src/__tests__/dawn/mipmap-srgb-linear.dawn.test.ts +2 -3
- package/src/__tests__/dawn/per-entity-material-texture-isolation.dawn.test.ts +2 -3
- package/src/__tests__/dawn/sprite-nineslice-mesh-bind.dawn.test.ts +2 -3
- package/src/__tests__/dawn/upload-texture.dawn.test.ts +4 -6
- package/src/__tests__/derive-bgl-integration.test.ts +11 -0
- package/src/__tests__/equirect-bc6h.integration.test.ts +6 -4
- package/src/__tests__/errors.unit.test.ts +71 -20
- package/src/__tests__/extract-frames-merge.test.ts +48 -40
- package/src/__tests__/extract-skin-mismatch.unit.test.ts +6 -2
- package/src/__tests__/four-path-compression.integration.test.ts +2 -2
- package/src/__tests__/frame-targets-shadow-regression.unit.test.ts +13 -0
- package/src/__tests__/geometry.unit.test.ts +7 -10
- package/src/__tests__/gpu-resource-cow-survivor.test.ts +2 -3
- package/src/__tests__/helpers/tilemap-assets.ts +3 -4
- package/src/__tests__/light-gpu-byte-neutral.unit.test.ts +6 -3
- package/src/__tests__/light-snapshot.test-d.ts +8 -0
- package/src/__tests__/lights-preservation.fixup.test.ts +127 -0
- package/src/__tests__/lights.unit.test.ts +75 -2214
- package/src/__tests__/loadbyguid-texture-intern.unit.test.ts +3 -4
- package/src/__tests__/loader-name-survival.test.ts +2 -3
- package/src/__tests__/material-texture-dimension-mismatch.unit.test.ts +18 -0
- package/src/__tests__/material-texture-uv-scale.unit.test.ts +10 -2
- package/src/__tests__/mip-gate.unit.test.ts +11 -8
- package/src/__tests__/msaa-sprite-pixel-diff.dawn.test.ts +2 -3
- package/src/__tests__/new-kind-refs-contract.test.ts +2 -3
- package/src/__tests__/pbr-pipeline.unit.test.ts +29 -5
- package/src/__tests__/pipeline.unit.test.ts +66 -221
- package/src/__tests__/point-light-shadow.browser.test.ts +208 -83
- package/src/__tests__/point-light-shadow.unit.test.ts +67 -9
- package/src/__tests__/render-error-exhaustive.test-d.ts +92 -9
- package/src/__tests__/render-system-extract.test.ts +4 -6
- package/src/__tests__/render-system-mega.test.ts +30 -41
- package/src/__tests__/render-system-record-multi-material-textureview.test.ts +8 -7
- package/src/__tests__/render-system-record-per-submesh-transparency.test.ts +6 -4
- package/src/__tests__/render-system-skin-bg.unit.test.ts +14 -9
- package/src/__tests__/renderer-recover.unit.test.ts +8 -0
- package/src/__tests__/renderer-surface.unit.test.ts +229 -3
- package/src/__tests__/shadow-csm-atlas.test.ts +41 -0
- package/src/__tests__/shadow-csm-component.test.ts +31 -24
- package/src/__tests__/shadow-csm-extract.test.ts +156 -47
- package/src/__tests__/shadow-csm-runtime-vary.dawn.test.ts +72 -0
- package/src/__tests__/shadow-csm-shader.dawn.test.ts +19 -0
- package/src/__tests__/shadow-csm-ubo.test.ts +41 -45
- package/src/__tests__/shadow-csm-viewport.browser.test.ts +29 -0
- package/src/__tests__/shadow-fields-observable.dawn.test.ts +140 -58
- package/src/__tests__/skinned-shadow-mixed.dawn.test.ts +6 -2
- package/src/__tests__/skylight-lazy-projection.test.ts +8 -5
- package/src/__tests__/sprite-cullmode-flip.dawn.test.ts +4 -6
- package/src/__tests__/sprite-lit-bgl-byte-identical.test.ts +4 -2
- package/src/__tests__/ssao-bgl.test.ts +10 -16
- package/src/__tests__/ssao-passes.test.ts +19 -2
- package/src/__tests__/systems.unit.test.ts +59 -33
- package/src/__tests__/texture-dimensions.browser.test.ts +127 -0
- package/src/__tests__/transcode-fallback.unit.test.ts +5 -1
- package/src/__tests__/view-ubo-layout.browser.test.ts +20 -10
- package/src/__tests__/volumetric-fog-record-recovery.integration.test.ts +180 -0
- package/src/createRenderer.ts +4 -0
- package/src/index.ts +1 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-renderer-gpu-pass-timing.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/create-renderer-gpu-pass-timing.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tilemap-assets.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/tilemap-assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C,wBAAgB,eAAe,CAAC,IAAI,SAAI,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"tilemap-assets.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/tilemap-assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C,wBAAgB,eAAe,CAAC,IAAI,SAAI,GAAG,YAAY,CAStD;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,YAAY,EACrB,KAAK,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAM,GAC1C,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAAG,SAAS,CAQrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lights-preservation.fixup.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/lights-preservation.fixup.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"material-texture-dimension-mismatch.unit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/material-texture-dimension-mismatch.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render-error-exhaustive.test-d.d.ts","sourceRoot":"","sources":["../../src/__tests__/render-error-exhaustive.test-d.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE3E,iBAAS,4BAA4B,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"render-error-exhaustive.test-d.d.ts","sourceRoot":"","sources":["../../src/__tests__/render-error-exhaustive.test-d.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE3E,iBAAS,4BAA4B,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAmInE;AAED,iBAAS,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAoRjD;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,mFAAmF;IACnF,MAAM,EAAE,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC;IACxD,2EAA2E;IAC3E,OAAO,EAAE,OAAO,iBAAiB,CAAC;CACnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"texture-dimensions.browser.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/texture-dimensions.browser.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"volumetric-fog-record-recovery.integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/volumetric-fog-record-recovery.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createRenderer.d.ts","sourceRoot":"","sources":["../src/createRenderer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAG9D;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,OAAO,CAAC,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,sBAAsB,GAAG,WAAW,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"createRenderer.d.ts","sourceRoot":"","sources":["../src/createRenderer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAC;AACzF,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAG9D;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,iBAAiB,GAAG,eAAe,EAC3C,OAAO,CAAC,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,sBAAsB,GAAG,WAAW,CAAC,CAAC,CA+BjE"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAgBlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAW9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,qBAAqB,CAAC;AAC7B;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,uBAAuB,CAAC;AAY/B;;;;;;;;;GASG;AACH;;;;;;;;;GASG;AAKH,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAQlE;;;;;;GAMG;AACH;;;;;;;;;;;;;;GAcG;AACH;GACG;AAQH;;;;;;;;;;;;;;;;GAgBG;AAGH,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG/D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAiB5E;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAiB5C,OAAO,EACL,iBAAiB,EACjB,KAAK,oBAAoB,EACzB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,gCAAgC,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAgBlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAW9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,2BAA2B,EAChC,QAAQ,EACR,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,GAC5B,MAAM,qBAAqB,CAAC;AAC7B;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,MAAM,EACX,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,uBAAuB,CAAC;AAY/B;;;;;;;;;GASG;AACH;;;;;;;;;GASG;AAKH,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAQlE;;;;;;GAMG;AACH;;;;;;;;;;;;;;GAcG;AACH;GACG;AAQH;;;;;;;;;;;;;;;;GAgBG;AAGH,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG/D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAiB5E;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAiB5C,OAAO,EACL,iBAAiB,EACjB,KAAK,oBAAoB,EACzB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AA+B/B;;;;;;;;;;GAUG"}
|
package/dist/index.mjs
CHANGED
|
@@ -169,8 +169,10 @@ async function createRenderer(canvas, options, bundler) {
|
|
|
169
169
|
...options.rhi === void 0 ? {} : { rhi: options.rhi },
|
|
170
170
|
...options.features === void 0 ? {} : { features: options.features },
|
|
171
171
|
...options.profiler === void 0 ? {} : { profiler: options.profiler },
|
|
172
|
+
...options.captureGpuTimings === void 0 ? {} : { captureGpuTimings: options.captureGpuTimings },
|
|
172
173
|
...options.rhiInstrumentation === void 0 ? {} : { rhiInstrumentation: options.rhiInstrumentation },
|
|
173
|
-
...options.standardProfile === void 0 ? {} : { standardProfile: options.standardProfile }
|
|
174
|
+
...options.standardProfile === void 0 ? {} : { standardProfile: options.standardProfile },
|
|
175
|
+
...options.gpuPassTiming === void 0 ? {} : { gpuPassTiming: options.gpuPassTiming }
|
|
174
176
|
};
|
|
175
177
|
try {
|
|
176
178
|
const constructed = await constructRuntimeRendererHost(canvas, rendererOptions, bundler);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../audio/src/assets/audio-decoder.ts","../../audio/src/components.ts","../src/asset-contributions.ts","../src/backend-selection.ts","../src/renderer-host.ts","../src/createRenderer.ts","../src/dev-import-transport.ts","../src/systems/sprite-animation-tick.ts","../src/scene-utils/mount-override-fold.ts","../src/collect-scene-asset.ts"],"names":["ok","err","EngineEnvironmentError","resolveAssetHandle","componentSchema","componentDefinition"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAQO,IAAM,iBAAA,GAAuE;EAClF,IAAA,EAAM,EAAE,MAAM,OAAA,EAAA;EACd,QAAA,EAAU,cAAA;EACV,OAAA,EAAS;AACP,IAAA,MAAM,MAAA,CAAO,EAAE,QAAA,EAAU,SAAA,EAAA,EAAa;AACpC,MAAA,MAAM,UAAU,QAAA,CAAS,OAAA;AACzB,MAAA,IAAI,OAAA,KAAY,IAAA,IAAQ,OAAO,OAAA,KAAY,QAAA,EAAU;AACnD,QAAA,MAAM,MAAA,GAAS,OAAA;AACf,QAAA,IAAI,KAAA,GACF,MAAA,CAAO,KAAA,YAAiB,UAAA,GACpB,OAAO,KAAA,GACP,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,GACxB,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,KAAiB,CAAA,GACxC,MAAA;AACR,QAAA,MAAM,IAAA,GAAO,QAAA,CAAS,SAAA,CAAU,IAAA,IAAQ,SAAS,SAAA,CAAU,MAAA;AAC3D,QAAA,IAAI,SAAS,MAAA,EAAW;AACtB,UAAA,MAAM,SAAA,GAAY,MAAM,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAC3C,UAAA,IAAI,CAAC,SAAA,CAAU,EAAA,EAAI,OAAO,SAAA;AAC1B,UAAA,KAAA,GAAQ,SAAA,CAAU,KAAA;AACpB,QAAA;AACA,QAAA,IACE,OAAO,IAAA,KAAS,OAAA,IAChB,OAAO,MAAA,CAAO,cAAc,QAAA,IAC5B,MAAA,CAAO,SAAA,CAAU,UAAA,CAAW,QAAQ,CAAA,IACpC,KAAA,KAAU,MAAA,IACV,KAAA,CAAM,aAAa,CAAA,EACnB;AACA,UAAA,OAAO,EAAA,CAAG;YACR,IAAA,EAAM,OAAA;YACN,SAAA,EACE,OAAO,MAAA,CAAO,SAAA,KAAc,QAAA,IAAY,MAAA,CAAO,UAAU,MAAA,GAAS,CAAA,GAC9D,MAAA,CAAO,SAAA,GACP,QAAA,CAAS,IAAA;AACf,YAAA,SAAA,EAAW,MAAA,CAAO,SAAA;AAClB,YAAA;WACD,CAAA;AACH,QAAA;AACF,MAAA;AACA,MAAA,OAAO,GAAA,CAAI;QACT,IAAA,EAAM,uBAAA;QACN,QAAA,EAAU,kEAAA;QACV,IAAA,EAAM,6DAAA;AACN,QAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,CAAS,IAAA,EAAM,QAAQ,+BAAA;OACxC,CAAA;AACH,IAAA;AAAA;AAEJ,CAAA;ACzC2B,gBAAgB,aAAA,EAAe;EACxD,IAAA,EAAM,EAAE,MAAM,wBAAA,EAAA;AACd,EAAA,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAA;AAClC,EAAA,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAA;AAC/B,EAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,CAAA,EAAA;AAChC,EAAA,YAAA,EAAc,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,CAAA,EAAA;AACtC,EAAA,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,KAAA;AAClC,CAAC;AAE4B,eAAA,CAAgB,eAAA,EAAiB,EAAE;ACChE,IAAM,qCAAA,GAAwC;AAAA,EAC5C,qBAAA;AAAA,EACA,oBAAA;AAAA,EACA,sBAAA;AAAA,EACA,mBAAA;AAAA,EACA,oBAAA;AAAA,EACA,mBAAA;AAAA,EACA,gBAAA;AAAA,EACA,0BAAA;AAAA,EACA,mBAAA;AAAA,EACA,iBAAA;AAAA,EACA,oBAAA;AAAA,EACA,gBAAA;AAAA,EACA,yBAAA;AAAA,EACA,0BAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA;AAKO,IAAM,mCAAmC,MAAA,CAAO,MAAA;AAAA,EACrD;AACF;AC1CO,SAAS,WAAA,CACd,KACA,eAAA,EACgB;AAChB,EAAA,MAAM,MAAM,GAAA,CAAI,GAAA;AAChB,EAAA,MAAM,qBAAqB,GAAA,CAAI,kBAAA;AAG/B,EAAA,MAAM,8BAA8B,GAAA,CAAI,2BAAA;AAGxC,EAAA,MAAM,gCAAgC,GAAA,CAAI,6BAAA;AAG1C,EAAA,MAAM,oBAAoB,GAAA,CAAI,sBAAA;AAG9B,EAAA,MAAM,yBAAyB,GAAA,CAAI,eAAA;AAGnC,EAAA,MAAM,IAAA,GAAuB;AAAA,IAC3B,GAAA;AAAA,IACA,GAAI,kBAAA,KAAuB,MAAA,GAAY,EAAC,GAAI,EAAE,kBAAA,EAAmB;AAAA,IACjE,GAAI,2BAAA,KAAgC,MAAA,GAAY,EAAC,GAAI,EAAE,2BAAA,EAA4B;AAAA,IACnF,GAAI,6BAAA,KAAkC,MAAA,GAAY,EAAC,GAAI,EAAE,6BAAA,EAA8B;AAAA,IACvF,GAAI,iBAAA,KAAsB,MAAA,GAAY,EAAC,GAAI,EAAE,wBAAwB,iBAAA;AAAkB,GACzF;AACA,EAAA,MAAM,0BAA0B,eAAA,IAAmB,sBAAA;AACnD,EAAA,OAAO,4BAA4B,MAAA,GAC/B,IAAA,GACA,EAAE,GAAG,IAAA,EAAM,iBAAiB,uBAAA,EAAwB;AAC1D;AAGA,eAAsB,eAAA,CACpB,OAAA,EACA,UAAA,GAAa,KAAA,EAIb;AACA,EAAA,MAAM,WAAW,OAAA,EAAS,GAAA;AAC1B,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,QAAA,KAAa,IAAA,EAAM;AAC/C,IAAA,OAAOA,IAAAA,CAAG,WAAA,CAAY,EAAE,GAAA,EAAK,QAAA,EAAU,GAAI,QAAA,EAAoB,EAAG,OAAA,EAAS,kBAAkB,CAAC,CAAA;AAAA,EAChG;AACA,EAAA,MAAM,GAAA,GACJ,OAAO,UAAA,KAAe,WAAA,GAClB,SACC,UAAA,CAAiD,SAAA;AACxD,EAAA,IAAI,CAAC,UAAA,IAAc,GAAA,EAAK,QAAQ,MAAA,IAAa,GAAA,CAAI,QAAQ,IAAA,EAAM;AAC7D,IAAA,OAAOA,IAAAA;AAAA,MACL,WAAA,CAAY,SAAA,EAAiD,OAAA,EAAS,kBAAkB;AAAA,KAC1F;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAO,MAAM,OAAO,0BAA0B,CAAA;AACpD,IAAA,MAAO,IAAI,WAAA,EAAuC;AAClD,IAAA,OAAOA,IAAAA,CAAG,WAAA,CAAY,GAAA,EAAK,OAAA,EAAS,kBAAkB,CAAC,CAAA;AAAA,EACzD,SAAS,KAAA,EAAO;AACd,IAAA,OAAOC,KAAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,mBAAA;AAAA,QACN,QAAA,EAAU,mCAAA;AAAA,QACV,IAAA,EAAM,CAAA,6BAAA,EAAgC,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,OACpD;AAAA,KACH;AAAA,EACF;AACF;;;ACvDA,IAAM,oBAAA,uBAA2B,GAAA,CAAI;AAAA,EACnC,qBAAA;AAAA,EACA,uBAAA;AAAA,EACA,qBAAA;AAAA,EACA,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,kBAAkB,KAAA,EAAyB;AAClD,EAAA,IAAI,EAAE,KAAA,YAAiBC,sBAAAA,CAAAA,EAAyB,OAAO,KAAA;AACvD,EAAA,MAAM,WAAA,GAAc,MAAM,MAAA,CAAO,WAAA;AACjC,EAAA,IAAI,WAAA,KAAgB,MAAA,IAAa,OAAO,WAAA,KAAgB,UAAU,OAAO,KAAA;AACzE,EAAA,IAAI,EAAE,MAAA,IAAU,WAAA,CAAA,EAAc,OAAO,KAAA;AACrC,EAAA,MAAM,OAAO,WAAA,CAAY,IAAA;AACzB,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,IAAY,oBAAA,CAAqB,IAAI,IAAI,CAAA;AAClE;AAGA,eAAsB,4BAAA,CACpB,MAAA,EACA,OAAA,EACA,OAAA,EACmF;AACnF,EAAA,MAAM,KAAA,GAAQ,MAAM,eAAA,CAAgB,OAAO,CAAA;AAC3C,EAAA,IAAI,CAAC,KAAA,CAAM,EAAA,EAAI,MAAM,KAAA,CAAM,KAAA;AAC3B,EAAA,MAAM,cAAc,MAAM,qBAAA,CAAsB,QAAQ,OAAA,EAAS,OAAA,EAAS,MAAM,KAAK,CAAA;AACrF,EAAA,IACE,WAAA,CAAY,EAAA,IACZ,OAAA,EAAS,GAAA,KAAQ,MAAA,IACjB,OAAO,UAAA,KAAe,WAAA,IACtB,CAAC,iBAAA,CAAkB,WAAA,CAAY,KAAK,CAAA,EACpC;AACA,IAAA,OAAO,WAAA;AAAA,EACT;AACA,EAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,OAAA,EAAS,IAAI,CAAA;AACpD,EAAA,IAAI,CAAC,QAAA,CAAS,EAAA,EAAI,OAAO,WAAA;AACzB,EAAA,OAAO,qBAAA,CAAsB,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,SAAS,KAAK,CAAA;AACvE;;;ACvCA,eAAsB,cAAA,CACpB,MAAA,EACA,OAAA,EACA,OAAA,EACiE;AACjE,EAAA,IAAI,YAAY,MAAA,IAAa,KAAA,IAAS,OAAA,IAAW,OAAA,CAAQ,QAAQ,MAAA,EAAW;AAC1E,IAAA,OAAOD,GAAAA,CAAI,IAAI,sBAAA,CAAuB,6BAA6B,CAAC,CAAA;AAAA,EACtE;AACA,EAAA,MAAM,eAAA,GACJ,OAAA,KAAY,MAAA,GACR,MAAA,GACA;AAAA,IACE,GAAI,QAAQ,GAAA,KAAQ,MAAA,GAAY,EAAC,GAAI,EAAE,GAAA,EAAK,OAAA,CAAQ,GAAA,EAAI;AAAA,IACxD,GAAI,QAAQ,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAS;AAAA,IACvE,GAAI,QAAQ,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAS;AAAA,IACvE,GAAI,QAAQ,kBAAA,KAAuB,MAAA,GAC/B,EAAC,GACD,EAAE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,EAAmB;AAAA,IACrD,GAAI,QAAQ,eAAA,KAAoB,MAAA,GAC5B,EAAC,GACD,EAAE,eAAA,EAAiB,OAAA,CAAQ,eAAA;AAAgB,GACjD;AACN,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,MAAM,4BAAA,CAA6B,MAAA,EAAQ,iBAAiB,OAAO,CAAA;AACvF,IAAA,IAAI,CAAC,WAAA,CAAY,EAAA,EAAI,OAAOA,GAAAA,CAAI,YAAY,KAAK,CAAA;AACjD,IAAA,OAAOD,EAAAA,CAAG,WAAA,CAAY,KAAA,CAAM,QAAQ,CAAA;AAAA,EACtC,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,KAAA,YAAiB,sBAAA,EAAwB,OAAOC,GAAAA,CAAI,KAAK,CAAA;AAC7D,IAAA,MAAM,MAAA,GAAS,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACvE,IAAA,OAAOA,GAAAA,CAAI,IAAI,sBAAA,CAAuB,8BAAA,EAAgC,EAAE,WAAA,EAAa,MAAA,EAAQ,CAAC,CAAA;AAAA,EAChG;AACF;;;ACTO,SAAS,yBAAyB,OAAA,EAAsD;AAC7F,EAAA,OAAO;AAAA,IACL,MAAM,SAAA,CACJ,IAAA,EACA,KAAA,EAGA;AACA,MAAA,MAAM,MAAA,GAAS,OAAA;AACf,MAAA,IACE,WAAW,MAAA,IACX,MAAA,CAAO,MAAA,KAAW,OAAA,IAClB,UAAU,MAAA,IACV,KAAA,CAAM,MAAA,KAAW,OAAA,IACjB,MAAM,OAAA,KAAY,MAAA,CAAO,WACzB,KAAA,CAAM,UAAA,KAAe,OAAO,UAAA,EAC5B;AACA,QAAA,OAAO,EAAE,IAAI,KAAA,EAAM;AAAA,MACrB;AACA,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,aAAA,CAAc,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACpD,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA,EAAI,EAAE,MAAA,EAAQ,QAAQ,CAAA;AACtF,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAMhB,UAAA,IAAI;AACF,YAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAKlC,YAAA,OAAA,CAAQ,IAAA;AAAA,cACN,+BAA+B,IAAI,CAAA,OAAA,EAAU,SAAS,MAAM,CAAA,GAAA,EACvD,KAAK,IAAA,IAAQ,eAAe,MAAM,IAAA,CAAK,MAAA,IAAU,EAAE,CAAA,CAAA,IACrD,IAAA,CAAK,OAAO,CAAA,SAAA,EAAY,IAAA,CAAK,IAAI,CAAA,CAAA,GAAK,EAAA;AAAA,aAC3C;AAAA,UACF,CAAA,CAAA,MAAQ;AAAA,UAER;AACA,UAAA,OAAO,EAAE,IAAI,KAAA,EAAM;AAAA,QACrB;AACA,QAAA,IAAI;AACF,UAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,UAAA,IAAI,KAAA,CAAM,QAAQ,IAAI,CAAA,SAAU,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,IAAA,EAAkC;AAAA,QACzF,CAAA,CAAA,MAAQ;AAAA,QAGR;AACA,QAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,MACpB,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,EAAE,IAAI,KAAA,EAAM;AAAA,MACrB;AAAA,IACF;AAAA,GACF;AACF;ACiBO,SAAS,0BAA0B,KAAA,EAAyD;AACjG,EAAA,MAAM,EAAA,GAAK,KAAA,CAAM,WAAA,CAAY,IAAI,CAAA,CAAE,KAAA;AAWnC,EAAA,MAAM,QAAA,GAAW,oBAAoB,KAAK,CAAA;AAE1C,EAAA,IAAI,UAAA,GAAiD,IAAA;AACrD,EAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,UAAA,GAAa,UAAA,CAAW,KAAA,EAAO,MAAA,EAAQ,EAAE,CAAA;AAC/C,IAAA,IAAI,UAAA,KAAe,IAAA,IAAQ,UAAA,KAAe,IAAA,EAAM;AAC9C,MAAA,UAAA,GAAa,UAAA;AAAA,IACf;AAAA,EACF;AAEA,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAOA,IAAI,UAAU,CAAA;AAAA,EACvB;AACA,EAAA,OAAOD,GAAG,MAAS,CAAA;AACrB;AAOA,SAAS,oBAAoB,KAAA,EAA8B;AACzD,EAAA,MAAM,WAAA,GAAc,MAAM,KAAA,CAAM,EAAE,MAAM,CAAC,eAAe,GAAG,CAAA;AAC3D,EAAA,IAAI,CAAC,WAAA,CAAY,EAAA,EAAI,OAAO,EAAC;AAC7B,EAAA,MAAM,WAA2B,EAAC;AAClC,EAAA,KAAA,MAAW,OAAO,WAAA,CAAY,KAAA,EAAO,QAAA,CAAS,IAAA,CAAK,IAAI,MAAM,CAAA;AAC7D,EAAA,OAAO,QAAA;AACT;AAUA,SAAS,UAAA,CACP,KAAA,EACA,MAAA,EACA,EAAA,EACoC;AACpC,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,eAAe,CAAA;AACjD,EAAA,IAAI,CAAC,QAAQ,EAAA,EAAI;AAKf,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAO,OAAA,CAAQ,KAAA;AACrB,EAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AACxB,EAAA,MAAM,gBAAgB,IAAA,CAAK,aAAA;AAC3B,EAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AAIrB,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,UAAA,GAAa,CAAA,EAAG;AACrC,IAAA,OAAO,IAAI,2BAAA,CAA4B;AAAA,MACrC,KAAA,EAAO,gBAAA;AAAA,MACP,eAAe,OAAA,CAAQ,MAAA;AAAA,MACvB;AAAA,KACD,CAAA;AAAA,EACH;AAIA,EAAA,IAAI,EAAE,gBAAgB,CAAA,CAAA,EAAI;AACxB,IAAA,OAAO,IAAI,2BAAA,CAA4B;AAAA,MACrC,KAAA,EAAO,gBAAA;AAAA,MACP;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,QAAA,GAAW,YAAA;AAAA,IACf,IAAA,CAAK,YAAA;AAAA,IACL,KAAK,OAAA,GAAU,EAAA;AAAA,IACf,aAAA;AAAA,IACA,UAAA;AAAA,IACA,IAAA,CAAK;AAAA,GACP;AAKA,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,eAAA,EAAiB;AAAA,IACnD,cAAc,QAAA,CAAS,YAAA;AAAA,IACvB,SAAS,QAAA,CAAS;AAAA,GACnB,CAAA;AACD,EAAA,IAAI,CAAC,SAAA,CAAU,EAAA,EAAI,OAAO,IAAA;AAQ1B,EAAA,MAAM,UAAA,GAAa,SAAS,YAAA,GAAe,CAAA;AAC3C,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa;AAAA,IAC9B,OAAA,CAAQ,UAAU,CAAA,IAAK,CAAA;AAAA,IACvB,OAAA,CAAQ,UAAA,GAAa,CAAC,CAAA,IAAK,CAAA;AAAA,IAC3B,OAAA,CAAQ,UAAA,GAAa,CAAC,CAAA,IAAK,CAAA;AAAA,IAC3B,OAAA,CAAQ,UAAA,GAAa,CAAC,CAAA,IAAK;AAAA,GAC5B,CAAA;AACD,EAAA,aAAA,CAAc,KAAA,EAAO,QAAQ,MAAM,CAAA;AACnC,EAAA,OAAO,IAAA;AACT;AAUA,SAAS,YAAA,CACP,cAAA,EACA,SAAA,EACA,aAAA,EACA,YACA,eAAA,EAC2C;AAC3C,EAAA,IAAI,YAAA,GAAe,cAAA;AACnB,EAAA,IAAI,OAAA,GAAU,SAAA;AACd,EAAA,MAAM,QAAA,GAAW,0BAA0B,eAAe,CAAA;AAC1D,EAAA,OAAO,WAAW,aAAA,EAAe;AAC/B,IAAA,OAAA,IAAW,aAAA;AACX,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,MAAA,EAAQ;AACX,QAAA,YAAA,GAAA,CAAgB,eAAe,CAAA,IAAK,UAAA;AACpC,QAAA;AAAA,MACF;AAAA,MACA,KAAK,OAAA,EAAS;AAKZ,QAAA,IAAI,YAAA,GAAe,aAAa,CAAA,EAAG;AACjC,UAAA,YAAA,IAAgB,CAAA;AAAA,QAClB;AACA,QAAA;AAAA,MACF;AAAA;AACF,EACF;AACA,EAAA,OAAO,EAAE,cAAc,OAAA,EAAQ;AACjC;AAsBA,SAAS,aAAA,CAAc,KAAA,EAAc,MAAA,EAAsB,MAAA,EAA4B;AACrF,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,YAAA,CAAa,MAAA,EAAQ;AAAA,IACvC,SAAA,EAAW,oBAAA;AAAA,IACX,IAAA,EAAM,EAAE,MAAA;AAAO,GAChB,CAAA;AACD,EAAA,IAAI,CAAC,KAAA,CAAM,EAAA,IAAM,KAAA,CAAM,KAAA,CAAM,SAAS,2BAAA,EAA6B;AACjE,IAAA,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,oBAAA,EAAsB,EAAE,QAAQ,CAAA;AAAA,EACpD;AACF;ACvOA,SAAS,sBAAA,GAAsC;AAC7C,EAAA,2BAAW,GAAA,CAAY,CAAC,QAAA,EAAU,SAAA,EAAW,UAAU,CAAC,CAAA;AAC1D;AAIA,SAAS,UAAU,KAAA,EAAyB;AAC1C,EAAA,IACE,MAAM,OAAA,CAAQ,KAAK,CAAA,IACnB,KAAA,YAAiB,eACjB,KAAA,YAAiB,YAAA,IACjB,KAAA,YAAiB,UAAA,IACjB,iBAAiB,YAAA,IACjB,KAAA,YAAiB,cACjB,KAAA,YAAiB,UAAA,IACjB,iBAAiB,WAAA,EACjB;AACA,IAAA,OAAO,KAAA,CAAM,KAAK,KAA2B,CAAA;AAAA,EAC/C;AACA,EAAA,OAAO,KAAA;AACT;AAIA,SAAS,WAAA,CAAY,GAAY,CAAA,EAAqB;AACpD,EAAA,OAAO,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,CAAC,CAAC,MAAM,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,CAAC,CAAC,CAAA;AACrE;AAKA,SAAS,cAAA,CACP,MACA,SAAA,EACyB;AACzB,EAAA,MAAM,MAAA,GAAS,qBAAA,CAAsB,IAAA,EAAM,SAAA,IAAa,EAAE,CAAA;AAC1D,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,IAAI,CAAA,CAAE,MAAA;AACzC,EAAA,KAAA,MAAW,aAAa,MAAA,CAAO,IAAA,CAAK,eAAA,CAAgB,IAAI,CAAC,CAAA,EAAG;AAC1D,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG,SAAA,EAAW;AAClC,IAAA,GAAA,CAAI,SAAS,CAAA,GAAI,MAAA,CAAO,SAAS,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,UAAA,CACP,KAAA,EACA,MAAA,EACA,IAAA,EACqC;AACrC,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAClC,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,MAAA;AACpB,EAAA,MAAM,MAAM,GAAA,CAAI,KAAA;AAChB,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,IAAI,CAAA,CAAE,MAAA;AACzC,EAAA,MAAM,MAAA,GAAS,gBAAgB,IAAI,CAAA;AACnC,EAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG;AAC3C,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG,SAAA,EAAW;AAClC,IAAA,MAAM,SAAA,GAAY,OAAO,SAAS,CAAA;AAClC,IAAA,IAAI,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,eAAA,EAAiB;AAC7D,IAAA,GAAA,CAAI,SAAS,CAAA,GAAI,SAAA,CAAU,GAAA,CAAI,SAAS,CAAC,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,kBAAA,CAAmB,OAAc,KAAA,EAAgD;AAC/F,EAAA,MAAM,SAAA,GAAY,kBAAA;AAAA,IAChB,KAAA;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AACA,EAAA,IAAI,CAAC,SAAA,CAAU,EAAA,EAAI,OAAO,EAAC;AAC3B,EAAA,MAAM,SAAS,SAAA,CAAU,KAAA;AAGzB,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAyB;AACjD,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,QAAA,EAAU;AAClC,IAAA,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,OAAA,EAA8B,IAAI,CAAA;AAAA,EACzD;AAEA,EAAA,MAAM,WAAW,sBAAA,EAAuB;AACxC,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,UAAA,CAAW,OAAA,EAAQ;AAC5C,EAAA,MAAM,YAA6B,EAAC;AAIpC,EAAA,MAAM,UAAyC,EAAC;AAChD,EAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,GAAG,CAAA,IAAK,MAAM,eAAA,EAAiB;AACjD,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,EAAQ,GAAwB,CAAC,CAAA;AAAA,EACjD;AACA,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AAElC,EAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,GAAG,CAAA,IAAK,OAAA,EAAS;AACnC,IAAA,MAAM,UAAA,GAAa,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA;AACtC,IAAA,MAAM,WAAA,GAAe,UAAA,EAAY,UAAA,IAAc,EAAC;AAEhD,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,SAAS,CAAA,IAAK,UAAA,EAAY;AAC9C,MAAA,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC5B,MAAA,IAAI,mBAAA,CAAoB,SAAS,CAAA,CAAE,MAAA,CAAO,SAAA,EAAW;AACrD,MAAA,MAAM,IAAA,GAAO,SAAA;AACb,MAAA,IAAI,OAAO,IAAA,CAAK,eAAA,CAAgB,IAAI,CAAC,CAAA,CAAE,WAAW,CAAA,EAAG;AAErD,MAAA,MAAM,IAAA,GAAO,UAAA,CAAW,KAAA,EAAO,MAAA,EAAQ,IAAI,CAAA;AAC3C,MAAA,IAAI,SAAS,MAAA,EAAW;AAExB,MAAA,MAAM,SAAA,GAAY,YAAY,QAAQ,CAAA;AACtC,MAAA,IAAI,cAAc,MAAA,EAAW;AAG3B,QAAA,SAAA,CAAU,IAAA,CAAK;AAAA,UACb,OAAA,EAAS,GAAA;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACR,CAAA;AACD,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,QAAA,GAAW,cAAA,CAAe,IAAA,EAAM,SAAS,CAAA;AAC/C,MAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG;AACzC,QAAA,IAAI,CAAC,YAAY,IAAA,CAAK,SAAS,GAAG,QAAA,CAAS,SAAS,CAAC,CAAA,EAAG;AACtD,UAAA,SAAA,CAAU,IAAA,CAAK;AAAA,YACb,OAAA,EAAS,GAAA;AAAA,YACT,IAAA,EAAM,QAAA;AAAA,YACN,KAAA,EAAO,SAAA;AAAA,YACP,KAAA,EAAO,KAAK,SAAS;AAAA,WACtB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,SAAA;AACT;;;AC9HA,SAAS,aAAa,KAAA,EAA6C;AAKjE,EAAA,OAAO,KAAA,CAAM,QAAQ,KAAK,CAAA,IAAM,YAAY,MAAA,CAAO,KAAK,CAAA,IAAK,EAAE,KAAA,YAAiB,QAAA,CAAA;AAClF;AACA,SAAS,gBAAgB,KAAA,EAAsC;AAC7D,EAAA,OAAO,KAAA,CAAM,KAAK,KAAK,CAAA;AACzB;AAUA,SAAS,oBAAoB,SAAA,EAA6D;AACxF,EAAA,IAAI,SAAA,KAAc,QAAW,OAAO,MAAA;AACpC,EAAA,IAAI,SAAA,CAAU,WAAW,SAAS,CAAA,SAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAK;AAC3E,EAAA,IAAI,SAAA,CAAU,WAAW,eAAe,CAAA,SAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,KAAA,EAAM;AAClF,EAAA,OAAO,MAAA;AACT;AAWA,SAAS,aAAA,CACP,KAAA,EACA,QAAA,EACA,MAAA,EACA,KAAA,EACkE;AAClE,EAAA,IAAI,MAAA,KAAW,CAAA,EAAG,OAAOA,IAAAA,CAAG,MAAS,CAAA;AACrC,EAAA,MAAM,WAAA,GAAc,gBAAgB,MAA6C,CAAA;AACjF,EAAA,IAAI,WAAA,KAAgB,MAAA,EAAW,OAAOA,IAAAA,CAAG,WAAW,CAAA;AACpD,EAAA,MAAM,QAAA,GAAWG,kBAAAA,CAAmB,KAAA,EAAO,MAA6C,CAAA;AACxF,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI,OAAOF,MAAI,IAAI,oCAAA,CAAqC,KAAA,EAAO,MAAM,CAAC,CAAA;AACpF,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,MAAA,CAAO,QAAA,CAAS,KAAc,CAAA;AACpD,EAAA,IAAI,IAAA,KAAS,QAAW,OAAOA,KAAAA,CAAI,IAAI,oCAAA,CAAqC,KAAA,EAAO,MAAM,CAAC,CAAA;AAC1F,EAAA,OAAOD,KAAG,IAAI,CAAA;AAChB;AAOA,SAAS,0BAAA,CACP,KAAA,EACA,QAAA,EACA,cAAA,EACA,OACA,KAAA,EACuD;AACvD,EAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAOA,KAAG,KAAK,CAAA;AAC9C,IAAA,OAAO,aAAA,CAAc,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,KAAK,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAOA,KAAG,KAAK,CAAA;AAC1C,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAiC;AAClD,IAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,MAAA,MAAA,CAAO,KAAK,IAAc,CAAA;AAC1B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAA,GAAI,aAAA,CAAc,KAAA,EAAO,QAAA,EAAU,MAAM,KAAK,CAAA;AACpD,IAAA,IAAI,CAAC,CAAA,CAAE,EAAA,EAAI,OAAO,CAAA;AAClB,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,KAAA,IAAS,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAOA,KAAG,MAAM,CAAA;AAClB;AAQA,SAAS,8BAAA,CACP,KAAA,EACA,QAAA,EACA,EAAA,EACuD;AACvD,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,GAAG,IAAI,CAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,IAAA,KAAS,MAAA,GAAY,MAAA,GAAaI,gBAAgB,IAAI,CAAA;AACrE,EAAA,IAAI,EAAA,CAAG,UAAU,MAAA,EAAW;AAC1B,IAAA,MAAM,iBAAiB,MAAA,GAAS,mBAAA,CAAoB,OAAO,EAAA,CAAG,KAAK,CAAC,CAAA,GAAI,MAAA;AACxE,IAAA,IAAI,CAAC,kBAAkB,cAAA,CAAe,IAAA,KAAS,UAAU,OAAOJ,IAAAA,CAAG,GAAG,KAAK,CAAA;AAC3E,IAAA,MAAM,IAAA,GAAO,2BAA2B,KAAA,EAAO,QAAA,EAAU,gBAAgB,EAAA,CAAG,KAAA,EAAO,GAAG,KAAK,CAAA;AAC3F,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA;AAGrB,IAAA,OAAOA,IAAAA,CAAG,IAAA,CAAK,KAAA,IAAS,CAAC,CAAA;AAAA,EAC3B;AAEA,EAAA,IAAI,OAAO,EAAA,CAAG,KAAA,KAAU,QAAA,IAAY,EAAA,CAAG,KAAA,KAAU,IAAA,IAAQ,KAAA,CAAM,OAAA,CAAQ,EAAA,CAAG,KAAK,CAAA,EAAG;AAChF,IAAA,OAAOA,IAAAA,CAAG,GAAG,KAAK,CAAA;AAAA,EACpB;AACA,EAAA,MAAM,MAAM,EAAA,CAAG,KAAA;AACf,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG;AACxC,IAAA,MAAM,iBAAiB,MAAA,GAAS,mBAAA,CAAoB,MAAA,CAAO,SAAS,CAAC,CAAA,GAAI,MAAA;AACzE,IAAA,IAAI,CAAC,cAAA,IAAkB,cAAA,CAAe,IAAA,KAAS,QAAA,EAAU;AACvD,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,GAAA,CAAI,SAAS,CAAA;AAC9B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,0BAAA;AAAA,MACX,KAAA;AAAA,MACA,QAAA;AAAA,MACA,cAAA;AAAA,MACA,IAAI,SAAS,CAAA;AAAA,MACb;AAAA,KACF;AACA,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA;AACrB,IAAA,IAAI,cAAA,CAAe,MAAA,IAAU,IAAA,CAAK,KAAA,KAAU,MAAA,EAAW;AACvD,IAAA,GAAA,CAAI,SAAS,IAAI,IAAA,CAAK,KAAA;AAAA,EACxB;AACA,EAAA,OAAOA,KAAG,GAAG,CAAA;AACf;AAGO,SAAS,yBAAA,CACd,UAAA,EACA,UAAA,EACA,IAAA,EACuE;AACvE,EAAA,MAAM,YAAA,GAAe,qBAAA,CAAsB,UAAA,EAAY,CAAC,aAAA,KAAkB;AACxE,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,aAAa,CAAA;AAC9C,IAAA,OAAO,SAAA,KAAc,MAAA,GAAY,MAAA,GAAYI,eAAAA,CAAgB,SAAS,CAAA;AAAA,EACxE,CAAC,CAAA;AACD,EAAA,IAAI,CAAC,aAAa,EAAA,EAAI;AACpB,IAAA,MAAM,KAAA,GAAQ,aAAa,KAAA,CAAM,KAAA;AACjC,IAAA,OAAOH,KAAAA;AAAA,MACL,IAAI,oCAAA;AAAA,QACF,aAAa,KAAA,CAAM,KAAA;AAAA,QACnB,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,QAAA,GAAW,KAAA,GAAQ,OAAO,KAAK;AAAA;AAC/E,KACF;AAAA,EACF;AACA,EAAA,OAAOD,IAAAA,CAAG;AAAA,IACR,aAAA,EAAe,OAAA;AAAA,IACf,IAAA,EAAM,uBAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN;AAAA,QACE,IAAA,EAAM,IAAA,IAAQ,MAAA,CAAO,UAAA,EAAW;AAAA,QAChC,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,aAAa,KAAA,CAAM,OAAA;AAAA,QAC5B,IAAA,EAAM,aAAa,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,SAAA,KAAc,UAAU,IAAI,CAAA;AAAA,QAC/D,WAAW;AAAC;AACd;AACF,GACD,CAAA;AACH;AAcO,SAAS,iBAAA,CACd,QAAA,EACA,KAAA,EACA,KAAA,EAIA;AACA,EAAA,MAAM,cAAA,GAAiB,qBAAA;AAEvB,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,cAAA,CAAe,KAAA,EAAO,MAAM,OAAO,CAAA;AAC7D,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,CAAA,EAAG,OAAOA,IAAAA,CAAG,EAAE,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,EAAC,EAAG,CAAA;AAEjE,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,UAAA,CAAW,GAAA,CAAI,CAAW,CAAA;AAGjD,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AACvC,EAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,IAAA,IAAI,KAAA,CAAM,IAAI,EAAA,EAAoB,aAAa,EAAE,EAAA,EAAI,cAAA,CAAe,IAAI,EAAE,CAAA;AAAA,EAC5E;AASA,EAAA,MAAM,aAAA,GAAgB,CAAC,GAAG,cAAc,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AAG9D,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AACvC,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAA0D;AACnF,EAAA,KAAA,MAAW,MAAM,aAAA,EAAe;AAC9B,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,0BAAA,CAA2B,KAAA,EAAO,EAAkB,CAAA;AAC/D,IAAA,IAAI,CAAC,GAAG,EAAA,EAAI;AACZ,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,GAAG,CAAA,IAAK,EAAA,CAAG,MAAM,eAAA,EAAiB;AAChD,MAAA,MAAM,EAAA,GAAK,EAAA;AACX,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,IAAK,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,IAAK,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,EAAG;AACzE,QAAA,cAAA,CAAe,IAAI,EAAE,CAAA;AACrB,QAAA,YAAA,CAAa,IAAI,EAAA,EAAI,EAAE,WAAW,EAAA,EAAI,aAAA,EAAe,KAA0B,CAAA;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAC/B,IAAA,IAAI,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,IAAK,CAAC,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG,cAAA,CAAe,MAAA,CAAO,EAAE,CAAA;AAAA,EAC7E;AAwBA,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AACrD,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,UAAU,CAAA;AACvD,EAAA,MAAM,cAAA,uBAAqB,GAAA,CAAI,CAAC,aAAa,UAAA,EAAY,SAAA,EAAW,QAAQ,CAAC,CAAA;AAC7E,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAoB;AACjD,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,EAAA,MAAM,cAAA,GAAiB,CAAC,CAAA,EAAW,SAAA,KAA+B;AAChE,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,EAAG,OAAO,KAAA;AAC9B,IAAA,IAAI,cAAA,CAAe,IAAI,CAAC,CAAA,IAAK,eAAe,GAAA,CAAI,CAAC,GAAG,OAAO,KAAA;AAC3D,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAG,OAAO,KAAA;AAC5B,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,SAAS,KAAK,KAAA,CAAM,UAAA,CAAW,SAAQ,EAAG;AAC9D,MAAA,IAAI,cAAA,CAAe,GAAA,CAAI,QAAQ,CAAA,EAAG;AAClC,MAAA,IAAI,MAAM,GAAA,CAAI,CAAA,EAAmB,SAAiC,CAAA,CAAE,IAAI,OAAO,KAAA;AAAA,IACjF;AACA,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,CAAA,EAAmB,WAAmC,CAAA;AAC3E,MAAA,IAAI,GAAG,EAAA,EAAI;AACT,QAAA,MAAM,IAAA,GAAQ,GAAG,KAAA,CAA2C,QAAA;AAC5D,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,IAAI,eAAA,GAAkB,CAAA;AACtB,UAAA,IAAI,SAAA,GAAY,KAAA;AAChB,UAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,YAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,YAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAAG;AACrB,YAAA,eAAA,IAAmB,CAAA;AACnB,YAAA,IAAI,CAAA,KAAM,WAAW,SAAA,GAAY,IAAA;AAAA,UACnC;AACA,UAAA,IAAI,CAAC,SAAA,IAAa,eAAA,KAAoB,CAAA,EAAG,OAAO,KAAA;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACA,EAAA,IAAI,UAAA,EAAY;AAGd,IAAA,KAAA,MAAW,aAAa,aAAA,EAAe;AACrC,MAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA,EAAG;AACpC,MAAA,IAAI,UAAA,CAAW,GAAA,CAAI,SAAS,CAAA,EAAG;AAC/B,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,SAAA,EAA2B,UAAkC,CAAA;AAClF,MAAA,IAAI,CAAC,GAAG,EAAA,EAAI;AACZ,MAAA,MAAM,IAAA,GAAQ,GAAG,KAAA,CAAkC,MAAA;AACnD,MAAA,IAAI,SAAS,MAAA,EAAW;AACxB,MAAA,IAAI,CAAC,gBAAgB,GAAA,CAAI,IAAI,KAAK,cAAA,CAAe,IAAA,EAAM,SAAS,CAAA,EAAG;AACjE,QAAA,gBAAA,CAAiB,GAAA,CAAI,WAAW,IAAI,CAAA;AACpC,QAAA,eAAA,CAAgB,GAAA,CAAI,MAAM,SAAS,CAAA;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,eAAA,GAAkB,CAAC,GAAG,OAAO,CAAA;AACnC,EAAA,MAAM,gBAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,MAAM,eAAA,EAAiB;AAChC,IAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,EAAE,CAAA,EAAG;AAC7B,IAAA,IAAA,CAAK,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,IAAK,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,KAAM,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,EAAG;AAC9E,MAAA,aAAA,CAAc,KAAK,EAAE,CAAA;AAAA,IACvB;AAAA,EACF;AAEA,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,CAAc,QAAQ,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,CAAA,GAAI,cAAc,CAAC,CAAA;AACzB,IAAA,IAAI,CAAA,KAAM,MAAA,EAAW,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,EAC/C;AAGA,EAAA,MAAM,iBAAuF,EAAC;AAC9F,EAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAC/B,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,6BAAA,CAA8B,KAAA,EAAO,EAAkB,CAAA;AAClE,IAAA,IAAI,CAAC,EAAA,CAAG,EAAA;AACN,MAAA,OAAOC,KAAAA;AAAA,QACL,IAAI,oCAAA;AAAA,UACF,sBAAA;AAAA,UACA,EAAA,CAAG;AAAA;AACL,OACF;AACF,IAAA,MAAM,EAAA,GAAKE,kBAAAA;AAAA,MACT,KAAA;AAAA,MACA,EAAA,CAAG;AAAA,KACL;AACA,IAAA,IAAI,CAAC,EAAA,CAAG,EAAA;AACN,MAAA,OAAOF,KAAAA;AAAA,QACL,IAAI,oCAAA;AAAA,UACF,sBAAA;AAAA,UACA,EAAA,CAAG;AAAA;AACL,OACF;AACF,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,MAAA,CAAO,EAAA,CAAG,KAAc,CAAA;AAC3C,IAAA,IAAI,CAAA,KAAM,MAAA;AACR,MAAA,OAAOA,KAAAA;AAAA,QACL,IAAI,oCAAA;AAAA,UACF,sBAAA;AAAA,UACA,EAAA,CAAG;AAAA;AACL,OACF;AACF,IAAA,MAAM,EAAA,GAAK,0BAAA,CAA2B,KAAA,EAAO,EAAkB,CAAA;AAC/D,IAAA,IAAI,CAAC,EAAA,CAAG,EAAA;AACN,MAAA,OAAOA,KAAAA,CAAI,IAAI,oCAAA,CAAqC,sBAAA,EAAwB,OAAO,CAAC,CAAA;AACtF,IAAA,cAAA,CAAe,IAAA,CAAK,EAAE,SAAA,EAAW,EAAA,EAAI,UAAA,EAAY,GAAG,UAAA,EAAY,EAAA,CAAG,KAAA,CAAM,UAAA,EAAY,CAAA;AAAA,EACvF;AAGA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,eAAA,CAAgB,QAAQ,CAAA,EAAA,EAAK;AAC/C,IAAA,IAAI,eAAA,CAAgB,CAAC,CAAA,KAAM,MAAA,SAAkB,GAAA,CAAI,eAAA,CAAgB,CAAC,CAAA,EAAa,CAAC,CAAA;AAAA,EAClF;AACA,EAAA,cAAA,CAAe,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAA,CAAO,OAAO,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,IAAK,MAAM,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,SAAS,KAAK,CAAA,CAAE,CAAA;AAG7F,EAAA,MAAM,aAAa,aAAA,CAAc,MAAA;AACjC,EAAA,MAAM,YAAkC,EAAC;AACzC,EAAA,IAAI,MAAA,GAAS,aAAa,cAAA,CAAe,MAAA;AACzC,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AAEpD,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,WAAW,CAAA;AACxD,EAAA,KAAA,MAAW,KAAK,cAAA,EAAgB;AAK9B,IAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AACnD,IAAA,MAAM,eAAA,GAAkB,cAAc,CAAA,CAAE,SAAA;AACxC,IAAA,IAAI,EAAA;AACJ,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,eAAA,EAAiC,SAAiC,CAAA;AACvF,MAAA,IAAI,GAAG,EAAA,EAAI;AACT,QAAA,MAAM,IAAA,GAAQ,GAAG,KAAA,CAAkC,MAAA;AACnD,QAAA,IAAI,SAAS,MAAA,EAAW;AACtB,UAAA,MAAM,EAAA,GAAK,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA;AACnC,UAAA,IAAI,EAAA,KAAO,QAAW,EAAA,GAAK,EAAA;AAAA,eACtB;AACH,YAAA,MAAM,EAAA,GAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AAChC,YAAA,IAAI,OAAO,MAAA,EAAW;AACpB,cAAA,MAAM,EAAA,GAAK,eAAe,SAAA,CAAU,CAAC,MAAM,CAAA,CAAE,SAAA,KAAc,GAAG,SAAS,CAAA;AACvE,cAAA,IAAI,EAAA,IAAM,CAAA,EAAG,EAAA,GAAK,UAAA,GAAa,EAAA;AAAA,YACjC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI,UAAA,KAAe,UAAa,WAAA,EAAa;AAC3C,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,UAAA,EAA4B,WAAmC,CAAA;AACpF,MAAA,IAAI,GAAG,EAAA,EAAI;AACT,QAAA,eAAA,GAAkB;AAAA,UAChB,SAAA,EAAW,EAAE,GAAI,EAAA,CAAG,KAAA;AAAkC,SACxD;AAAA,MACF;AAAA,IACF;AAOA,IAAA,MAAM,YAAA,GAAe,MAAA;AACrB,IAAA,IAAI,cAAA;AACJ,IAAA,MAAM,YAAA,GAAe,0BAAA,CAA2B,KAAA,EAAO,CAAA,CAAE,SAAyB,CAAA;AAClF,IAAA,IAAI,aAAa,EAAA,EAAI;AACnB,MAAA,MAAM,YAAA,GAAe,kBAAA,CAAmB,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA;AACjE,MAAA,IAAI,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3B,QAAA,cAAA,GAAiB,EAAC;AAClB,QAAA,KAAA,MAAW,MAAM,YAAA,EAAc;AAC7B,UAAA,MAAM,OAAA,GAAU,8BAAA,CAA+B,KAAA,EAAO,QAAA,EAAU,EAAE,CAAA;AAClE,UAAA,IAAI,CAAC,OAAA,CAAQ,EAAA,EAAI,OAAO,OAAA;AACxB,UAAA,cAAA,CAAe,IAAA,CAAK;AAAA,YAClB,GAAG,EAAA;AAAA,YACH,OAAA,EAAU,eAAgB,EAAA,CAAG,OAAA;AAAA,YAC7B,OAAO,OAAA,CAAQ;AAAA,WAChB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAA4B;AAAA,MAChC,OAAA,EAAU,aAAa,SAAA,CAAU,MAAA;AAAA,MACjC,QAAQ,CAAA,CAAE,UAAA;AAAA,MACV,WAAA,EAAa,MAAA;AAAA,MACb,aAAa,CAAA,CAAE,UAAA;AAAA,MACf,GAAI,EAAA,KAAO,MAAA,GAAY,EAAE,MAAA,EAAQ,EAAA,KAAwB,EAAC;AAAA,MAC1D,GAAI,eAAA,KAAoB,MAAA,GAAY,EAAE,UAAA,EAAY,eAAA,KAAoB,EAAC;AAAA,MACvE,GAAI,cAAA,KAAmB,MAAA,IAAa,cAAA,CAAe,MAAA,GAAS,IACxD,EAAE,SAAA,EAAW,cAAA,EAAe,GAC5B;AAAC,KACP;AACA,IAAA,SAAA,CAAU,KAAK,KAAK,CAAA;AACpB,IAAA,MAAA,IAAU,CAAA,CAAE,UAAA;AAAA,EACd;AAGA,EAAA,SAAS,MAAM,CAAA,EAA+B;AAC5C,IAAA,MAAM,EAAA,GAAK,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAA;AAChC,IAAA,IAAI,EAAA,KAAO,QAAW,OAAO,EAAA;AAI7B,IAAA,MAAM,cAAA,GAAiB,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAA;AAC5C,IAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,cAAA,CAAe,QAAQ,CAAA,EAAA,EAAK;AAC9C,QAAA,IAAI,eAAe,CAAC,CAAA,EAAG,SAAA,KAAc,cAAA,SAAuB,UAAA,GAAa,CAAA;AAAA,MAC3E;AAAA,IACF;AACA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,cAAA,CAAe,QAAQ,CAAA,EAAA,EAAK;AAC9C,MAAA,IAAI,eAAe,CAAC,CAAA,EAAG,SAAA,KAAc,CAAA,SAAU,UAAA,GAAa,CAAA;AAAA,IAC9D;AACA,IAAA,MAAM,EAAA,GAAK,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA;AAC7B,IAAA,IAAI,OAAO,MAAA,EAAW;AACpB,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,cAAA,CAAe,QAAQ,CAAA,EAAA,EAAK;AAC9C,QAAA,IAAI,cAAA,CAAe,CAAC,CAAA,EAAG,SAAA,KAAc,GAAG,SAAA,EAAW;AACjD,UAAA,IAAI,EAAA,GAAK,aAAa,cAAA,CAAe,MAAA;AACrC,UAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,GAAI,CAAA,EAAG,KAAK,EAAA,IAAM,cAAA,CAAe,CAAC,CAAA,EAAG,UAAA,IAAc,CAAA;AACnE,UAAA,OAAO,KAAK,EAAA,CAAG,aAAA;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,UAAA,CAAW,OAAA,EAAQ;AACjD,EAAA,MAAM,WAA0B,EAAC;AAEjC,EAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,aAAA,CAAc,QAAQ,GAAA,EAAA,EAAO;AACnD,IAAA,MAAM,SAAA,GAAY,cAAc,GAAG,CAAA;AACnC,IAAA,IAAI,cAAc,MAAA,EAAW;AAC7B,IAAA,MAAM,MAAA,GAAS,SAAA;AACf,IAAA,MAAM,aAAsD,EAAC;AAC7D,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,GAAA,CAAI,SAAS,CAAA;AAEvC,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,SAAS,CAAA,IAAK,eAAA,EAAiB;AACnD,MAAA,IACE,CAAC,cAAA,CAAe,gBAAA;AAAA,QACd,QAAA;AAAA,QACAI,mBAAAA,CAAoB,SAAS,CAAA,CAAE,MAAA,CAAO,SAAA,KAAc;AAAA,OACtD;AAEA,QAAA;AACF,MAAA,IAAI,MAAA,IAAU,aAAa,SAAA,EAAW;AAEtC,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,SAAiC,CAAA;AAClE,MAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AAEhB,MAAA,MAAM,MAAM,MAAA,CAAO,KAAA;AACnB,MAAA,MAAM,IAAA,GAAO,SAAA;AACb,MAAA,IAAI,SAAS,MAAA,EAAW;AAExB,MAAA,MAAM,MAAA,GAASD,gBAAgB,IAAI,CAAA;AACnC,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAKrC,MAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,QAAA,UAAA,CAAW,QAAQ,IAAI,EAAC;AACxB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,cAAuC,EAAC;AAE9C,MAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,QAAA,MAAM,QAAA,GAAW,IAAI,SAAS,CAAA;AAC9B,QAAA,IAAI,aAAa,MAAA,EAAW;AAM5B,QAAA,IACE,CAAC,cAAA,CAAe,YAAA;AAAA,UACd,QAAA;AAAA,UACA,SAAA;AAAA,UACAC,oBAAoB,IAAI,CAAA,CAAE,MAAA,CAAO,SAAS,GAAG,SAAA,KAAc;AAAA,SAC7D;AAEA,UAAA;AAEF,QAAA,MAAM,eAAA,GAAkB,OAAO,SAAS,CAAA;AACxC,QAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,IAAA,EAAsB,SAAS,CAAA;AACtE,QAAA,MAAM,WAAA,GACJ,eAAA,KAAoB,MAAA,GAAY,mBAAA,CAAoB,eAAe,CAAA,GAAI,MAAA;AAEzE,QAAA,IAAI,CAAC,UAAA,IAAc,CAAC,WAAA,EAAa;AAC/B,UAAA,IAAI,YAAA,CAAa,QAAQ,CAAA,EAAG;AAC1B,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,eAAA,CAAgB,QAAQ,CAAA;AAAA,UACnD,CAAA,MAAO;AACL,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,QAAA;AAAA,UAC3B;AACA,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,eAAe,IAAA,EAAM;AAEvB,UAAA,IAAI,WAAW,OAAA,EAAS;AACtB,YAAA,MAAM,MAAM,YAAA,CAAa,QAAQ,CAAA,GAC7B,eAAA,CAAgB,QAAQ,CAAA,GACvB,QAAA;AACL,YAAA,MAAM,SAAmB,EAAC;AAC1B,YAAA,KAAA,MAAW,QAAQ,GAAA,EAAK;AACtB,cAAA,MAAM,IAAA,GAAO,MAAM,IAAc,CAAA;AACjC,cAAA,IAAI,SAAS,MAAA,EAAW;AACtB,gBAAA,OAAOJ,KAAAA;AAAA,kBACL,IAAI,sCAAA,CAAuC,SAAA,EAAW,SAAA,EAAW,IAAc;AAAA,iBACjF;AAAA,cACF;AACA,cAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,YAClB;AACA,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,MAAA;AAAA,UAC3B,CAAA,MAAO;AAIL,YAAA,IAAI,aAAa,IAAA,EAAM;AACvB,YAAA,MAAM,IAAA,GAAO,MAAM,QAAkB,CAAA;AACrC,YAAA,IAAI,SAAS,MAAA,EAAW;AACtB,cAAA,OAAOA,KAAAA;AAAA,gBACL,IAAI,sCAAA;AAAA,kBACF,SAAA;AAAA,kBACA,SAAA;AAAA,kBACA;AAAA;AACF,eACF;AAAA,YACF;AACA,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,IAAA;AAAA,UAC3B;AAAA,QACF,CAAA,MAAO;AASL,UAAA,MAAM,aAAa,YAAA,CAAa,QAAQ,CAAA,GAAI,eAAA,CAAgB,QAAQ,CAAA,GAAI,QAAA;AACxE,UAAA,IAAI,gBAAgB,MAAA,EAAW;AAE7B,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,UAAA;AACzB,YAAA;AAAA,UACF;AACA,UAAA,MAAM,IAAA,GAAO,0BAAA;AAAA,YACX,KAAA;AAAA,YACA,QAAA;AAAA,YACA,WAAA;AAAA,YACA,UAAA;AAAA,YACA;AAAA,WACF;AACA,UAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA;AACrB,UAAA,IAAI,WAAA,CAAY,MAAA,IAAU,IAAA,CAAK,KAAA,KAAU,MAAA,EAAW;AACpD,UAAA,WAAA,CAAY,SAAS,IAAI,IAAA,CAAK,KAAA;AAAA,QAChC;AAAA,MACF;AAEA,MAAA,IAAI,MAAA,CAAO,KAAK,WAAW,CAAA,CAAE,SAAS,CAAA,EAAG,UAAA,CAAW,QAAQ,CAAA,GAAI,WAAA;AAAA,IAClE;AAEA,IAAA,QAAA,CAAS,IAAA,CAAK,EAAE,OAAA,EAAS,GAAA,EAAsB,YAA2B,CAAA;AAAA,EAC5E;AAEA,EAAA,OAAOD,IAAAA,CAAG;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,QAAA;AAAA,IACA,GAAI,UAAU,MAAA,GAAS,CAAA,GAAI,EAAE,MAAA,EAAQ,SAAA,KAAc;AAAC,GACrD,CAAA;AACH","file":"index.mjs","sourcesContent":["import {\n type AssetDecoderContribution,\n type AssetKind,\n type AudioClipAsset,\n err,\n ok,\n} from '@forgeax/engine-types';\n\nexport const audioContribution: AssetDecoderContribution<AudioClipAsset, 'audio'> = {\n kind: { kind: 'audio' } as AssetKind<AudioClipAsset, 'audio'>,\n consumer: 'AudioBackend',\n decoder: {\n async decode({ envelope, artifacts }) {\n const payload = envelope.payload as unknown;\n if (payload !== null && typeof payload === 'object') {\n const source = payload as Record<string, unknown>;\n let bytes =\n source.bytes instanceof Uint8Array\n ? source.bytes\n : Array.isArray(source.bytes)\n ? Uint8Array.from(source.bytes as number[])\n : undefined;\n const body = envelope.artifacts.body ?? envelope.artifacts.source;\n if (body !== undefined) {\n const bodyBytes = await artifacts.read(body);\n if (!bodyBytes.ok) return bodyBytes;\n bytes = bodyBytes.value;\n }\n if (\n source.kind === 'audio' &&\n typeof source.mediaType === 'string' &&\n source.mediaType.startsWith('audio/') &&\n bytes !== undefined &&\n bytes.byteLength > 0\n ) {\n return ok({\n kind: 'audio',\n sourceKey:\n typeof source.sourceKey === 'string' && source.sourceKey.length > 0\n ? source.sourceKey\n : envelope.guid,\n mediaType: source.mediaType as `audio/${string}`,\n bytes,\n });\n }\n }\n return err({\n code: 'asset-package-invalid',\n expected: 'an audio payload with non-empty source bytes and audio mediaType',\n hint: 'recook the audio source with a browser-supported media type',\n detail: { guid: envelope.guid, reason: 'audio owner validation failed' },\n });\n },\n },\n};\n","// @forgeax/engine-audio -- AudioSource + AudioListener ECS components (feat-20260527-audio-system M1 / w9)\n//\n// Decision anchors:\n// - requirements S-3 (AudioSource single-component surface, 6 fields)\n// - requirements S-4 (AudioListener independent marker component)\n// - plan-strategy D-4 (edge-detection tick system; AudioSource.playing drives play/stop edges)\n// - plan-strategy D-5 (AudioSource.bus defaults to 'sfx'; BusName is 'sfx' | 'music')\n// - plan-strategy section 3.1 (6-field AudioSource + marker AudioListener)\n// - charter P1 (progressive disclosure: 3-symbol core surface)\n// - charter P4 (consistent abstraction: same defineComponent pattern as Transform/Camera)\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\nexport const AudioSource = defineComponent('AudioSource', {\n clip: { type: 'shared<AudioClipAsset>' },\n playing: { type: 'bool', default: false },\n loop: { type: 'bool', default: false },\n volume: { type: 'f32', default: 1.0 },\n spatialBlend: { type: 'f32', default: 0 },\n bus: { type: 'string', default: 'sfx' },\n});\n\nexport const AudioListener = defineComponent('AudioListener', {});\n","import { animationClipContribution, animationGraphContribution } from '@forgeax/engine-animation';\nimport { audioContribution } from '@forgeax/engine-audio';\nimport { fontContribution } from '@forgeax/engine-font';\nimport { meshAssetContribution } from '@forgeax/engine-geometry';\nimport { tilesetContribution, videoContribution } from '@forgeax/engine-graphics-extras';\nimport { equirectContribution, textureContribution } from '@forgeax/engine-image';\nimport {\n materialContribution,\n renderPipelineContribution,\n samplerContribution,\n} from '@forgeax/engine-render';\nimport { sceneAssetContribution } from '@forgeax/engine-scene';\nimport { skeletonContribution, skinContribution } from '@forgeax/engine-skinning';\nimport type { AssetDecoderContributionRef } from '@forgeax/engine-types';\nimport { particleEffectContribution } from '@forgeax/engine-vfx';\n\n/**\n * The built-in decoder set assembled by the host/runtime boundary.\n *\n * Each entry remains owned by its domain package; this list is only the one\n * default lease assembly for an App realm. A caller-provided contribution for\n * a built-in kind replaces that default entry for the current realm.\n */\nconst typedDefaultAssetDecoderContributions = [\n meshAssetContribution,\n materialContribution,\n sceneAssetContribution,\n textureContribution,\n equirectContribution,\n samplerContribution,\n fontContribution,\n renderPipelineContribution,\n tilesetContribution,\n videoContribution,\n skeletonContribution,\n skinContribution,\n animationClipContribution,\n animationGraphContribution,\n audioContribution,\n particleEffectContribution,\n] as const;\n\n// The registry installation seam intentionally erases the payload type while\n// it stores heterogeneous owner contributions. Each owner contribution above\n// remains typed at its source and is checked again by its decoder.\nexport const defaultAssetDecoderContributions = Object.freeze(\n typedDefaultAssetDecoderContributions as unknown as readonly AssetDecoderContributionRef[],\n);\n","import type { RendererOptions } from '@forgeax/engine-render';\nimport type { RhiBackendPack } from '@forgeax/engine-render/internal/construct-renderer';\nimport { err, ok, RhiError } from '@forgeax/engine-rhi';\nimport * as rhiWebgpu from '@forgeax/engine-rhi-webgpu';\n\nexport function loadRhiPack(\n mod: Record<string, unknown>,\n instrumentation?: RhiBackendPack['instrumentation'],\n): RhiBackendPack {\n const rhi = mod.rhi as unknown as RhiBackendPack['rhi'];\n const createShaderModule = mod.createShaderModule as\n | RhiBackendPack['createShaderModule']\n | undefined;\n const createShaderModuleImmediate = mod.createShaderModuleImmediate as\n | RhiBackendPack['createShaderModuleImmediate']\n | undefined;\n const translateErrorEventToRhiError = mod.translateErrorEventToRhiError as\n | RhiBackendPack['translateErrorEventToRhiError']\n | undefined;\n const rawDeviceAccessor = mod._internal_getRawDevice as unknown as\n | RhiBackendPack['_internal_getRawDevice']\n | undefined;\n const backendInstrumentation = mod.instrumentation as\n | RhiBackendPack['instrumentation']\n | undefined;\n const pack: RhiBackendPack = {\n rhi,\n ...(createShaderModule === undefined ? {} : { createShaderModule }),\n ...(createShaderModuleImmediate === undefined ? {} : { createShaderModuleImmediate }),\n ...(translateErrorEventToRhiError === undefined ? {} : { translateErrorEventToRhiError }),\n ...(rawDeviceAccessor === undefined ? {} : { _internal_getRawDevice: rawDeviceAccessor }),\n };\n const resolvedInstrumentation = instrumentation ?? backendInstrumentation;\n return resolvedInstrumentation === undefined\n ? pack\n : { ...pack, instrumentation: resolvedInstrumentation };\n}\n\n/** Selects one backend pack; render receives only this typed owner contract. */\nexport async function loadBackendPack(\n options: RendererOptions | undefined,\n preferWgpu = false,\n): Promise<\n | { readonly ok: true; readonly value: RhiBackendPack }\n | { readonly ok: false; readonly error: RhiError }\n> {\n const explicit = options?.rhi;\n if (explicit !== undefined && explicit !== null) {\n return ok(loadRhiPack({ rhi: explicit, ...(explicit as object) }, options?.rhiInstrumentation));\n }\n const nav =\n typeof globalThis === 'undefined'\n ? undefined\n : (globalThis as { navigator?: { gpu?: unknown } }).navigator;\n if (!preferWgpu && nav?.gpu !== undefined && nav.gpu !== null) {\n return ok(\n loadRhiPack(rhiWebgpu as unknown as Record<string, unknown>, options?.rhiInstrumentation),\n );\n }\n try {\n const mod = (await import('@forgeax/engine-rhi-wgpu')) as Record<string, unknown>;\n await (mod.ensureReady as () => Promise<unknown>)();\n return ok(loadRhiPack(mod, options?.rhiInstrumentation));\n } catch (cause) {\n return err(\n new RhiError({\n code: 'rhi-not-available',\n expected: 'a usable RHI backend is available',\n hint: `failed to load wgpu backend: ${String(cause)}`,\n }),\n );\n }\n}\n","import type { AssetRegistry } from '@forgeax/engine-assets-runtime';\nimport type { RenderError, RendererOptions, RenderResult } from '@forgeax/engine-render';\nimport type {\n BundlerOptions,\n RendererHostAssembly,\n} from '@forgeax/engine-render/internal/construct-renderer';\nimport {\n constructRendererHost,\n EngineEnvironmentError,\n} from '@forgeax/engine-render/internal/construct-renderer';\nimport { loadBackendPack } from './backend-selection';\n\nexport type {\n BundlerOptions,\n RendererHostAssembly,\n} from '@forgeax/engine-render/internal/construct-renderer';\n\nconst FALLBACK_ERROR_CODES = new Set([\n 'adapter-unavailable',\n 'request-adapter-threw',\n 'feature-not-enabled',\n 'limit-exceeded',\n 'rhi-not-available',\n 'device-lost',\n 'oom',\n]);\n\nfunction canFallbackToWgpu(error: unknown): boolean {\n if (!(error instanceof EngineEnvironmentError)) return false;\n const webgpuError = error.detail.webgpuError;\n if (webgpuError === undefined || typeof webgpuError !== 'object') return false;\n if (!('code' in webgpuError)) return false;\n const code = webgpuError.code;\n return typeof code === 'string' && FALLBACK_ERROR_CODES.has(code);\n}\n\n/** Assemble renderer plus asset services in the Runtime-owned backend host. */\nexport async function constructRuntimeRendererHost(\n canvas: unknown,\n options?: RendererOptions,\n bundler?: BundlerOptions,\n): Promise<RenderResult<RendererHostAssembly, RenderError | EngineEnvironmentError>> {\n const first = await loadBackendPack(options);\n if (!first.ok) throw first.error;\n const constructed = await constructRendererHost(canvas, options, bundler, first.value);\n if (\n constructed.ok ||\n options?.rhi !== undefined ||\n typeof globalThis === 'undefined' ||\n !canFallbackToWgpu(constructed.error)\n ) {\n return constructed;\n }\n const fallback = await loadBackendPack(options, true);\n if (!fallback.ok) return constructed;\n return constructRendererHost(canvas, options, bundler, fallback.value);\n}\n\nexport { loadRhiPack } from './backend-selection';\nexport type { AssetRegistry };\n","// Runtime is the host assembly facade. Concrete Renderer construction and\n// frame interpretation live in the render owner assembly.\nimport type { RenderError, Renderer, RendererOptions } from '@forgeax/engine-render';\nimport type { BundlerOptions } from '@forgeax/engine-render/internal/construct-renderer';\nimport { err, ok, type Result } from '@forgeax/engine-types';\nimport { EngineEnvironmentError } from './errors/environment';\nimport { constructRuntimeRendererHost } from './renderer-host';\n\n/**\n * Assemble the sole public renderer host.\n *\n * Runtime owns backend selection and partial-construction cleanup. Render owns\n * the scene/frame contract; successful construction returns the host that\n * exposes attach, draw, inspect, observe, and recover. Expected failures are\n * structured Result errors at the owning boundary; environment failures retain\n * EngineEnvironmentError recovery guidance for the caller.\n */\nexport async function createRenderer(\n canvas: HTMLCanvasElement | OffscreenCanvas,\n options?: RendererOptions,\n bundler?: BundlerOptions,\n): Promise<Result<Renderer, EngineEnvironmentError | RenderError>> {\n if (options !== undefined && 'rhi' in options && options.rhi === undefined) {\n return err(new EngineEnvironmentError('no usable rendering backend'));\n }\n const rendererOptions: RendererOptions | undefined =\n options === undefined\n ? undefined\n : {\n ...(options.rhi === undefined ? {} : { rhi: options.rhi }),\n ...(options.features === undefined ? {} : { features: options.features }),\n ...(options.profiler === undefined ? {} : { profiler: options.profiler }),\n ...(options.rhiInstrumentation === undefined\n ? {}\n : { rhiInstrumentation: options.rhiInstrumentation }),\n ...(options.standardProfile === undefined\n ? {}\n : { standardProfile: options.standardProfile }),\n };\n try {\n const constructed = await constructRuntimeRendererHost(canvas, rendererOptions, bundler);\n if (!constructed.ok) return err(constructed.error);\n return ok(constructed.value.renderer);\n } catch (cause) {\n if (cause instanceof EngineEnvironmentError) return err(cause);\n const detail = cause instanceof Error ? cause : new Error(String(cause));\n return err(new EngineEnvironmentError('renderer construction failed', { webgpuError: detail }));\n }\n}\n","// dev-import-transport.ts -- the dev-only ImportTransport adapter (M4 / w15,\n// AC-04). A host explicitly wires this into createRenderer / createApp so a\n// DDC miss at runtime triggers an on-demand import against the vite-plugin-pack\n// dev server (POST to the binding's scoped import endpoint). The shipped form\n// unwired so a miss fails fast with `asset-not-imported` (AC-08).\n//\n// Pure browser fetch -- no Node-only dependency (AC-04), no import.meta.env /\n// import.meta.hot / NODE_ENV probe (AC-05 / OOS-1: host-explicit assembly is\n// the only path, the library never auto-detects dev vs prod). The module also\n// never imports @forgeax/engine-image (image-pipeline-isolation: runtime/src\n// must not statically depend on the image package).\n\nimport type { ImportTransport, PackIndexEntry, RuntimeAssetBinding } from '@forgeax/engine-types';\n\nexport type DevImportTransportBinding = Pick<\n RuntimeAssetBinding,\n 'scopeId' | 'generation' | 'status' | 'importUrlBase'\n>;\n\n/**\n * Build the dev-only {@link ImportTransport}. A caller must provide the\n * current runtime binding; `fetchPack(guid)` then issues a scoped POST against\n * the vite-plugin-pack dev server, which imports\n * exactly that GUID's `.bin` and returns the single imported catalog row (+ any\n * sub-asset siblings). The caller patches those rows into its catalog cache\n * incrementally -- per-asset, never a whole-catalog re-fetch (the four-verb\n * redesign, 2026-06-06). On a non-2xx / network failure it reports\n * `{ ok: false }`.\n *\n * Aligns with the `wireDefaultLoaders` `create*` / `wire*` factory family so\n * IDE autocomplete on `@forgeax/engine-runtime` surfaces it.\n *\n * @example\n * import { createApp } from '@forgeax/engine-app';\n * import { createDevImportTransport } from '@forgeax/engine-runtime';\n * const app = await createApp(canvas, opts, {\n * importTransport: createDevImportTransport(runtimeBinding),\n * });\n */\nexport function createDevImportTransport(binding?: DevImportTransportBinding): ImportTransport {\n return {\n async fetchPack(\n guid: string,\n scope?: Pick<RuntimeAssetBinding, 'scopeId' | 'generation' | 'status'>,\n ): Promise<\n { readonly ok: true; readonly entries?: readonly PackIndexEntry[] } | { readonly ok: false }\n > {\n const active = binding;\n if (\n active === undefined ||\n active.status !== 'ready' ||\n scope === undefined ||\n scope.status !== 'ready' ||\n scope.scopeId !== active.scopeId ||\n scope.generation !== active.generation\n ) {\n return { ok: false };\n }\n try {\n const base = active.importUrlBase.replace(/\\/+$/, '');\n const response = await fetch(`${base}/${encodeURIComponent(guid)}`, { method: 'POST' });\n if (!response.ok) {\n // The ImportTransport contract has no error channel (returns only\n // ok:false), so the runtime would otherwise report a generic\n // `asset-not-imported`. Surface the dev server's structured failure\n // body (e.g. `code: fbx-mesh-type-unsupported`, reason, hint) to the\n // console so the actual cause is visible to AI/human users.\n try {\n const fail = (await response.json()) as {\n code?: string;\n reason?: string;\n hint?: string;\n };\n console.warn(\n `[forgeax] import failed for ${guid} (HTTP ${response.status}): ` +\n `${fail.code ?? 'import-failed'} - ${fail.reason ?? ''}` +\n (fail.hint ? ` | hint: ${fail.hint}` : ''),\n );\n } catch {\n // Non-JSON error body; nothing extra to surface.\n }\n return { ok: false };\n }\n try {\n const body = (await response.json()) as unknown;\n if (Array.isArray(body)) return { ok: true, entries: body as readonly PackIndexEntry[] };\n } catch {\n // Body was not JSON (or empty) -- success without inline rows; the\n // caller re-resolves the GUID from its cache.\n }\n return { ok: true };\n } catch {\n return { ok: false };\n }\n },\n };\n}\n","// @forgeax/engine-runtime - sprite-animation tick system (M4 / T-23).\n//\n// Walks every entity that carries `SpriteAnimation`, advances its dt\n// accumulator clock per Time.delta, and writes the current frame's UV slice\n// into the entity's `SpriteRegionOverride` column (auto-adding the\n// component on first observation when the entity does not yet carry it).\n// Designed to sit between `input` / `time` and `RenderSystem.extract` in\n// the schedule (plan-strategy section 2 D-7); the M3 sprite-bucket\n// extract branch (`render-system-extract.ts:861-870`) reads the override\n// column to materialise per-entity UV in the sprite snapshot.\n//\n// Why a stand-alone tick system instead of folding the dt accumulator\n// into the renderer? Charter P5 producer/consumer separation: the\n// renderer is a consumer of presentation state and never writes ECS\n// columns; the tick system owns the per-entity write so the\n// `SpriteRegionOverride.region` slot has exactly one writer (the tick\n// system) and zero readers in the writer tree (the extract branch is a\n// disjoint consumer). Plan-strategy section 1 + section 5 constraint #1\n// pin the boundary; this file is the producer half.\n//\n// Schedule positioning (informational; the App schedule is wired by the\n// host, not this file): input / time -> spriteAnimationTickSystem ->\n// RenderSystem.extract. The tick is `void`-returning under the\n// `Result<void, SpriteAnimationInvalidError>` shape so the schedule's\n// Layer-3 ErrorHandler observes a structured first-error signal without\n// the system aborting mid-pass on healthy entities (charter P3 explicit\n// failure + P4 consistent abstraction with `setTransparentSortConfig`'s\n// `Result<void, ResourceInvalidValueError>` shape).\n//\n// Invariants checked per-entity (AC-09 fail-fast paths; M1 T-05 added\n// `SpriteAnimationInvalidError`):\n// - `regions.length === frameCount * 4` -> detail.field='regions-length'\n// - `frameDuration > 0` -> detail.field='frame-duration'\n// First error wins; subsequent invalid entities still skip advance but\n// only the first surfaces in the returned Result.err. Healthy entities\n// continue to advance regardless of an invalid sibling (T-19 second\n// it() block locks this).\n//\n// Time.delta sourcing: `world.getResource(Time).delta`. When\n// the resource is missing (e.g. the tick system is invoked outside an\n// `App` rAF loop), dt defaults to 0 and the system runs as a no-op\n// schedule pass. Time.delta is already frame-loop clamped to a sane\n// ceiling by `@forgeax/engine-app frame-loop.ts`; the tick system MUST\n// NOT second-clamp (research F-3 + plan-strategy R-TIME-1). T-22 case\n// (1) feeds dt=30s directly to lock that contract.\n//\n// playbackMode dispatch: the per-entity `playbackMode: u32` column is\n// translated through `spritePlaybackModeFromU32` (M1 SSOT) into the\n// closed `'loop' | 'clamp'` literal union. The advance arm is selected\n// per-tick per-entity so AI users can mutate playbackMode at runtime\n// (e.g. swap LOOP for CLAMP on a death animation) and observe the\n// behavioural switch on the very next tick.\n//\n// Anchors: plan-strategy section 2 D-1 + D-5 + D-6 + D-7 + section 3.1\n// TICK + section 3.2 sequence diagram Tick->Ovr block + section 4 risk\n// R-TIME-1; plan-tasks.json T-23; requirements section 2.1 C system\n// surface + section AC-04 / AC-05 / AC-09 + section 7 boundary table;\n// charter P3 + P4 + P5 + F1.\n\nimport { type EntityHandle, Time, type World } from '@forgeax/engine-ecs';\nimport { SpriteAnimationInvalidError } from '@forgeax/engine-ecs/projection';\nimport {\n SpriteAnimation,\n SpriteRegionOverride,\n spritePlaybackModeFromU32,\n} from '@forgeax/engine-render/authoring';\nimport { err, ok, type Result } from '@forgeax/engine-types';\n\n/**\n * Walk every entity carrying `SpriteAnimation`, advance its dt\n * accumulator, and write the current frame's UV slice to the entity's\n * `SpriteRegionOverride` column.\n *\n * Returns `Result<void, SpriteAnimationInvalidError>`:\n *\n * - `ok(void)` when every observed entity satisfies both invariants\n * (`regions.length === frameCount * 4` and `frameDuration > 0`) — the\n * pass advanced every entity normally.\n * - `err(SpriteAnimationInvalidError)` carrying the FIRST entity-level\n * invariant violation observed during the pass. The offending entity\n * does not advance (its `currentFrame` / `accumDt` columns stay\n * untouched); every other healthy entity in the same pass still\n * advances normally so AI users observe a \"fail one, advance the\n * rest\" semantics rather than an all-or-nothing abort.\n *\n * The returned error is the canonical 4-field structured payload\n * (`.code` / `.expected` / `.hint` / `.detail`) — narrow on\n * `err.detail.field` (`'regions-length'` | `'frame-duration'`) to reach\n * the per-arm recovery hint without parsing the message string\n * (charter P3 + P4).\n *\n * @example Wire into an App schedule between input/time and the renderer:\n * ```ts\n * import { createApp } from '@forgeax/engine-app';\n * import { spriteAnimationTickSystem } from '@forgeax/engine-runtime';\n *\n * const app = createApp({ canvas, schedule: { update: [\n * spriteAnimationTickSystem,\n * // ... other systems\n * ] } });\n * ```\n *\n * @example Handle the first-error-wins surface:\n * ```ts\n * const r = spriteAnimationTickSystem(world);\n * if (!r.ok) {\n * // r.error.code === 'sprite-animation-invalid'\n * if (r.error.detail.field === 'regions-length') {\n * console.warn(`fix regions buffer length to ${r.error.detail.frameCount * 4}`);\n * }\n * }\n * ```\n */\nexport function spriteAnimationTickSystem(world: World): Result<void, SpriteAnimationInvalidError> {\n const dt = world.getResource(Time).delta;\n\n // Query filters entities carrying SpriteAnimation, so a World that never\n // spawned the component naturally yields an empty entity set (the pass is a\n // no-op).\n // Two-pass to avoid mid-iteration archetype migration. The auto-add\n // of `SpriteRegionOverride` migrates the entity into a new archetype\n // (SA + SRO) which a single-pass query would re-visit later in the same\n // pass — yielding double-advance\n // for any entity that did not yet carry the override. Collecting\n // every Entity handle first gives each entity a single tick.\n const entities = collectAnimEntities(world);\n\n let firstError: SpriteAnimationInvalidError | null = null;\n for (const entity of entities) {\n const entryError = tickEntity(world, entity, dt);\n if (entryError !== null && firstError === null) {\n firstError = entryError;\n }\n }\n\n if (firstError !== null) {\n return err(firstError);\n }\n return ok(undefined);\n}\n\n/**\n * First pass: collect every Entity handle from the ECS Query projection.\n * Handles remain valid across subsequent migrations because they are stable\n * index+generation identities, not archetype-row pointers.\n */\nfunction collectAnimEntities(world: World): EntityHandle[] {\n const queryResult = world.query({ with: [SpriteAnimation] });\n if (!queryResult.ok) return [];\n const entities: EntityHandle[] = [];\n for (const row of queryResult.value) entities.push(row.entity);\n return entities;\n}\n\n/**\n * Second pass: validate one entity's `SpriteAnimation` invariants,\n * advance its dt accumulator, and write the per-frame UV slice into\n * `SpriteRegionOverride`. Returns `null` when the entity advanced\n * normally; returns a structured `SpriteAnimationInvalidError` instance\n * when the entity's row violates an invariant (the caller stitches the\n * first such error into the system's Result.err).\n */\nfunction tickEntity(\n world: World,\n entity: EntityHandle,\n dt: number,\n): SpriteAnimationInvalidError | null {\n const snapRes = world.get(entity, SpriteAnimation);\n if (!snapRes.ok) {\n // Defensive: the alive-record check inside world.get already guards\n // stale handles; reaching here means something racier (component\n // sweep removed the column mid-pass). Skip silently — the route is\n // engine-internal, not an AI-user-visible failure mode.\n return null;\n }\n const snap = snapRes.value;\n const frameCount = snap.frameCount;\n const frameDuration = snap.frameDuration;\n const regions = snap.regions;\n\n // Invariant: regions.length === frameCount * 4 (D-1 fail-fast,\n // T-19 covers).\n if (regions.length !== frameCount * 4) {\n return new SpriteAnimationInvalidError({\n field: 'regions-length',\n regionsLength: regions.length,\n frameCount,\n });\n }\n // Invariant: frameDuration > 0 (covers both === 0 and < 0; T-20 +\n // T-21 lock both arms to the same .detail.field='frame-duration'\n // branch — charter P4 consistent abstraction).\n if (!(frameDuration > 0)) {\n return new SpriteAnimationInvalidError({\n field: 'frame-duration',\n frameDuration,\n });\n }\n\n const advanced = advanceFrame(\n snap.currentFrame,\n snap.accumDt + dt,\n frameDuration,\n frameCount,\n snap.playbackMode,\n );\n\n // Write the new clock state. Partial set leaves regions / frameCount\n // / frameDuration / playbackMode untouched (world.set iterates\n // Object.keys(value)).\n const writeAnim = world.set(entity, SpriteAnimation, {\n currentFrame: advanced.currentFrame,\n accumDt: advanced.accumDt,\n });\n if (!writeAnim.ok) return null;\n\n // Materialise the per-frame UV slice into SpriteRegionOverride.\n // The slice is guaranteed to be 4 floats by the regions-length\n // invariant above. A fresh Float32Array is allocated per write so\n // the column owner's BufferPool slot does not alias the\n // SpriteAnimation.regions backing array (charter P5 producer\n // boundary: the override slot is a snapshot, not a view).\n const sliceStart = advanced.currentFrame * 4;\n const region = new Float32Array([\n regions[sliceStart] ?? 0,\n regions[sliceStart + 1] ?? 0,\n regions[sliceStart + 2] ?? 0,\n regions[sliceStart + 3] ?? 0,\n ]);\n writeOverride(world, entity, region);\n return null;\n}\n\n/**\n * Advance `currentFrame` / `accumDt` per the dt accumulator clock model\n * (research F-3 + plan-strategy section 2 D-5). `dt` is the\n * already-frame-loop-clamped Time.delta; the inner while-loop drains\n * frameDuration units one at a time. The playbackMode discriminator\n * picks LOOP (wrap) vs CLAMP (halt at last frame) per-tick per-entity\n * (D-5).\n */\nfunction advanceFrame(\n currentFrameIn: number,\n accumDtIn: number,\n frameDuration: number,\n frameCount: number,\n playbackModeRaw: number,\n): { currentFrame: number; accumDt: number } {\n let currentFrame = currentFrameIn;\n let accumDt = accumDtIn;\n const playback = spritePlaybackModeFromU32(playbackModeRaw);\n while (accumDt >= frameDuration) {\n accumDt -= frameDuration;\n switch (playback) {\n case 'loop': {\n currentFrame = (currentFrame + 1) % frameCount;\n break;\n }\n case 'clamp': {\n // `min(currentFrame + 1, frameCount - 1)`; once at the last\n // frame the index stops advancing. The accumDt subtraction\n // continues so the residue does not pile up across ticks (T-18\n // second it() block + T-22 case (2b) lock the halt).\n if (currentFrame < frameCount - 1) {\n currentFrame += 1;\n }\n break;\n }\n }\n }\n return { currentFrame, accumDt };\n}\n\n/**\n * Write the per-entity UV region into `SpriteRegionOverride`,\n * add-or-set with no registration-concept probe.\n *\n * `addComponent` is the registration-agnostic entry point: it auto-adds\n * the `SpriteRegionOverride` column on first use, so a World that only ever\n * spawned `SpriteAnimation` reaches the override column through this single\n * call (requirements section 7 boundary table row 2 / charter P3). When the\n * entity already carries the column, `addComponent` returns\n * `err(component-already-present)` — the steady-state signal — and we\n * `set` the region in place. `SpriteRegionOverride` declares no\n * relationship, so the exclusive auto-reparent arm of `addComponent`\n * never fires and `component-already-present` is the only present-case\n * outcome.\n *\n * This replaces the former `_getComponentByName` registration gate: the\n * \"is it registered\" question is no longer asked at all — `addComponent`\n * owns registration, and column presence is read from its structured\n * `Result` rather than a per-World registry lookup.\n */\nfunction writeOverride(world: World, entity: EntityHandle, region: Float32Array): void {\n const added = world.addComponent(entity, {\n component: SpriteRegionOverride,\n data: { region },\n });\n if (!added.ok && added.error.code === 'component-already-present') {\n world.set(entity, SpriteRegionOverride, { region });\n }\n}\n","// feat-20260713-mount-override-component-add-and-shared-ref-round M5 / w20 —\n// collect fold: derive the runtime-authored MountOverride[] for one nested\n// SceneInstance anchor (plan-strategy D-3).\n//\n// ── What it does ──\n// Given a nested anchor's SceneInstanceState, walk each live member entity and\n// diff its live component columns against the member's authored baseline (the\n// source SceneAsset's layer-1 values, filled with schema defaults so the\n// comparison is against a fully-populated row). Every difference becomes a\n// MountOverride the collect step splices into the parent's `mounts[].overrides`:\n// - a component present live but absent in source -> component-ADD override\n// ({ localId, comp, value }) whose value is the whole filled component map;\n// - a field whose live value differs from baseline -> field-PATCH override\n// ({ localId, comp, field, value }) for that single field;\n// - a component present in source but absent live -> NOT emitted (OOS-6:\n// component-remove deltas do not fold back this feat).\n//\n// ── Value domain ──\n// The fold emits values in the LIVE domain: shared<T> fields carry numeric\n// handles, not GUID strings. The caller (rootsToSceneAsset / serialize wiring,\n// w21) performs the handle->GUID reverse-lookup with the two-state NULL-sentinel\n// handling (scalar handle 0 -> omit, array handle 0 -> keep positional 0),\n// reusing the same classifier the owned-entity serialization uses. Keeping the\n// fold registry-free means it stays a pure World+state read (D-3 / §2.5).\n//\n// ── localId namespace ──\n// Emitted `localId` is in the CHILD scene's namespace (0-based, exactly what\n// `state.entityToLocalId` maps to). The collect caller rebases it into the\n// parent namespace by adding the mount window's `memberFirst`, so the override\n// addresses the same slot the apply path validates against\n// (`_validateMountOverrides`: [memberFirst, memberFirst + memberCount)).\n//\n// ── Idempotency (AC-04) ──\n// A parent-authored mount-time override is applied to the child member's LIVE\n// column at instantiate time, and the child's source SceneAsset does not carry\n// it — so `live - source` re-derives it every round. Emitting it exactly once\n// (never separately re-passing state.mountTimeOverrides on top) keeps the\n// override entry set stable across save->load->save cycles: lossless without\n// doubling. (Runtime fact grounding this: parent-authored overrides on a nested\n// member land in the PARENT anchor's state, not the folded child anchor's; the\n// child anchor's own mountTimeOverrides is empty. See the M5 implement report.)\n\nimport { resolveAssetHandle } from '@forgeax/engine-assets-runtime';\nimport {\n componentDefinition,\n type Component as EcsComponent,\n type EntityHandle,\n type World,\n} from '@forgeax/engine-ecs';\nimport { componentSchema } from '@forgeax/engine-ecs/internal';\nimport { fillComponentDefaults } from '@forgeax/engine-ecs/projection';\nimport type {\n Handle,\n LocalEntityId,\n MountOverride,\n SceneAsset,\n SceneEntity,\n} from '@forgeax/engine-types';\n\n/** Minimal structural view of a SceneInstanceState the fold reads (D-4 boundary:\n * `world.getSceneInstanceState(root).value` is structurally assignable). */\nexport interface FoldSceneInstanceState {\n readonly source: Handle<'SceneAsset', 'shared'>;\n readonly entityToLocalId: Map<EntityHandle, LocalEntityId>;\n}\n\n/** Component names that never participate in an authored baseline diff: the\n * essential row-identity column, and structural hierarchy relationship\n * holders/mirrors (ChildOf/Children) whose live values are re-wired by\n * instantiate, not authored. */\nfunction excludedComponentNames(): Set<string> {\n return new Set<string>(['Entity', 'ChildOf', 'Children']);\n}\n\n/** Normalize an array-like (typed array or Array) to a plain array for\n * structural comparison; pass non-array values through unchanged. */\nfunction normalize(value: unknown): unknown {\n if (\n Array.isArray(value) ||\n value instanceof Uint32Array ||\n value instanceof Float32Array ||\n value instanceof Int32Array ||\n value instanceof Float64Array ||\n value instanceof Uint8Array ||\n value instanceof Int16Array ||\n value instanceof Uint16Array\n ) {\n return Array.from(value as ArrayLike<unknown>);\n }\n return value;\n}\n\n/** Structural value equality after array normalization (handles Float32Array vs\n * number[] and nested arrays via JSON). Both inputs are column-shape values. */\nfunction valuesEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(normalize(a)) === JSON.stringify(normalize(b));\n}\n\n/** Build the per-field baseline map for a member from its source node, filled\n * with schema defaults so it matches the fully-populated live row. Transient\n * fields are dropped (they are never authored / never serialized, D-5). */\nfunction baselineFields(\n comp: EcsComponent<string>,\n sourceRaw: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const filled = fillComponentDefaults(comp, sourceRaw ?? {});\n const out: Record<string, unknown> = {};\n const fields = componentDefinition(comp).fields;\n for (const fieldName of Object.keys(componentSchema(comp))) {\n if (fields[fieldName]?.transient) continue;\n out[fieldName] = filled[fieldName];\n }\n return out;\n}\n\n/** Read the live, non-transient, non-entity field values of a component on an\n * entity into a plain map. Entity-type fields are dropped: their live value is a\n * live EntityHandle while the source carries a LocalEntityId, so they cannot be\n * diffed without remap — entity-ref override deltas are out of scope this feat\n * (the AC set centers on shared/asset fields + component-add). */\nfunction liveFields(\n world: World,\n entity: EntityHandle,\n comp: EcsComponent<string>,\n): Record<string, unknown> | undefined {\n const res = world.get(entity, comp);\n if (!res.ok) return undefined;\n const val = res.value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n const fields = componentDefinition(comp).fields;\n const schema = componentSchema(comp) as Record<string, string>;\n for (const fieldName of Object.keys(schema)) {\n if (fields[fieldName]?.transient) continue;\n const fieldType = schema[fieldName];\n if (fieldType === 'entity' || fieldType === 'array<entity>') continue;\n out[fieldName] = normalize(val[fieldName]);\n }\n return out;\n}\n\n/**\n * Fold one nested anchor's live member state into the runtime-authored\n * MountOverride[] (child-namespace localIds, live value domain). See file\n * header for the full contract. Returns [] when nothing differs from source.\n */\nexport function foldMountOverrides(world: World, state: FoldSceneInstanceState): MountOverride[] {\n const sourceRes = resolveAssetHandle<SceneAsset>(\n world,\n state.source as unknown as Handle<string, 'shared'>,\n );\n if (!sourceRes.ok) return [];\n const source = sourceRes.value as SceneAsset;\n\n // Index source entities by localId for O(1) baseline lookup.\n const sourceByLid = new Map<number, SceneEntity>();\n for (const node of source.entities) {\n sourceByLid.set(node.localId as unknown as number, node);\n }\n\n const excluded = excludedComponentNames();\n const registered = world.components.entries();\n const overrides: MountOverride[] = [];\n\n // Deterministic member order (localId ascending) so collect output is a pure\n // function of the graph (mirrors rootsToSceneAsset D-7 ordering discipline).\n const members: Array<[EntityHandle, number]> = [];\n for (const [entity, lid] of state.entityToLocalId) {\n members.push([entity, lid as unknown as number]);\n }\n members.sort((a, b) => a[1] - b[1]);\n\n for (const [entity, lid] of members) {\n const sourceNode = sourceByLid.get(lid);\n const sourceComps = (sourceNode?.components ?? {}) as Record<string, Record<string, unknown>>;\n\n for (const [compName, compToken] of registered) {\n if (excluded.has(compName)) continue;\n if (componentDefinition(compToken).policy.transient) continue;\n const comp = compToken as EcsComponent<string>;\n if (Object.keys(componentSchema(comp)).length === 0) continue;\n\n const live = liveFields(world, entity, comp);\n if (live === undefined) continue; // component absent live\n\n const sourceRaw = sourceComps[compName];\n if (sourceRaw === undefined) {\n // Component present live but absent in source -> component-ADD override.\n // Emit the whole live component value map (apply upserts with defaults).\n overrides.push({\n localId: lid as unknown as LocalEntityId,\n comp: compName,\n value: live,\n });\n continue;\n }\n\n // Component present in both -> per-field diff (field-PATCH overrides).\n const baseline = baselineFields(comp, sourceRaw);\n for (const fieldName of Object.keys(live)) {\n if (!valuesEqual(live[fieldName], baseline[fieldName])) {\n overrides.push({\n localId: lid as unknown as LocalEntityId,\n comp: compName,\n field: fieldName,\n value: live[fieldName],\n });\n }\n }\n }\n }\n\n return overrides;\n}\n","// feat-20260623 M2 w11+w12 — SceneInstance to SceneAsset POD collection + pack\n// serialization (plan-strategy D-1: pure-data collector).\n//\n// feat-20260701-rootstosceneasset-forest-collect-schema-derived-ha:\n// rootsToSceneAsset(registry, world, roots) -> Result<SceneAsset, ...>\n// serializeSceneAssetToPack -> schema-derived refs[] index.\n//\n// feat-20260703-collect-nested-sceneinstance-to-mount-roundtrip M2 + M3:\n//\n// ── mount-collapse (M2) ──\n// rootsToSceneAsset detects entities carrying SceneInstance (anchors) and\n// folds each anchor's subtree into a mounts[] entry — the uplink inverse of\n// instantiateScene which expands mounts[] into live entities. Member\n// classification filter, not subtree pruning: BFS walks the full subtree\n// (collectSubtree unchanged, D-4), then anchors' members are folded into\n// mount windows, graft entities survive as owned, and cross-window entity\n// references are remapped to window LocalEntityIds. Two anchor forms:\n// Form 2 (root = instance) strips SceneInstance without self-mount; Form 1\n// (deep anchor) folds at the anchor site with mount.parent pointing to the\n// anchor's ChildOf parent. Window accounting (totalSlots = entities.length\n// + mounts.length + sum(memberCount)) preserves the child instance's full\n// totalSlots, never shrinking by surviving-member count (AC-03, #495 guard).\n//\n// ── serialize mounts (M3) ──\n// serializeSceneAssetToPack maps in-memory mounts[].source GUID strings to\n// refs[] indices, memberFirst/memberCount/localId/parent numeric pass-through.\n// _resolveSceneGuids (asset-registry.ts) carries mounts through the reload\n// chain: recursively resolves child scene GUIDs, registers child copies in\n// the origin reverse-index (D-7), and protects against mount-source cycles\n// (R-9). registry.instantiate wires an identity resolver so resolved mount\n// handles flow into instantiateScene transparently.\n//\n// ── round-trip closure ──\n// The round-trip instantiate -> collect (rootsToSceneAsset) -> serialize\n// (serializeSceneAssetToPack) -> reload (loadByGuid + registry.instantiate)\n// -> instantiate produces a structurally equivalent live subtree (AC-04).\n// The equivalence benchmark is a second collect (fixed-point): after the\n// first reload, the second collect output equals the first (D-9 normalization\n// converges after one cycle).\n//\n// ── known limitations ──\n// OOS-1: mount.overrides[] (Layer-0 diffs) are not folded back during collect.\n// D-9: Form 1 mount entity absorption — when the anchor parent cannot be\n// proven to be a mount entity, components is left undefined (one-time\n// normalization on first reload; fixed-point from second collect onward).\n\nimport {\n builtinMeshGuid,\n resolveAssetHandle,\n SceneCollectAssetGuidUnresolvedError,\n SceneCollectEntityRefOutOfClosureError,\n} from '@forgeax/engine-assets-runtime';\nimport {\n componentDefinition,\n type Component as EcsComponent,\n type EntityHandle,\n type World,\n} from '@forgeax/engine-ecs';\nimport { classifyEntityField } from '@forgeax/engine-ecs/externalization';\nimport { componentSchema } from '@forgeax/engine-ecs/internal';\nimport { SceneInstance } from '@forgeax/engine-render';\nimport { err, ok, type Result } from '@forgeax/engine-rhi';\nimport {\n collectSubtree,\n externalizeSceneAsset,\n SCENE_COLLECT_PROFILE,\n worldGetSceneAssetForInstance,\n worldGetSceneInstanceState,\n} from '@forgeax/engine-scene';\nimport type {\n Asset,\n Handle,\n LocalEntityId,\n MountOverride,\n SceneAsset,\n SceneEntity,\n SceneInstanceMount,\n} from '@forgeax/engine-types';\nimport { foldMountOverrides } from './scene-utils/mount-override-fold';\n\n/** The collector needs identity lookup, not an authoring registry implementation. */\nexport interface SceneAssetGuidLookup {\n guidOf(asset: Asset): string | undefined;\n}\n\n// Shared helpers\nfunction _isArrayLike(value: unknown): value is ArrayLike<unknown> {\n // SceneAsset values are ordinary JSON arrays at the boundary. Use the\n // platform view predicate so fixed-array component fields such as Fog.color\n // remain generic when their storage element type grows, while DataView (a\n // byte accessor without indexed array semantics) stays scalar.\n return Array.isArray(value) || (ArrayBuffer.isView(value) && !(value instanceof DataView));\n}\nfunction _normalizeArray(value: ArrayLike<unknown>): unknown[] {\n return Array.from(value);\n}\n\n// Schema-derived field classifier — shared kernel now owns entity classification.\n// Keep the local shared<T> classifier because the kernel only handles entity fields.\ntype SchemaFieldClass =\n | { kind: 'entity'; scalar: true }\n | { kind: 'entity'; scalar: false }\n | { kind: 'shared'; scalar: true }\n | { kind: 'shared'; scalar: false };\n\nfunction classifyFieldSchema(fieldType: string | undefined): SchemaFieldClass | undefined {\n if (fieldType === undefined) return undefined;\n if (fieldType.startsWith('shared<')) return { kind: 'shared', scalar: true };\n if (fieldType.startsWith('array<shared<')) return { kind: 'shared', scalar: false };\n return undefined;\n}\n\n// ── M5 (w21): override-value handle→GUID serialization ──\n//\n// Reverse-lookup one shared-field handle to its catalogued GUID string. Returns\n// `undefined` for the NULL sentinel (handle 0) so the caller applies the two\n// distinct sentinel semantics: scalar -> omit the field, array -> placeholder 0.\n// Any non-zero handle that fails to resolve is a fail-fast (D-2, no silent drop).\n// Shared kernel: both the owned-entity serialization loop (Step 4) and the M5\n// override-value serialization call this so the resolve/lookup/fail-fast idiom\n// lives in exactly one place; `field` names the failing field in the error.\nfunction _handleToGuid(\n world: World,\n registry: SceneAssetGuidLookup,\n handle: number,\n field: string,\n): Result<string | undefined, SceneCollectAssetGuidUnresolvedError> {\n if (handle === 0) return ok(undefined); // NULL sentinel\n const builtinGuid = builtinMeshGuid(handle as unknown as Handle<string, 'shared'>);\n if (builtinGuid !== undefined) return ok(builtinGuid);\n const assetRes = resolveAssetHandle(world, handle as unknown as Handle<string, 'shared'>);\n if (!assetRes.ok) return err(new SceneCollectAssetGuidUnresolvedError(field, handle));\n const guid = registry.guidOf(assetRes.value as Asset);\n if (guid === undefined) return err(new SceneCollectAssetGuidUnresolvedError(field, handle));\n return ok(guid);\n}\n\n// Convert one shared field value (scalar handle or array<handle>) from the live\n// handle domain to the serialized GUID domain, applying the two-state NULL\n// sentinel: scalar handle 0 -> undefined (caller omits the field); array handle\n// 0 -> numeric 0 kept in place (positional SoA alignment, #640). Non-shared\n// values pass through untouched.\nfunction _serializeSharedFieldValue(\n world: World,\n registry: SceneAssetGuidLookup,\n classification: SchemaFieldClass,\n value: unknown,\n field: string,\n): Result<unknown, SceneCollectAssetGuidUnresolvedError> {\n if (classification.scalar) {\n if (typeof value !== 'number') return ok(value);\n return _handleToGuid(world, registry, value, field); // undefined -> caller omits\n }\n if (!Array.isArray(value)) return ok(value);\n const mapped: Array<string | number> = [];\n for (const elem of value as ReadonlyArray<unknown>) {\n if (typeof elem !== 'number') {\n mapped.push(elem as number);\n continue;\n }\n const g = _handleToGuid(world, registry, elem, field);\n if (!g.ok) return g;\n mapped.push(g.value ?? 0); // NULL sentinel keeps positional 0\n }\n return ok(mapped);\n}\n\n// Convert an override's value from the live handle domain to the serialized GUID\n// domain (w21). Field-patch form (`ov.field` present) carries a single field\n// value; component-add form carries a per-field value map. Shared fields are\n// reverse-looked-up per {@link _serializeSharedFieldValue}; a scalar NULL\n// sentinel drops the key (component-add) or is kept as 0 (field-patch, where the\n// override IS that field so it cannot be omitted). Non-shared fields pass through.\nfunction _serializeOverrideValueHandles(\n world: World,\n registry: SceneAssetGuidLookup,\n ov: MountOverride,\n): Result<unknown, SceneCollectAssetGuidUnresolvedError> {\n const comp = world.components.resolve(ov.comp);\n const schema = comp === undefined ? undefined : (componentSchema(comp) as Record<string, string>);\n if (ov.field !== undefined) {\n const classification = schema ? classifyFieldSchema(schema[ov.field]) : undefined;\n if (!classification || classification.kind !== 'shared') return ok(ov.value);\n const conv = _serializeSharedFieldValue(world, registry, classification, ov.value, ov.field);\n if (!conv.ok) return conv;\n // Field-patch: keep the field even at NULL sentinel (the override IS the\n // field); undefined only arises for a scalar handle 0 -> emit 0.\n return ok(conv.value ?? 0);\n }\n // component-add: value is a per-field map.\n if (typeof ov.value !== 'object' || ov.value === null || Array.isArray(ov.value)) {\n return ok(ov.value);\n }\n const src = ov.value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const fieldName of Object.keys(src)) {\n const classification = schema ? classifyFieldSchema(schema[fieldName]) : undefined;\n if (!classification || classification.kind !== 'shared') {\n out[fieldName] = src[fieldName];\n continue;\n }\n const conv = _serializeSharedFieldValue(\n world,\n registry,\n classification,\n src[fieldName],\n fieldName,\n );\n if (!conv.ok) return conv;\n if (classification.scalar && conv.value === undefined) continue; // scalar 0 -> omit\n out[fieldName] = conv.value;\n }\n return ok(out);\n}\n\n// serializeSceneAssetToPack — emits the current Pack v2/local-artifact envelope.\nexport function serializeSceneAssetToPack(\n sceneAsset: SceneAsset,\n components: ReadonlyMap<string, EcsComponent>,\n guid?: string,\n): Result<Record<string, unknown>, SceneCollectAssetGuidUnresolvedError> {\n const externalized = externalizeSceneAsset(sceneAsset, (componentName) => {\n const component = components.get(componentName);\n return component === undefined ? undefined : componentSchema(component);\n });\n if (!externalized.ok) {\n const value = externalized.error.value;\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n externalized.error.field,\n typeof value === 'string' || typeof value === 'number' ? value : String(value),\n ),\n );\n }\n return ok({\n schemaVersion: '2.0.0',\n kind: 'internal-text-package',\n assets: [\n {\n guid: guid ?? crypto.randomUUID(),\n kind: 'scene',\n payload: externalized.value.payload,\n refs: externalized.value.refs.map((reference) => reference.guid),\n artifacts: {},\n },\n ],\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// rootsToSceneAsset — with M2 mount-collapse\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Collect a forest of entity subtrees into a self-contained SceneAsset.\n *\n * M2 mount-collapse: entities carrying SceneInstance that are NOT roots\n * are folded into mount entries. Root anchors have their SceneInstance\n * row stripped without producing a self-mount. Member classification\n * filter (not subtree pruning): graft entities under members survive as owned.\n */\nexport function rootsToSceneAsset(\n registry: SceneAssetGuidLookup,\n world: World,\n roots: EntityHandle[],\n): Result<\n SceneAsset,\n SceneCollectEntityRefOutOfClosureError | SceneCollectAssetGuidUnresolvedError\n> {\n const collectProfile = SCENE_COLLECT_PROFILE;\n // ── Step 1: BFS closure ──\n const visited = new Set<number>();\n for (const root of roots) collectSubtree(world, root, visited);\n if (visited.size === 0) return ok({ kind: 'scene', entities: [] });\n\n const rootRawSet = new Set<number>();\n for (const r of roots) rootRawSet.add(r as number);\n\n // ── Step 1.5: Mount-collapse — identify anchors ──\n const anchorEntities = new Set<number>();\n for (const er of visited) {\n if (world.get(er as EntityHandle, SceneInstance).ok) anchorEntities.add(er);\n }\n\n // D-7 (feat-20260707) ordering robustness: the first-wins loops below\n // (memberEntities claim + carrier absorption) resolve ties by iteration\n // order. Iterating the anchorEntities Set directly ties the outcome to BFS\n // insertion order — deterministic within one run but fragile to Node/VM\n // changes. Sort by raw handle so \"which anchor claims a shared member / a\n // shared carrier\" is a deterministic function of the SceneAsset (§3.2\n // fixed-point premise: collect output must be a pure function of the graph).\n const anchorsSorted = [...anchorEntities].sort((a, b) => a - b);\n\n // Classify members for non-root anchors.\n const memberEntities = new Set<number>();\n const memberOrigin = new Map<number, { anchorRaw: number; memberLocalId: number }>();\n for (const er of anchorsSorted) {\n if (rootRawSet.has(er)) continue; // root anchor: don't classify members\n const sr = worldGetSceneInstanceState(world, er as EntityHandle);\n if (!sr.ok) continue;\n for (const [me, lid] of sr.value.entityToLocalId) {\n const mr = me as number;\n if (visited.has(mr) && !anchorEntities.has(mr) && !memberEntities.has(mr)) {\n memberEntities.add(mr);\n memberOrigin.set(mr, { anchorRaw: er, memberLocalId: lid as unknown as number });\n }\n }\n }\n\n // Remove inner anchors (members of outer anchors).\n for (const er of anchorEntities) {\n if (memberEntities.has(er) && !rootRawSet.has(er)) anchorEntities.delete(er);\n }\n\n // ── Step 1.75: Mount-carrier absorption ──\n //\n // worldInstantiateScene materialises each mounts[] entry as a plain \"mount\n // entity\" (`_spawnMountEntity` output: mount.components + a default Transform,\n // but NO SceneInstance) whose child is the mounted scene's synthetic root (the\n // real anchor, which DOES carry SceneInstance). So a `mounts[{parent: W}]`\n // whose parent W is an OWNED entity comes back on reload as the live chain\n // W (owned) -> carrier (plain mount entity) -> anchor (SceneInstance).\n // The carrier IS the re-materialised mount slot. If collect keeps it as an\n // owned entity (it has no SceneInstance, so Step 2 would), the next serialize→\n // reload inserts ANOTHER carrier under it, growing one nameless ghost node per\n // save→reload cycle — unbounded (the editor \"Add to Scene → save → reopen →\n // #N\" regression). Existing pure-mount round-trips don't hit this because they\n // use `mount.parent === undefined` (mount attaches to the synthetic root,\n // which is stripped, so no owned carrier survives).\n //\n // Fix: recognise a carrier and fold it back into its mount. A carrier is the\n // ChildOf-parent P of a non-root anchor A where P is a pure mount slot: not a\n // root, not itself an anchor/member, carries no authored identity (only the\n // structural Transform/Children/ChildOf/Entity that _spawnMountEntity leaves),\n // and its sole visited child is A. The mount for A then takes P's slot:\n // mount.parent = P's ChildOf parent, and any ref to P resolves to the mount.\n const childOfTk0 = world.components.resolve('ChildOf');\n const childrenTk0 = world.components.resolve('Children');\n const carrierAllowed = new Set(['Transform', 'Children', 'ChildOf', 'Entity']);\n const carrierForAnchor = new Map<number, number>(); // anchorRaw -> carrierRaw\n const carrierToAnchor = new Map<number, number>(); // carrierRaw -> anchorRaw\n const isMountCarrier = (p: number, anchorRaw: number): boolean => {\n if (rootRawSet.has(p)) return false;\n if (anchorEntities.has(p) || memberEntities.has(p)) return false;\n if (!visited.has(p)) return false;\n for (const [compName, compToken] of world.components.entries()) {\n if (carrierAllowed.has(compName)) continue;\n if (world.get(p as EntityHandle, compToken as EcsComponent<string>).ok) return false;\n }\n if (childrenTk0) {\n const cr = world.get(p as EntityHandle, childrenTk0 as EcsComponent<string>);\n if (cr.ok) {\n const kids = (cr.value as { entities?: ArrayLike<number> }).entities;\n if (kids) {\n let visitedKidCount = 0;\n let sawAnchor = false;\n for (let i = 0; i < kids.length; i++) {\n const k = kids[i] as number;\n if (!visited.has(k)) continue;\n visitedKidCount += 1;\n if (k === anchorRaw) sawAnchor = true;\n }\n if (!sawAnchor || visitedKidCount !== 1) return false;\n }\n }\n }\n return true;\n };\n if (childOfTk0) {\n // Deterministic order (D-7): a carrier shared by two anchors is claimed by\n // the lowest-handle anchor regardless of Set iteration order.\n for (const anchorRaw of anchorsSorted) {\n if (!anchorEntities.has(anchorRaw)) continue; // pruned inner anchor\n if (rootRawSet.has(anchorRaw)) continue;\n const cr = world.get(anchorRaw as EntityHandle, childOfTk0 as EcsComponent<string>);\n if (!cr.ok) continue;\n const pRaw = (cr.value as Record<string, unknown>).parent as number | undefined;\n if (pRaw === undefined) continue;\n if (!carrierToAnchor.has(pRaw) && isMountCarrier(pRaw, anchorRaw)) {\n carrierForAnchor.set(anchorRaw, pRaw);\n carrierToAnchor.set(pRaw, anchorRaw);\n }\n }\n }\n\n // ── Step 2: Filter owned & build mounts for non-root anchors ──\n const orderedEntities = [...visited];\n const ownedEntities: number[] = [];\n for (const er of orderedEntities) {\n if (carrierToAnchor.has(er)) continue; // absorbed into its mount\n if ((!anchorEntities.has(er) || rootRawSet.has(er)) && !memberEntities.has(er)) {\n ownedEntities.push(er);\n }\n }\n\n const entityToLocalId = new Map<number, number>();\n for (let i = 0; i < ownedEntities.length; i++) {\n const e = ownedEntities[i];\n if (e !== undefined) entityToLocalId.set(e, i);\n }\n\n // Build non-root anchor info + resolve GUIDs.\n const nonRootAnchors: Array<{ entityRaw: number; sourceGuid: string; totalSlots: number }> = [];\n for (const er of anchorEntities) {\n if (rootRawSet.has(er)) continue;\n const sh = worldGetSceneAssetForInstance(world, er as EntityHandle);\n if (!sh.ok)\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n 'SceneInstance.source',\n sh.error as unknown as number,\n ),\n );\n const pr = resolveAssetHandle<SceneAsset>(\n world,\n sh.value as unknown as Handle<string, 'shared'>,\n );\n if (!pr.ok)\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n 'SceneInstance.source',\n sh.value as unknown as number,\n ),\n );\n const g = registry.guidOf(pr.value as Asset);\n if (g === undefined)\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n 'SceneInstance.source',\n sh.value as unknown as number,\n ),\n );\n const sr = worldGetSceneInstanceState(world, er as EntityHandle);\n if (!sr.ok)\n return err(new SceneCollectAssetGuidUnresolvedError('SceneInstance.source', 'state'));\n nonRootAnchors.push({ entityRaw: er, sourceGuid: g, totalSlots: sr.value.totalSlots });\n }\n\n // Sort by BFS order.\n const bfsIdx = new Map<number, number>();\n for (let i = 0; i < orderedEntities.length; i++) {\n if (orderedEntities[i] !== undefined) bfsIdx.set(orderedEntities[i] as number, i);\n }\n nonRootAnchors.sort((a, b) => (bfsIdx.get(a.entityRaw) ?? 0) - (bfsIdx.get(b.entityRaw) ?? 0));\n\n // ── Step 3: Allocate mount windows ──\n const ownedCount = ownedEntities.length;\n const outMounts: SceneInstanceMount[] = [];\n let nextMF = ownedCount + nonRootAnchors.length;\n const childOfTk = world.components.resolve('ChildOf');\n\n const transformTk = world.components.resolve('Transform');\n for (const a of nonRootAnchors) {\n // When a mount carrier was absorbed (Step 1.75), the mount takes the\n // carrier's slot: resolve the ChildOf parent from the CARRIER (the anchor's\n // own parent IS the carrier, which no longer exists as an owned entity), and\n // carry the carrier's Transform as mount.components so placement round-trips.\n const carrierRaw = carrierForAnchor.get(a.entityRaw);\n const parentSourceRaw = carrierRaw ?? a.entityRaw;\n let mp: number | undefined;\n if (childOfTk) {\n const cr = world.get(parentSourceRaw as EntityHandle, childOfTk as EcsComponent<string>);\n if (cr.ok) {\n const pRaw = (cr.value as Record<string, unknown>).parent as number;\n if (pRaw !== undefined) {\n const ol = entityToLocalId.get(pRaw);\n if (ol !== undefined) mp = ol;\n else {\n const mo = memberOrigin.get(pRaw);\n if (mo !== undefined) {\n const ai = nonRootAnchors.findIndex((x) => x.entityRaw === mo.anchorRaw);\n if (ai >= 0) mp = ownedCount + ai;\n }\n }\n }\n }\n }\n let mountComponents: SceneInstanceMount['components'] | undefined;\n if (carrierRaw !== undefined && transformTk) {\n const tr = world.get(carrierRaw as EntityHandle, transformTk as EcsComponent<string>);\n if (tr.ok) {\n mountComponents = {\n Transform: { ...(tr.value as Record<string, unknown>) },\n } as SceneInstanceMount['components'];\n }\n }\n // ── M5 (w20 + w21): fold runtime-authored overrides into this mount ──\n // foldMountOverrides emits child-namespace localIds in the LIVE handle\n // domain; rebase each into the parent namespace (memberFirst + childLocalId)\n // and reverse-lookup shared-field handles to GUID strings (two-state\n // NULL-sentinel). Unresolvable handle -> SceneCollectAssetGuidUnresolvedError\n // (D-2 fail-fast, no silent drop).\n const memberFirst0 = nextMF;\n let mountOverrides: MountOverride[] | undefined;\n const foldStateRes = worldGetSceneInstanceState(world, a.entityRaw as EntityHandle);\n if (foldStateRes.ok) {\n const rawOverrides = foldMountOverrides(world, foldStateRes.value);\n if (rawOverrides.length > 0) {\n mountOverrides = [];\n for (const ov of rawOverrides) {\n const convRes = _serializeOverrideValueHandles(world, registry, ov);\n if (!convRes.ok) return convRes;\n mountOverrides.push({\n ...ov,\n localId: (memberFirst0 + (ov.localId as unknown as number)) as LocalEntityId,\n value: convRes.value,\n });\n }\n }\n }\n\n const mount: SceneInstanceMount = {\n localId: (ownedCount + outMounts.length) as LocalEntityId,\n source: a.sourceGuid,\n memberFirst: nextMF as LocalEntityId,\n memberCount: a.totalSlots,\n ...(mp !== undefined ? { parent: mp as LocalEntityId } : {}),\n ...(mountComponents !== undefined ? { components: mountComponents } : {}),\n ...(mountOverrides !== undefined && mountOverrides.length > 0\n ? { overrides: mountOverrides }\n : {}),\n };\n outMounts.push(mount);\n nextMF += a.totalSlots;\n }\n\n // Entity ref resolution helper.\n function _rlid(t: number): number | undefined {\n const ol = entityToLocalId.get(t);\n if (ol !== undefined) return ol;\n // An absorbed mount carrier resolves to its mount's localId (the mount took\n // the carrier's slot in Step 1.75), so refs to the carrier — e.g. the\n // wrapper's Children list — point at the mount rather than dangle.\n const absorbedAnchor = carrierToAnchor.get(t);\n if (absorbedAnchor !== undefined) {\n for (let i = 0; i < nonRootAnchors.length; i++) {\n if (nonRootAnchors[i]?.entityRaw === absorbedAnchor) return ownedCount + i;\n }\n }\n for (let i = 0; i < nonRootAnchors.length; i++) {\n if (nonRootAnchors[i]?.entityRaw === t) return ownedCount + i;\n }\n const mo = memberOrigin.get(t);\n if (mo !== undefined) {\n for (let i = 0; i < nonRootAnchors.length; i++) {\n if (nonRootAnchors[i]?.entityRaw === mo.anchorRaw) {\n let mf = ownedCount + nonRootAnchors.length;\n for (let j = 0; j < i; j++) mf += nonRootAnchors[j]?.totalSlots ?? 0;\n return mf + mo.memberLocalId;\n }\n }\n }\n return undefined;\n }\n\n // ── Step 4: Build SceneEntity rows ──\n const registeredComps = world.components.entries();\n const entities: SceneEntity[] = [];\n\n for (let lid = 0; lid < ownedEntities.length; lid++) {\n const entityRaw = ownedEntities[lid];\n if (entityRaw === undefined) continue;\n const entity = entityRaw as EntityHandle;\n const components: Record<string, Record<string, unknown>> = {};\n const isRoot = rootRawSet.has(entityRaw);\n\n for (const [compName, compToken] of registeredComps) {\n if (\n !collectProfile.includeComponent(\n compName,\n componentDefinition(compToken).policy.transient === true,\n )\n )\n continue;\n if (isRoot && compName === 'ChildOf') continue;\n\n const valRes = world.get(entity, compToken as EcsComponent<string>);\n if (!valRes.ok) continue;\n\n const val = valRes.value as Record<string, unknown>;\n const comp = compToken;\n if (comp === undefined) continue;\n\n const schema = componentSchema(comp);\n const schemaKeys = Object.keys(schema);\n // Empty-schema components are authored marker components, not absent\n // state. Preserve their presence through scene-pack round-trips (for\n // example AudioListener); transient markers have already been excluded\n // above and therefore remain derived-only by declaration.\n if (schemaKeys.length === 0) {\n components[compName] = {};\n continue;\n }\n\n const fieldValues: Record<string, unknown> = {};\n\n for (const fieldName of schemaKeys) {\n const rawValue = val[fieldName];\n if (rawValue === undefined) continue;\n\n // Field-level transient skip (D-5): a field declared `transient: true`\n // is derived/reconstructable and excluded from serialization, just as a\n // transient component (L554) is. Generic — reads the reflection flag for\n // any component/field; no hardcoded component or field name.\n if (\n !collectProfile.includeField(\n compName,\n fieldName,\n componentDefinition(comp).fields[fieldName]?.transient === true,\n )\n )\n continue;\n\n const schemaFieldType = schema[fieldName];\n const entityKind = classifyEntityField(comp as EcsComponent, fieldName);\n const sharedClass =\n schemaFieldType !== undefined ? classifyFieldSchema(schemaFieldType) : undefined;\n\n if (!entityKind && !sharedClass) {\n if (_isArrayLike(rawValue)) {\n fieldValues[fieldName] = _normalizeArray(rawValue);\n } else {\n fieldValues[fieldName] = rawValue;\n }\n continue;\n }\n\n if (entityKind !== null) {\n // Entity / array<entity> field — use shared kernel for remap\n if (entityKind.isArray) {\n const arr = _isArrayLike(rawValue)\n ? _normalizeArray(rawValue)\n : (rawValue as unknown[]);\n const mapped: number[] = [];\n for (const elem of arr) {\n const lid2 = _rlid(elem as number);\n if (lid2 === undefined) {\n return err(\n new SceneCollectEntityRefOutOfClosureError(entityRaw, fieldName, elem as number),\n );\n }\n mapped.push(lid2);\n }\n fieldValues[fieldName] = mapped;\n } else {\n // A nullable entity field uses the ECS null sentinel and is omitted\n // from the scene payload just like a null shared handle. It is not\n // an out-of-closure reference.\n if (rawValue === null) continue;\n const lid2 = _rlid(rawValue as number);\n if (lid2 === undefined) {\n return err(\n new SceneCollectEntityRefOutOfClosureError(\n entityRaw,\n fieldName,\n rawValue as number,\n ),\n );\n }\n fieldValues[fieldName] = lid2;\n }\n } else {\n // shared<T> field — reverse-lookup handle(s) to GUID(s) via the shared\n // kernel (same two-state NULL-sentinel the M5 override serializer uses).\n // scalar handle 0 -> undefined => omit the field (deserialize restores\n // the slot-0 default; emitting 0 would be misread as refs index 0 by\n // parseScenePayload HANDLE_FIELD_NAMES). array handle 0 -> positional 0\n // kept (paired SoA alignment, e.g. AnimationPlayer.clips = [h,0,0,0]).\n // AnimationPlayer.graph (shared<AnimationGraph> scalar, M4/w31) is\n // handled generically here — no special case needed.\n const normalized = _isArrayLike(rawValue) ? _normalizeArray(rawValue) : rawValue;\n if (sharedClass === undefined) {\n // Fallback: non-entity, non-shared — pass through\n fieldValues[fieldName] = normalized;\n continue;\n }\n const conv = _serializeSharedFieldValue(\n world,\n registry,\n sharedClass,\n normalized,\n fieldName,\n );\n if (!conv.ok) return conv;\n if (sharedClass.scalar && conv.value === undefined) continue; // NULL sentinel -> omit\n fieldValues[fieldName] = conv.value;\n }\n }\n\n if (Object.keys(fieldValues).length > 0) components[compName] = fieldValues;\n }\n\n entities.push({ localId: lid as LocalEntityId, components } as SceneEntity);\n }\n\n return ok({\n kind: 'scene',\n entities,\n ...(outMounts.length > 0 ? { mounts: outMounts } : {}),\n });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../audio/src/assets/audio-decoder.ts","../../audio/src/components.ts","../src/asset-contributions.ts","../src/backend-selection.ts","../src/renderer-host.ts","../src/createRenderer.ts","../src/dev-import-transport.ts","../src/systems/sprite-animation-tick.ts","../src/scene-utils/mount-override-fold.ts","../src/collect-scene-asset.ts"],"names":["ok","err","EngineEnvironmentError","resolveAssetHandle","componentSchema","componentDefinition"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAQO,IAAM,iBAAA,GAAuE;EAClF,IAAA,EAAM,EAAE,MAAM,OAAA,EAAA;EACd,QAAA,EAAU,cAAA;EACV,OAAA,EAAS;AACP,IAAA,MAAM,MAAA,CAAO,EAAE,QAAA,EAAU,SAAA,EAAA,EAAa;AACpC,MAAA,MAAM,UAAU,QAAA,CAAS,OAAA;AACzB,MAAA,IAAI,OAAA,KAAY,IAAA,IAAQ,OAAO,OAAA,KAAY,QAAA,EAAU;AACnD,QAAA,MAAM,MAAA,GAAS,OAAA;AACf,QAAA,IAAI,KAAA,GACF,MAAA,CAAO,KAAA,YAAiB,UAAA,GACpB,OAAO,KAAA,GACP,KAAA,CAAM,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,GACxB,UAAA,CAAW,IAAA,CAAK,MAAA,CAAO,KAAiB,CAAA,GACxC,MAAA;AACR,QAAA,MAAM,IAAA,GAAO,QAAA,CAAS,SAAA,CAAU,IAAA,IAAQ,SAAS,SAAA,CAAU,MAAA;AAC3D,QAAA,IAAI,SAAS,MAAA,EAAW;AACtB,UAAA,MAAM,SAAA,GAAY,MAAM,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA;AAC3C,UAAA,IAAI,CAAC,SAAA,CAAU,EAAA,EAAI,OAAO,SAAA;AAC1B,UAAA,KAAA,GAAQ,SAAA,CAAU,KAAA;AACpB,QAAA;AACA,QAAA,IACE,OAAO,IAAA,KAAS,OAAA,IAChB,OAAO,MAAA,CAAO,cAAc,QAAA,IAC5B,MAAA,CAAO,SAAA,CAAU,UAAA,CAAW,QAAQ,CAAA,IACpC,KAAA,KAAU,MAAA,IACV,KAAA,CAAM,aAAa,CAAA,EACnB;AACA,UAAA,OAAO,EAAA,CAAG;YACR,IAAA,EAAM,OAAA;YACN,SAAA,EACE,OAAO,MAAA,CAAO,SAAA,KAAc,QAAA,IAAY,MAAA,CAAO,UAAU,MAAA,GAAS,CAAA,GAC9D,MAAA,CAAO,SAAA,GACP,QAAA,CAAS,IAAA;AACf,YAAA,SAAA,EAAW,MAAA,CAAO,SAAA;AAClB,YAAA;WACD,CAAA;AACH,QAAA;AACF,MAAA;AACA,MAAA,OAAO,GAAA,CAAI;QACT,IAAA,EAAM,uBAAA;QACN,QAAA,EAAU,kEAAA;QACV,IAAA,EAAM,6DAAA;AACN,QAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,QAAA,CAAS,IAAA,EAAM,QAAQ,+BAAA;OACxC,CAAA;AACH,IAAA;AAAA;AAEJ,CAAA;ACzC2B,gBAAgB,aAAA,EAAe;EACxD,IAAA,EAAM,EAAE,MAAM,wBAAA,EAAA;AACd,EAAA,OAAA,EAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAA;AAClC,EAAA,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAA;AAC/B,EAAA,MAAA,EAAQ,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,CAAA,EAAA;AAChC,EAAA,YAAA,EAAc,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,CAAA,EAAA;AACtC,EAAA,GAAA,EAAK,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,KAAA;AAClC,CAAC;AAE4B,eAAA,CAAgB,eAAA,EAAiB,EAAE;ACChE,IAAM,qCAAA,GAAwC;AAAA,EAC5C,qBAAA;AAAA,EACA,oBAAA;AAAA,EACA,sBAAA;AAAA,EACA,mBAAA;AAAA,EACA,oBAAA;AAAA,EACA,mBAAA;AAAA,EACA,gBAAA;AAAA,EACA,0BAAA;AAAA,EACA,mBAAA;AAAA,EACA,iBAAA;AAAA,EACA,oBAAA;AAAA,EACA,gBAAA;AAAA,EACA,yBAAA;AAAA,EACA,0BAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA;AAKO,IAAM,mCAAmC,MAAA,CAAO,MAAA;AAAA,EACrD;AACF;AC1CO,SAAS,WAAA,CACd,KACA,eAAA,EACgB;AAChB,EAAA,MAAM,MAAM,GAAA,CAAI,GAAA;AAChB,EAAA,MAAM,qBAAqB,GAAA,CAAI,kBAAA;AAG/B,EAAA,MAAM,8BAA8B,GAAA,CAAI,2BAAA;AAGxC,EAAA,MAAM,gCAAgC,GAAA,CAAI,6BAAA;AAG1C,EAAA,MAAM,oBAAoB,GAAA,CAAI,sBAAA;AAG9B,EAAA,MAAM,yBAAyB,GAAA,CAAI,eAAA;AAGnC,EAAA,MAAM,IAAA,GAAuB;AAAA,IAC3B,GAAA;AAAA,IACA,GAAI,kBAAA,KAAuB,MAAA,GAAY,EAAC,GAAI,EAAE,kBAAA,EAAmB;AAAA,IACjE,GAAI,2BAAA,KAAgC,MAAA,GAAY,EAAC,GAAI,EAAE,2BAAA,EAA4B;AAAA,IACnF,GAAI,6BAAA,KAAkC,MAAA,GAAY,EAAC,GAAI,EAAE,6BAAA,EAA8B;AAAA,IACvF,GAAI,iBAAA,KAAsB,MAAA,GAAY,EAAC,GAAI,EAAE,wBAAwB,iBAAA;AAAkB,GACzF;AACA,EAAA,MAAM,0BAA0B,eAAA,IAAmB,sBAAA;AACnD,EAAA,OAAO,4BAA4B,MAAA,GAC/B,IAAA,GACA,EAAE,GAAG,IAAA,EAAM,iBAAiB,uBAAA,EAAwB;AAC1D;AAGA,eAAsB,eAAA,CACpB,OAAA,EACA,UAAA,GAAa,KAAA,EAIb;AACA,EAAA,MAAM,WAAW,OAAA,EAAS,GAAA;AAC1B,EAAA,IAAI,QAAA,KAAa,MAAA,IAAa,QAAA,KAAa,IAAA,EAAM;AAC/C,IAAA,OAAOA,IAAAA,CAAG,WAAA,CAAY,EAAE,GAAA,EAAK,QAAA,EAAU,GAAI,QAAA,EAAoB,EAAG,OAAA,EAAS,kBAAkB,CAAC,CAAA;AAAA,EAChG;AACA,EAAA,MAAM,GAAA,GACJ,OAAO,UAAA,KAAe,WAAA,GAClB,SACC,UAAA,CAAiD,SAAA;AACxD,EAAA,IAAI,CAAC,UAAA,IAAc,GAAA,EAAK,QAAQ,MAAA,IAAa,GAAA,CAAI,QAAQ,IAAA,EAAM;AAC7D,IAAA,OAAOA,IAAAA;AAAA,MACL,WAAA,CAAY,SAAA,EAAiD,OAAA,EAAS,kBAAkB;AAAA,KAC1F;AAAA,EACF;AACA,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAO,MAAM,OAAO,0BAA0B,CAAA;AACpD,IAAA,MAAO,IAAI,WAAA,EAAuC;AAClD,IAAA,OAAOA,IAAAA,CAAG,WAAA,CAAY,GAAA,EAAK,OAAA,EAAS,kBAAkB,CAAC,CAAA;AAAA,EACzD,SAAS,KAAA,EAAO;AACd,IAAA,OAAOC,KAAAA;AAAA,MACL,IAAI,QAAA,CAAS;AAAA,QACX,IAAA,EAAM,mBAAA;AAAA,QACN,QAAA,EAAU,mCAAA;AAAA,QACV,IAAA,EAAM,CAAA,6BAAA,EAAgC,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,OACpD;AAAA,KACH;AAAA,EACF;AACF;;;ACvDA,IAAM,oBAAA,uBAA2B,GAAA,CAAI;AAAA,EACnC,qBAAA;AAAA,EACA,uBAAA;AAAA,EACA,qBAAA;AAAA,EACA,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAC,CAAA;AAED,SAAS,kBAAkB,KAAA,EAAyB;AAClD,EAAA,IAAI,EAAE,KAAA,YAAiBC,sBAAAA,CAAAA,EAAyB,OAAO,KAAA;AACvD,EAAA,MAAM,WAAA,GAAc,MAAM,MAAA,CAAO,WAAA;AACjC,EAAA,IAAI,WAAA,KAAgB,MAAA,IAAa,OAAO,WAAA,KAAgB,UAAU,OAAO,KAAA;AACzE,EAAA,IAAI,EAAE,MAAA,IAAU,WAAA,CAAA,EAAc,OAAO,KAAA;AACrC,EAAA,MAAM,OAAO,WAAA,CAAY,IAAA;AACzB,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,IAAY,oBAAA,CAAqB,IAAI,IAAI,CAAA;AAClE;AAGA,eAAsB,4BAAA,CACpB,MAAA,EACA,OAAA,EACA,OAAA,EACmF;AACnF,EAAA,MAAM,KAAA,GAAQ,MAAM,eAAA,CAAgB,OAAO,CAAA;AAC3C,EAAA,IAAI,CAAC,KAAA,CAAM,EAAA,EAAI,MAAM,KAAA,CAAM,KAAA;AAC3B,EAAA,MAAM,cAAc,MAAM,qBAAA,CAAsB,QAAQ,OAAA,EAAS,OAAA,EAAS,MAAM,KAAK,CAAA;AACrF,EAAA,IACE,WAAA,CAAY,EAAA,IACZ,OAAA,EAAS,GAAA,KAAQ,MAAA,IACjB,OAAO,UAAA,KAAe,WAAA,IACtB,CAAC,iBAAA,CAAkB,WAAA,CAAY,KAAK,CAAA,EACpC;AACA,IAAA,OAAO,WAAA;AAAA,EACT;AACA,EAAA,MAAM,QAAA,GAAW,MAAM,eAAA,CAAgB,OAAA,EAAS,IAAI,CAAA;AACpD,EAAA,IAAI,CAAC,QAAA,CAAS,EAAA,EAAI,OAAO,WAAA;AACzB,EAAA,OAAO,qBAAA,CAAsB,MAAA,EAAQ,OAAA,EAAS,OAAA,EAAS,SAAS,KAAK,CAAA;AACvE;;;ACvCA,eAAsB,cAAA,CACpB,MAAA,EACA,OAAA,EACA,OAAA,EACiE;AACjE,EAAA,IAAI,YAAY,MAAA,IAAa,KAAA,IAAS,OAAA,IAAW,OAAA,CAAQ,QAAQ,MAAA,EAAW;AAC1E,IAAA,OAAOD,GAAAA,CAAI,IAAI,sBAAA,CAAuB,6BAA6B,CAAC,CAAA;AAAA,EACtE;AACA,EAAA,MAAM,eAAA,GACJ,OAAA,KAAY,MAAA,GACR,MAAA,GACA;AAAA,IACE,GAAI,QAAQ,GAAA,KAAQ,MAAA,GAAY,EAAC,GAAI,EAAE,GAAA,EAAK,OAAA,CAAQ,GAAA,EAAI;AAAA,IACxD,GAAI,QAAQ,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAS;AAAA,IACvE,GAAI,QAAQ,QAAA,KAAa,MAAA,GAAY,EAAC,GAAI,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAS;AAAA,IACvE,GAAI,QAAQ,iBAAA,KAAsB,MAAA,GAC9B,EAAC,GACD,EAAE,iBAAA,EAAmB,OAAA,CAAQ,iBAAA,EAAkB;AAAA,IACnD,GAAI,QAAQ,kBAAA,KAAuB,MAAA,GAC/B,EAAC,GACD,EAAE,kBAAA,EAAoB,OAAA,CAAQ,kBAAA,EAAmB;AAAA,IACrD,GAAI,QAAQ,eAAA,KAAoB,MAAA,GAC5B,EAAC,GACD,EAAE,eAAA,EAAiB,OAAA,CAAQ,eAAA,EAAgB;AAAA,IAC/C,GAAI,QAAQ,aAAA,KAAkB,MAAA,GAAY,EAAC,GAAI,EAAE,aAAA,EAAe,OAAA,CAAQ,aAAA;AAAc,GACxF;AACN,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,MAAM,4BAAA,CAA6B,MAAA,EAAQ,iBAAiB,OAAO,CAAA;AACvF,IAAA,IAAI,CAAC,WAAA,CAAY,EAAA,EAAI,OAAOA,GAAAA,CAAI,YAAY,KAAK,CAAA;AACjD,IAAA,OAAOD,EAAAA,CAAG,WAAA,CAAY,KAAA,CAAM,QAAQ,CAAA;AAAA,EACtC,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,KAAA,YAAiB,sBAAA,EAAwB,OAAOC,GAAAA,CAAI,KAAK,CAAA;AAC7D,IAAA,MAAM,MAAA,GAAS,iBAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,CAAC,CAAA;AACvE,IAAA,OAAOA,GAAAA,CAAI,IAAI,sBAAA,CAAuB,8BAAA,EAAgC,EAAE,WAAA,EAAa,MAAA,EAAQ,CAAC,CAAA;AAAA,EAChG;AACF;;;ACbO,SAAS,yBAAyB,OAAA,EAAsD;AAC7F,EAAA,OAAO;AAAA,IACL,MAAM,SAAA,CACJ,IAAA,EACA,KAAA,EAGA;AACA,MAAA,MAAM,MAAA,GAAS,OAAA;AACf,MAAA,IACE,WAAW,MAAA,IACX,MAAA,CAAO,MAAA,KAAW,OAAA,IAClB,UAAU,MAAA,IACV,KAAA,CAAM,MAAA,KAAW,OAAA,IACjB,MAAM,OAAA,KAAY,MAAA,CAAO,WACzB,KAAA,CAAM,UAAA,KAAe,OAAO,UAAA,EAC5B;AACA,QAAA,OAAO,EAAE,IAAI,KAAA,EAAM;AAAA,MACrB;AACA,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAA,CAAO,aAAA,CAAc,OAAA,CAAQ,QAAQ,EAAE,CAAA;AACpD,QAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA,EAAI,EAAE,MAAA,EAAQ,QAAQ,CAAA;AACtF,QAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAMhB,UAAA,IAAI;AACF,YAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAKlC,YAAA,OAAA,CAAQ,IAAA;AAAA,cACN,+BAA+B,IAAI,CAAA,OAAA,EAAU,SAAS,MAAM,CAAA,GAAA,EACvD,KAAK,IAAA,IAAQ,eAAe,MAAM,IAAA,CAAK,MAAA,IAAU,EAAE,CAAA,CAAA,IACrD,IAAA,CAAK,OAAO,CAAA,SAAA,EAAY,IAAA,CAAK,IAAI,CAAA,CAAA,GAAK,EAAA;AAAA,aAC3C;AAAA,UACF,CAAA,CAAA,MAAQ;AAAA,UAER;AACA,UAAA,OAAO,EAAE,IAAI,KAAA,EAAM;AAAA,QACrB;AACA,QAAA,IAAI;AACF,UAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,UAAA,IAAI,KAAA,CAAM,QAAQ,IAAI,CAAA,SAAU,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,IAAA,EAAkC;AAAA,QACzF,CAAA,CAAA,MAAQ;AAAA,QAGR;AACA,QAAA,OAAO,EAAE,IAAI,IAAA,EAAK;AAAA,MACpB,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,EAAE,IAAI,KAAA,EAAM;AAAA,MACrB;AAAA,IACF;AAAA,GACF;AACF;ACiBO,SAAS,0BAA0B,KAAA,EAAyD;AACjG,EAAA,MAAM,EAAA,GAAK,KAAA,CAAM,WAAA,CAAY,IAAI,CAAA,CAAE,KAAA;AAWnC,EAAA,MAAM,QAAA,GAAW,oBAAoB,KAAK,CAAA;AAE1C,EAAA,IAAI,UAAA,GAAiD,IAAA;AACrD,EAAA,KAAA,MAAW,UAAU,QAAA,EAAU;AAC7B,IAAA,MAAM,UAAA,GAAa,UAAA,CAAW,KAAA,EAAO,MAAA,EAAQ,EAAE,CAAA;AAC/C,IAAA,IAAI,UAAA,KAAe,IAAA,IAAQ,UAAA,KAAe,IAAA,EAAM;AAC9C,MAAA,UAAA,GAAa,UAAA;AAAA,IACf;AAAA,EACF;AAEA,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAOA,IAAI,UAAU,CAAA;AAAA,EACvB;AACA,EAAA,OAAOD,GAAG,MAAS,CAAA;AACrB;AAOA,SAAS,oBAAoB,KAAA,EAA8B;AACzD,EAAA,MAAM,WAAA,GAAc,MAAM,KAAA,CAAM,EAAE,MAAM,CAAC,eAAe,GAAG,CAAA;AAC3D,EAAA,IAAI,CAAC,WAAA,CAAY,EAAA,EAAI,OAAO,EAAC;AAC7B,EAAA,MAAM,WAA2B,EAAC;AAClC,EAAA,KAAA,MAAW,OAAO,WAAA,CAAY,KAAA,EAAO,QAAA,CAAS,IAAA,CAAK,IAAI,MAAM,CAAA;AAC7D,EAAA,OAAO,QAAA;AACT;AAUA,SAAS,UAAA,CACP,KAAA,EACA,MAAA,EACA,EAAA,EACoC;AACpC,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,eAAe,CAAA;AACjD,EAAA,IAAI,CAAC,QAAQ,EAAA,EAAI;AAKf,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,OAAO,OAAA,CAAQ,KAAA;AACrB,EAAA,MAAM,aAAa,IAAA,CAAK,UAAA;AACxB,EAAA,MAAM,gBAAgB,IAAA,CAAK,aAAA;AAC3B,EAAA,MAAM,UAAU,IAAA,CAAK,OAAA;AAIrB,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,UAAA,GAAa,CAAA,EAAG;AACrC,IAAA,OAAO,IAAI,2BAAA,CAA4B;AAAA,MACrC,KAAA,EAAO,gBAAA;AAAA,MACP,eAAe,OAAA,CAAQ,MAAA;AAAA,MACvB;AAAA,KACD,CAAA;AAAA,EACH;AAIA,EAAA,IAAI,EAAE,gBAAgB,CAAA,CAAA,EAAI;AACxB,IAAA,OAAO,IAAI,2BAAA,CAA4B;AAAA,MACrC,KAAA,EAAO,gBAAA;AAAA,MACP;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,QAAA,GAAW,YAAA;AAAA,IACf,IAAA,CAAK,YAAA;AAAA,IACL,KAAK,OAAA,GAAU,EAAA;AAAA,IACf,aAAA;AAAA,IACA,UAAA;AAAA,IACA,IAAA,CAAK;AAAA,GACP;AAKA,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,eAAA,EAAiB;AAAA,IACnD,cAAc,QAAA,CAAS,YAAA;AAAA,IACvB,SAAS,QAAA,CAAS;AAAA,GACnB,CAAA;AACD,EAAA,IAAI,CAAC,SAAA,CAAU,EAAA,EAAI,OAAO,IAAA;AAQ1B,EAAA,MAAM,UAAA,GAAa,SAAS,YAAA,GAAe,CAAA;AAC3C,EAAA,MAAM,MAAA,GAAS,IAAI,YAAA,CAAa;AAAA,IAC9B,OAAA,CAAQ,UAAU,CAAA,IAAK,CAAA;AAAA,IACvB,OAAA,CAAQ,UAAA,GAAa,CAAC,CAAA,IAAK,CAAA;AAAA,IAC3B,OAAA,CAAQ,UAAA,GAAa,CAAC,CAAA,IAAK,CAAA;AAAA,IAC3B,OAAA,CAAQ,UAAA,GAAa,CAAC,CAAA,IAAK;AAAA,GAC5B,CAAA;AACD,EAAA,aAAA,CAAc,KAAA,EAAO,QAAQ,MAAM,CAAA;AACnC,EAAA,OAAO,IAAA;AACT;AAUA,SAAS,YAAA,CACP,cAAA,EACA,SAAA,EACA,aAAA,EACA,YACA,eAAA,EAC2C;AAC3C,EAAA,IAAI,YAAA,GAAe,cAAA;AACnB,EAAA,IAAI,OAAA,GAAU,SAAA;AACd,EAAA,MAAM,QAAA,GAAW,0BAA0B,eAAe,CAAA;AAC1D,EAAA,OAAO,WAAW,aAAA,EAAe;AAC/B,IAAA,OAAA,IAAW,aAAA;AACX,IAAA,QAAQ,QAAA;AAAU,MAChB,KAAK,MAAA,EAAQ;AACX,QAAA,YAAA,GAAA,CAAgB,eAAe,CAAA,IAAK,UAAA;AACpC,QAAA;AAAA,MACF;AAAA,MACA,KAAK,OAAA,EAAS;AAKZ,QAAA,IAAI,YAAA,GAAe,aAAa,CAAA,EAAG;AACjC,UAAA,YAAA,IAAgB,CAAA;AAAA,QAClB;AACA,QAAA;AAAA,MACF;AAAA;AACF,EACF;AACA,EAAA,OAAO,EAAE,cAAc,OAAA,EAAQ;AACjC;AAsBA,SAAS,aAAA,CAAc,KAAA,EAAc,MAAA,EAAsB,MAAA,EAA4B;AACrF,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,YAAA,CAAa,MAAA,EAAQ;AAAA,IACvC,SAAA,EAAW,oBAAA;AAAA,IACX,IAAA,EAAM,EAAE,MAAA;AAAO,GAChB,CAAA;AACD,EAAA,IAAI,CAAC,KAAA,CAAM,EAAA,IAAM,KAAA,CAAM,KAAA,CAAM,SAAS,2BAAA,EAA6B;AACjE,IAAA,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,oBAAA,EAAsB,EAAE,QAAQ,CAAA;AAAA,EACpD;AACF;ACvOA,SAAS,sBAAA,GAAsC;AAC7C,EAAA,2BAAW,GAAA,CAAY,CAAC,QAAA,EAAU,SAAA,EAAW,UAAU,CAAC,CAAA;AAC1D;AAIA,SAAS,UAAU,KAAA,EAAyB;AAC1C,EAAA,IACE,MAAM,OAAA,CAAQ,KAAK,CAAA,IACnB,KAAA,YAAiB,eACjB,KAAA,YAAiB,YAAA,IACjB,KAAA,YAAiB,UAAA,IACjB,iBAAiB,YAAA,IACjB,KAAA,YAAiB,cACjB,KAAA,YAAiB,UAAA,IACjB,iBAAiB,WAAA,EACjB;AACA,IAAA,OAAO,KAAA,CAAM,KAAK,KAA2B,CAAA;AAAA,EAC/C;AACA,EAAA,OAAO,KAAA;AACT;AAIA,SAAS,WAAA,CAAY,GAAY,CAAA,EAAqB;AACpD,EAAA,OAAO,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,CAAC,CAAC,MAAM,IAAA,CAAK,SAAA,CAAU,SAAA,CAAU,CAAC,CAAC,CAAA;AACrE;AAKA,SAAS,cAAA,CACP,MACA,SAAA,EACyB;AACzB,EAAA,MAAM,MAAA,GAAS,qBAAA,CAAsB,IAAA,EAAM,SAAA,IAAa,EAAE,CAAA;AAC1D,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,IAAI,CAAA,CAAE,MAAA;AACzC,EAAA,KAAA,MAAW,aAAa,MAAA,CAAO,IAAA,CAAK,eAAA,CAAgB,IAAI,CAAC,CAAA,EAAG;AAC1D,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG,SAAA,EAAW;AAClC,IAAA,GAAA,CAAI,SAAS,CAAA,GAAI,MAAA,CAAO,SAAS,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,GAAA;AACT;AAOA,SAAS,UAAA,CACP,KAAA,EACA,MAAA,EACA,IAAA,EACqC;AACrC,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,IAAI,CAAA;AAClC,EAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,MAAA;AACpB,EAAA,MAAM,MAAM,GAAA,CAAI,KAAA;AAChB,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,IAAI,CAAA,CAAE,MAAA;AACzC,EAAA,MAAM,MAAA,GAAS,gBAAgB,IAAI,CAAA;AACnC,EAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,EAAG;AAC3C,IAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG,SAAA,EAAW;AAClC,IAAA,MAAM,SAAA,GAAY,OAAO,SAAS,CAAA;AAClC,IAAA,IAAI,SAAA,KAAc,QAAA,IAAY,SAAA,KAAc,eAAA,EAAiB;AAC7D,IAAA,GAAA,CAAI,SAAS,CAAA,GAAI,SAAA,CAAU,GAAA,CAAI,SAAS,CAAC,CAAA;AAAA,EAC3C;AACA,EAAA,OAAO,GAAA;AACT;AAOO,SAAS,kBAAA,CAAmB,OAAc,KAAA,EAAgD;AAC/F,EAAA,MAAM,SAAA,GAAY,kBAAA;AAAA,IAChB,KAAA;AAAA,IACA,KAAA,CAAM;AAAA,GACR;AACA,EAAA,IAAI,CAAC,SAAA,CAAU,EAAA,EAAI,OAAO,EAAC;AAC3B,EAAA,MAAM,SAAS,SAAA,CAAU,KAAA;AAGzB,EAAA,MAAM,WAAA,uBAAkB,GAAA,EAAyB;AACjD,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,QAAA,EAAU;AAClC,IAAA,WAAA,CAAY,GAAA,CAAI,IAAA,CAAK,OAAA,EAA8B,IAAI,CAAA;AAAA,EACzD;AAEA,EAAA,MAAM,WAAW,sBAAA,EAAuB;AACxC,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,UAAA,CAAW,OAAA,EAAQ;AAC5C,EAAA,MAAM,YAA6B,EAAC;AAIpC,EAAA,MAAM,UAAyC,EAAC;AAChD,EAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,GAAG,CAAA,IAAK,MAAM,eAAA,EAAiB;AACjD,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,MAAA,EAAQ,GAAwB,CAAC,CAAA;AAAA,EACjD;AACA,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,CAAC,CAAA,GAAI,CAAA,CAAE,CAAC,CAAC,CAAA;AAElC,EAAA,KAAA,MAAW,CAAC,MAAA,EAAQ,GAAG,CAAA,IAAK,OAAA,EAAS;AACnC,IAAA,MAAM,UAAA,GAAa,WAAA,CAAY,GAAA,CAAI,GAAG,CAAA;AACtC,IAAA,MAAM,WAAA,GAAe,UAAA,EAAY,UAAA,IAAc,EAAC;AAEhD,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,SAAS,CAAA,IAAK,UAAA,EAAY;AAC9C,MAAA,IAAI,QAAA,CAAS,GAAA,CAAI,QAAQ,CAAA,EAAG;AAC5B,MAAA,IAAI,mBAAA,CAAoB,SAAS,CAAA,CAAE,MAAA,CAAO,SAAA,EAAW;AACrD,MAAA,MAAM,IAAA,GAAO,SAAA;AACb,MAAA,IAAI,OAAO,IAAA,CAAK,eAAA,CAAgB,IAAI,CAAC,CAAA,CAAE,WAAW,CAAA,EAAG;AAErD,MAAA,MAAM,IAAA,GAAO,UAAA,CAAW,KAAA,EAAO,MAAA,EAAQ,IAAI,CAAA;AAC3C,MAAA,IAAI,SAAS,MAAA,EAAW;AAExB,MAAA,MAAM,SAAA,GAAY,YAAY,QAAQ,CAAA;AACtC,MAAA,IAAI,cAAc,MAAA,EAAW;AAG3B,QAAA,SAAA,CAAU,IAAA,CAAK;AAAA,UACb,OAAA,EAAS,GAAA;AAAA,UACT,IAAA,EAAM,QAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACR,CAAA;AACD,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,QAAA,GAAW,cAAA,CAAe,IAAA,EAAM,SAAS,CAAA;AAC/C,MAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,EAAG;AACzC,QAAA,IAAI,CAAC,YAAY,IAAA,CAAK,SAAS,GAAG,QAAA,CAAS,SAAS,CAAC,CAAA,EAAG;AACtD,UAAA,SAAA,CAAU,IAAA,CAAK;AAAA,YACb,OAAA,EAAS,GAAA;AAAA,YACT,IAAA,EAAM,QAAA;AAAA,YACN,KAAA,EAAO,SAAA;AAAA,YACP,KAAA,EAAO,KAAK,SAAS;AAAA,WACtB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,SAAA;AACT;;;AC9HA,SAAS,aAAa,KAAA,EAA6C;AAKjE,EAAA,OAAO,KAAA,CAAM,QAAQ,KAAK,CAAA,IAAM,YAAY,MAAA,CAAO,KAAK,CAAA,IAAK,EAAE,KAAA,YAAiB,QAAA,CAAA;AAClF;AACA,SAAS,gBAAgB,KAAA,EAAsC;AAC7D,EAAA,OAAO,KAAA,CAAM,KAAK,KAAK,CAAA;AACzB;AAUA,SAAS,oBAAoB,SAAA,EAA6D;AACxF,EAAA,IAAI,SAAA,KAAc,QAAW,OAAO,MAAA;AACpC,EAAA,IAAI,SAAA,CAAU,WAAW,SAAS,CAAA,SAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,IAAA,EAAK;AAC3E,EAAA,IAAI,SAAA,CAAU,WAAW,eAAe,CAAA,SAAU,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,KAAA,EAAM;AAClF,EAAA,OAAO,MAAA;AACT;AAWA,SAAS,aAAA,CACP,KAAA,EACA,QAAA,EACA,MAAA,EACA,KAAA,EACkE;AAClE,EAAA,IAAI,MAAA,KAAW,CAAA,EAAG,OAAOA,IAAAA,CAAG,MAAS,CAAA;AACrC,EAAA,MAAM,WAAA,GAAc,gBAAgB,MAA6C,CAAA;AACjF,EAAA,IAAI,WAAA,KAAgB,MAAA,EAAW,OAAOA,IAAAA,CAAG,WAAW,CAAA;AACpD,EAAA,MAAM,QAAA,GAAWG,kBAAAA,CAAmB,KAAA,EAAO,MAA6C,CAAA;AACxF,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI,OAAOF,MAAI,IAAI,oCAAA,CAAqC,KAAA,EAAO,MAAM,CAAC,CAAA;AACpF,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,MAAA,CAAO,QAAA,CAAS,KAAc,CAAA;AACpD,EAAA,IAAI,IAAA,KAAS,QAAW,OAAOA,KAAAA,CAAI,IAAI,oCAAA,CAAqC,KAAA,EAAO,MAAM,CAAC,CAAA;AAC1F,EAAA,OAAOD,KAAG,IAAI,CAAA;AAChB;AAOA,SAAS,0BAAA,CACP,KAAA,EACA,QAAA,EACA,cAAA,EACA,OACA,KAAA,EACuD;AACvD,EAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,EAAU,OAAOA,KAAG,KAAK,CAAA;AAC9C,IAAA,OAAO,aAAA,CAAc,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,KAAK,CAAA;AAAA,EACpD;AACA,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAOA,KAAG,KAAK,CAAA;AAC1C,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAiC;AAClD,IAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC5B,MAAA,MAAA,CAAO,KAAK,IAAc,CAAA;AAC1B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAA,GAAI,aAAA,CAAc,KAAA,EAAO,QAAA,EAAU,MAAM,KAAK,CAAA;AACpD,IAAA,IAAI,CAAC,CAAA,CAAE,EAAA,EAAI,OAAO,CAAA;AAClB,IAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,KAAA,IAAS,CAAC,CAAA;AAAA,EAC1B;AACA,EAAA,OAAOA,KAAG,MAAM,CAAA;AAClB;AAQA,SAAS,8BAAA,CACP,KAAA,EACA,QAAA,EACA,EAAA,EACuD;AACvD,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,GAAG,IAAI,CAAA;AAC7C,EAAA,MAAM,MAAA,GAAS,IAAA,KAAS,MAAA,GAAY,MAAA,GAAaI,gBAAgB,IAAI,CAAA;AACrE,EAAA,IAAI,EAAA,CAAG,UAAU,MAAA,EAAW;AAC1B,IAAA,MAAM,iBAAiB,MAAA,GAAS,mBAAA,CAAoB,OAAO,EAAA,CAAG,KAAK,CAAC,CAAA,GAAI,MAAA;AACxE,IAAA,IAAI,CAAC,kBAAkB,cAAA,CAAe,IAAA,KAAS,UAAU,OAAOJ,IAAAA,CAAG,GAAG,KAAK,CAAA;AAC3E,IAAA,MAAM,IAAA,GAAO,2BAA2B,KAAA,EAAO,QAAA,EAAU,gBAAgB,EAAA,CAAG,KAAA,EAAO,GAAG,KAAK,CAAA;AAC3F,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA;AAGrB,IAAA,OAAOA,IAAAA,CAAG,IAAA,CAAK,KAAA,IAAS,CAAC,CAAA;AAAA,EAC3B;AAEA,EAAA,IAAI,OAAO,EAAA,CAAG,KAAA,KAAU,QAAA,IAAY,EAAA,CAAG,KAAA,KAAU,IAAA,IAAQ,KAAA,CAAM,OAAA,CAAQ,EAAA,CAAG,KAAK,CAAA,EAAG;AAChF,IAAA,OAAOA,IAAAA,CAAG,GAAG,KAAK,CAAA;AAAA,EACpB;AACA,EAAA,MAAM,MAAM,EAAA,CAAG,KAAA;AACf,EAAA,MAAM,MAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,SAAA,IAAa,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,EAAG;AACxC,IAAA,MAAM,iBAAiB,MAAA,GAAS,mBAAA,CAAoB,MAAA,CAAO,SAAS,CAAC,CAAA,GAAI,MAAA;AACzE,IAAA,IAAI,CAAC,cAAA,IAAkB,cAAA,CAAe,IAAA,KAAS,QAAA,EAAU;AACvD,MAAA,GAAA,CAAI,SAAS,CAAA,GAAI,GAAA,CAAI,SAAS,CAAA;AAC9B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAO,0BAAA;AAAA,MACX,KAAA;AAAA,MACA,QAAA;AAAA,MACA,cAAA;AAAA,MACA,IAAI,SAAS,CAAA;AAAA,MACb;AAAA,KACF;AACA,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA;AACrB,IAAA,IAAI,cAAA,CAAe,MAAA,IAAU,IAAA,CAAK,KAAA,KAAU,MAAA,EAAW;AACvD,IAAA,GAAA,CAAI,SAAS,IAAI,IAAA,CAAK,KAAA;AAAA,EACxB;AACA,EAAA,OAAOA,KAAG,GAAG,CAAA;AACf;AAGO,SAAS,yBAAA,CACd,UAAA,EACA,UAAA,EACA,IAAA,EACuE;AACvE,EAAA,MAAM,YAAA,GAAe,qBAAA,CAAsB,UAAA,EAAY,CAAC,aAAA,KAAkB;AACxE,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,aAAa,CAAA;AAC9C,IAAA,OAAO,SAAA,KAAc,MAAA,GAAY,MAAA,GAAYI,eAAAA,CAAgB,SAAS,CAAA;AAAA,EACxE,CAAC,CAAA;AACD,EAAA,IAAI,CAAC,aAAa,EAAA,EAAI;AACpB,IAAA,MAAM,KAAA,GAAQ,aAAa,KAAA,CAAM,KAAA;AACjC,IAAA,OAAOH,KAAAA;AAAA,MACL,IAAI,oCAAA;AAAA,QACF,aAAa,KAAA,CAAM,KAAA;AAAA,QACnB,OAAO,UAAU,QAAA,IAAY,OAAO,UAAU,QAAA,GAAW,KAAA,GAAQ,OAAO,KAAK;AAAA;AAC/E,KACF;AAAA,EACF;AACA,EAAA,OAAOD,IAAAA,CAAG;AAAA,IACR,aAAA,EAAe,OAAA;AAAA,IACf,IAAA,EAAM,uBAAA;AAAA,IACN,MAAA,EAAQ;AAAA,MACN;AAAA,QACE,IAAA,EAAM,IAAA,IAAQ,MAAA,CAAO,UAAA,EAAW;AAAA,QAChC,IAAA,EAAM,OAAA;AAAA,QACN,OAAA,EAAS,aAAa,KAAA,CAAM,OAAA;AAAA,QAC5B,IAAA,EAAM,aAAa,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,SAAA,KAAc,UAAU,IAAI,CAAA;AAAA,QAC/D,WAAW;AAAC;AACd;AACF,GACD,CAAA;AACH;AAcO,SAAS,iBAAA,CACd,QAAA,EACA,KAAA,EACA,KAAA,EAIA;AACA,EAAA,MAAM,cAAA,GAAiB,qBAAA;AAEvB,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAChC,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,cAAA,CAAe,KAAA,EAAO,MAAM,OAAO,CAAA;AAC7D,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,CAAA,EAAG,OAAOA,IAAAA,CAAG,EAAE,IAAA,EAAM,OAAA,EAAS,QAAA,EAAU,EAAC,EAAG,CAAA;AAEjE,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAY;AACnC,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,UAAA,CAAW,GAAA,CAAI,CAAW,CAAA;AAGjD,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AACvC,EAAA,KAAA,MAAW,MAAM,OAAA,EAAS;AACxB,IAAA,IAAI,KAAA,CAAM,IAAI,EAAA,EAAoB,aAAa,EAAE,EAAA,EAAI,cAAA,CAAe,IAAI,EAAE,CAAA;AAAA,EAC5E;AASA,EAAA,MAAM,aAAA,GAAgB,CAAC,GAAG,cAAc,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AAG9D,EAAA,MAAM,cAAA,uBAAqB,GAAA,EAAY;AACvC,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAA0D;AACnF,EAAA,KAAA,MAAW,MAAM,aAAA,EAAe;AAC9B,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,0BAAA,CAA2B,KAAA,EAAO,EAAkB,CAAA;AAC/D,IAAA,IAAI,CAAC,GAAG,EAAA,EAAI;AACZ,IAAA,KAAA,MAAW,CAAC,EAAA,EAAI,GAAG,CAAA,IAAK,EAAA,CAAG,MAAM,eAAA,EAAiB;AAChD,MAAA,MAAM,EAAA,GAAK,EAAA;AACX,MAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,IAAK,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,IAAK,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,EAAG;AACzE,QAAA,cAAA,CAAe,IAAI,EAAE,CAAA;AACrB,QAAA,YAAA,CAAa,IAAI,EAAA,EAAI,EAAE,WAAW,EAAA,EAAI,aAAA,EAAe,KAA0B,CAAA;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAC/B,IAAA,IAAI,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,IAAK,CAAC,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG,cAAA,CAAe,MAAA,CAAO,EAAE,CAAA;AAAA,EAC7E;AAwBA,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AACrD,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,UAAU,CAAA;AACvD,EAAA,MAAM,cAAA,uBAAqB,GAAA,CAAI,CAAC,aAAa,UAAA,EAAY,SAAA,EAAW,QAAQ,CAAC,CAAA;AAC7E,EAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAoB;AACjD,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,EAAA,MAAM,cAAA,GAAiB,CAAC,CAAA,EAAW,SAAA,KAA+B;AAChE,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,EAAG,OAAO,KAAA;AAC9B,IAAA,IAAI,cAAA,CAAe,IAAI,CAAC,CAAA,IAAK,eAAe,GAAA,CAAI,CAAC,GAAG,OAAO,KAAA;AAC3D,IAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAC,GAAG,OAAO,KAAA;AAC5B,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,SAAS,KAAK,KAAA,CAAM,UAAA,CAAW,SAAQ,EAAG;AAC9D,MAAA,IAAI,cAAA,CAAe,GAAA,CAAI,QAAQ,CAAA,EAAG;AAClC,MAAA,IAAI,MAAM,GAAA,CAAI,CAAA,EAAmB,SAAiC,CAAA,CAAE,IAAI,OAAO,KAAA;AAAA,IACjF;AACA,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,CAAA,EAAmB,WAAmC,CAAA;AAC3E,MAAA,IAAI,GAAG,EAAA,EAAI;AACT,QAAA,MAAM,IAAA,GAAQ,GAAG,KAAA,CAA2C,QAAA;AAC5D,QAAA,IAAI,IAAA,EAAM;AACR,UAAA,IAAI,eAAA,GAAkB,CAAA;AACtB,UAAA,IAAI,SAAA,GAAY,KAAA;AAChB,UAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,YAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,YAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,EAAG;AACrB,YAAA,eAAA,IAAmB,CAAA;AACnB,YAAA,IAAI,CAAA,KAAM,WAAW,SAAA,GAAY,IAAA;AAAA,UACnC;AACA,UAAA,IAAI,CAAC,SAAA,IAAa,eAAA,KAAoB,CAAA,EAAG,OAAO,KAAA;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA;AACA,EAAA,IAAI,UAAA,EAAY;AAGd,IAAA,KAAA,MAAW,aAAa,aAAA,EAAe;AACrC,MAAA,IAAI,CAAC,cAAA,CAAe,GAAA,CAAI,SAAS,CAAA,EAAG;AACpC,MAAA,IAAI,UAAA,CAAW,GAAA,CAAI,SAAS,CAAA,EAAG;AAC/B,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,SAAA,EAA2B,UAAkC,CAAA;AAClF,MAAA,IAAI,CAAC,GAAG,EAAA,EAAI;AACZ,MAAA,MAAM,IAAA,GAAQ,GAAG,KAAA,CAAkC,MAAA;AACnD,MAAA,IAAI,SAAS,MAAA,EAAW;AACxB,MAAA,IAAI,CAAC,gBAAgB,GAAA,CAAI,IAAI,KAAK,cAAA,CAAe,IAAA,EAAM,SAAS,CAAA,EAAG;AACjE,QAAA,gBAAA,CAAiB,GAAA,CAAI,WAAW,IAAI,CAAA;AACpC,QAAA,eAAA,CAAgB,GAAA,CAAI,MAAM,SAAS,CAAA;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,eAAA,GAAkB,CAAC,GAAG,OAAO,CAAA;AACnC,EAAA,MAAM,gBAA0B,EAAC;AACjC,EAAA,KAAA,MAAW,MAAM,eAAA,EAAiB;AAChC,IAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,EAAE,CAAA,EAAG;AAC7B,IAAA,IAAA,CAAK,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,IAAK,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,KAAM,CAAC,cAAA,CAAe,GAAA,CAAI,EAAE,CAAA,EAAG;AAC9E,MAAA,aAAA,CAAc,KAAK,EAAE,CAAA;AAAA,IACvB;AAAA,EACF;AAEA,EAAA,MAAM,eAAA,uBAAsB,GAAA,EAAoB;AAChD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,CAAc,QAAQ,CAAA,EAAA,EAAK;AAC7C,IAAA,MAAM,CAAA,GAAI,cAAc,CAAC,CAAA;AACzB,IAAA,IAAI,CAAA,KAAM,MAAA,EAAW,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAC,CAAA;AAAA,EAC/C;AAGA,EAAA,MAAM,iBAAuF,EAAC;AAC9F,EAAA,KAAA,MAAW,MAAM,cAAA,EAAgB;AAC/B,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,EAAG;AACxB,IAAA,MAAM,EAAA,GAAK,6BAAA,CAA8B,KAAA,EAAO,EAAkB,CAAA;AAClE,IAAA,IAAI,CAAC,EAAA,CAAG,EAAA;AACN,MAAA,OAAOC,KAAAA;AAAA,QACL,IAAI,oCAAA;AAAA,UACF,sBAAA;AAAA,UACA,EAAA,CAAG;AAAA;AACL,OACF;AACF,IAAA,MAAM,EAAA,GAAKE,kBAAAA;AAAA,MACT,KAAA;AAAA,MACA,EAAA,CAAG;AAAA,KACL;AACA,IAAA,IAAI,CAAC,EAAA,CAAG,EAAA;AACN,MAAA,OAAOF,KAAAA;AAAA,QACL,IAAI,oCAAA;AAAA,UACF,sBAAA;AAAA,UACA,EAAA,CAAG;AAAA;AACL,OACF;AACF,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,MAAA,CAAO,EAAA,CAAG,KAAc,CAAA;AAC3C,IAAA,IAAI,CAAA,KAAM,MAAA;AACR,MAAA,OAAOA,KAAAA;AAAA,QACL,IAAI,oCAAA;AAAA,UACF,sBAAA;AAAA,UACA,EAAA,CAAG;AAAA;AACL,OACF;AACF,IAAA,MAAM,EAAA,GAAK,0BAAA,CAA2B,KAAA,EAAO,EAAkB,CAAA;AAC/D,IAAA,IAAI,CAAC,EAAA,CAAG,EAAA;AACN,MAAA,OAAOA,KAAAA,CAAI,IAAI,oCAAA,CAAqC,sBAAA,EAAwB,OAAO,CAAC,CAAA;AACtF,IAAA,cAAA,CAAe,IAAA,CAAK,EAAE,SAAA,EAAW,EAAA,EAAI,UAAA,EAAY,GAAG,UAAA,EAAY,EAAA,CAAG,KAAA,CAAM,UAAA,EAAY,CAAA;AAAA,EACvF;AAGA,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AACvC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,eAAA,CAAgB,QAAQ,CAAA,EAAA,EAAK;AAC/C,IAAA,IAAI,eAAA,CAAgB,CAAC,CAAA,KAAM,MAAA,SAAkB,GAAA,CAAI,eAAA,CAAgB,CAAC,CAAA,EAAa,CAAC,CAAA;AAAA,EAClF;AACA,EAAA,cAAA,CAAe,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAA,CAAO,OAAO,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA,IAAK,MAAM,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,SAAS,KAAK,CAAA,CAAE,CAAA;AAG7F,EAAA,MAAM,aAAa,aAAA,CAAc,MAAA;AACjC,EAAA,MAAM,YAAkC,EAAC;AACzC,EAAA,IAAI,MAAA,GAAS,aAAa,cAAA,CAAe,MAAA;AACzC,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,SAAS,CAAA;AAEpD,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,WAAW,CAAA;AACxD,EAAA,KAAA,MAAW,KAAK,cAAA,EAAgB;AAK9B,IAAA,MAAM,UAAA,GAAa,gBAAA,CAAiB,GAAA,CAAI,CAAA,CAAE,SAAS,CAAA;AACnD,IAAA,MAAM,eAAA,GAAkB,cAAc,CAAA,CAAE,SAAA;AACxC,IAAA,IAAI,EAAA;AACJ,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,eAAA,EAAiC,SAAiC,CAAA;AACvF,MAAA,IAAI,GAAG,EAAA,EAAI;AACT,QAAA,MAAM,IAAA,GAAQ,GAAG,KAAA,CAAkC,MAAA;AACnD,QAAA,IAAI,SAAS,MAAA,EAAW;AACtB,UAAA,MAAM,EAAA,GAAK,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA;AACnC,UAAA,IAAI,EAAA,KAAO,QAAW,EAAA,GAAK,EAAA;AAAA,eACtB;AACH,YAAA,MAAM,EAAA,GAAK,YAAA,CAAa,GAAA,CAAI,IAAI,CAAA;AAChC,YAAA,IAAI,OAAO,MAAA,EAAW;AACpB,cAAA,MAAM,EAAA,GAAK,eAAe,SAAA,CAAU,CAAC,MAAM,CAAA,CAAE,SAAA,KAAc,GAAG,SAAS,CAAA;AACvE,cAAA,IAAI,EAAA,IAAM,CAAA,EAAG,EAAA,GAAK,UAAA,GAAa,EAAA;AAAA,YACjC;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,IAAA,IAAI,eAAA;AACJ,IAAA,IAAI,UAAA,KAAe,UAAa,WAAA,EAAa;AAC3C,MAAA,MAAM,EAAA,GAAK,KAAA,CAAM,GAAA,CAAI,UAAA,EAA4B,WAAmC,CAAA;AACpF,MAAA,IAAI,GAAG,EAAA,EAAI;AACT,QAAA,eAAA,GAAkB;AAAA,UAChB,SAAA,EAAW,EAAE,GAAI,EAAA,CAAG,KAAA;AAAkC,SACxD;AAAA,MACF;AAAA,IACF;AAOA,IAAA,MAAM,YAAA,GAAe,MAAA;AACrB,IAAA,IAAI,cAAA;AACJ,IAAA,MAAM,YAAA,GAAe,0BAAA,CAA2B,KAAA,EAAO,CAAA,CAAE,SAAyB,CAAA;AAClF,IAAA,IAAI,aAAa,EAAA,EAAI;AACnB,MAAA,MAAM,YAAA,GAAe,kBAAA,CAAmB,KAAA,EAAO,YAAA,CAAa,KAAK,CAAA;AACjE,MAAA,IAAI,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3B,QAAA,cAAA,GAAiB,EAAC;AAClB,QAAA,KAAA,MAAW,MAAM,YAAA,EAAc;AAC7B,UAAA,MAAM,OAAA,GAAU,8BAAA,CAA+B,KAAA,EAAO,QAAA,EAAU,EAAE,CAAA;AAClE,UAAA,IAAI,CAAC,OAAA,CAAQ,EAAA,EAAI,OAAO,OAAA;AACxB,UAAA,cAAA,CAAe,IAAA,CAAK;AAAA,YAClB,GAAG,EAAA;AAAA,YACH,OAAA,EAAU,eAAgB,EAAA,CAAG,OAAA;AAAA,YAC7B,OAAO,OAAA,CAAQ;AAAA,WAChB,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,MAAM,KAAA,GAA4B;AAAA,MAChC,OAAA,EAAU,aAAa,SAAA,CAAU,MAAA;AAAA,MACjC,QAAQ,CAAA,CAAE,UAAA;AAAA,MACV,WAAA,EAAa,MAAA;AAAA,MACb,aAAa,CAAA,CAAE,UAAA;AAAA,MACf,GAAI,EAAA,KAAO,MAAA,GAAY,EAAE,MAAA,EAAQ,EAAA,KAAwB,EAAC;AAAA,MAC1D,GAAI,eAAA,KAAoB,MAAA,GAAY,EAAE,UAAA,EAAY,eAAA,KAAoB,EAAC;AAAA,MACvE,GAAI,cAAA,KAAmB,MAAA,IAAa,cAAA,CAAe,MAAA,GAAS,IACxD,EAAE,SAAA,EAAW,cAAA,EAAe,GAC5B;AAAC,KACP;AACA,IAAA,SAAA,CAAU,KAAK,KAAK,CAAA;AACpB,IAAA,MAAA,IAAU,CAAA,CAAE,UAAA;AAAA,EACd;AAGA,EAAA,SAAS,MAAM,CAAA,EAA+B;AAC5C,IAAA,MAAM,EAAA,GAAK,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAA;AAChC,IAAA,IAAI,EAAA,KAAO,QAAW,OAAO,EAAA;AAI7B,IAAA,MAAM,cAAA,GAAiB,eAAA,CAAgB,GAAA,CAAI,CAAC,CAAA;AAC5C,IAAA,IAAI,mBAAmB,MAAA,EAAW;AAChC,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,cAAA,CAAe,QAAQ,CAAA,EAAA,EAAK;AAC9C,QAAA,IAAI,eAAe,CAAC,CAAA,EAAG,SAAA,KAAc,cAAA,SAAuB,UAAA,GAAa,CAAA;AAAA,MAC3E;AAAA,IACF;AACA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,cAAA,CAAe,QAAQ,CAAA,EAAA,EAAK;AAC9C,MAAA,IAAI,eAAe,CAAC,CAAA,EAAG,SAAA,KAAc,CAAA,SAAU,UAAA,GAAa,CAAA;AAAA,IAC9D;AACA,IAAA,MAAM,EAAA,GAAK,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA;AAC7B,IAAA,IAAI,OAAO,MAAA,EAAW;AACpB,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,cAAA,CAAe,QAAQ,CAAA,EAAA,EAAK;AAC9C,QAAA,IAAI,cAAA,CAAe,CAAC,CAAA,EAAG,SAAA,KAAc,GAAG,SAAA,EAAW;AACjD,UAAA,IAAI,EAAA,GAAK,aAAa,cAAA,CAAe,MAAA;AACrC,UAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,GAAI,CAAA,EAAG,KAAK,EAAA,IAAM,cAAA,CAAe,CAAC,CAAA,EAAG,UAAA,IAAc,CAAA;AACnE,UAAA,OAAO,KAAK,EAAA,CAAG,aAAA;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,MAAA;AAAA,EACT;AAGA,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,UAAA,CAAW,OAAA,EAAQ;AACjD,EAAA,MAAM,WAA0B,EAAC;AAEjC,EAAA,KAAA,IAAS,GAAA,GAAM,CAAA,EAAG,GAAA,GAAM,aAAA,CAAc,QAAQ,GAAA,EAAA,EAAO;AACnD,IAAA,MAAM,SAAA,GAAY,cAAc,GAAG,CAAA;AACnC,IAAA,IAAI,cAAc,MAAA,EAAW;AAC7B,IAAA,MAAM,MAAA,GAAS,SAAA;AACf,IAAA,MAAM,aAAsD,EAAC;AAC7D,IAAA,MAAM,MAAA,GAAS,UAAA,CAAW,GAAA,CAAI,SAAS,CAAA;AAEvC,IAAA,KAAA,MAAW,CAAC,QAAA,EAAU,SAAS,CAAA,IAAK,eAAA,EAAiB;AACnD,MAAA,IACE,CAAC,cAAA,CAAe,gBAAA;AAAA,QACd,QAAA;AAAA,QACAI,mBAAAA,CAAoB,SAAS,CAAA,CAAE,MAAA,CAAO,SAAA,KAAc;AAAA,OACtD;AAEA,QAAA;AACF,MAAA,IAAI,MAAA,IAAU,aAAa,SAAA,EAAW;AAEtC,MAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,SAAiC,CAAA;AAClE,MAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AAEhB,MAAA,MAAM,MAAM,MAAA,CAAO,KAAA;AACnB,MAAA,MAAM,IAAA,GAAO,SAAA;AACb,MAAA,IAAI,SAAS,MAAA,EAAW;AAExB,MAAA,MAAM,MAAA,GAASD,gBAAgB,IAAI,CAAA;AACnC,MAAA,MAAM,UAAA,GAAa,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAKrC,MAAA,IAAI,UAAA,CAAW,WAAW,CAAA,EAAG;AAC3B,QAAA,UAAA,CAAW,QAAQ,IAAI,EAAC;AACxB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,cAAuC,EAAC;AAE9C,MAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,QAAA,MAAM,QAAA,GAAW,IAAI,SAAS,CAAA;AAC9B,QAAA,IAAI,aAAa,MAAA,EAAW;AAM5B,QAAA,IACE,CAAC,cAAA,CAAe,YAAA;AAAA,UACd,QAAA;AAAA,UACA,SAAA;AAAA,UACAC,oBAAoB,IAAI,CAAA,CAAE,MAAA,CAAO,SAAS,GAAG,SAAA,KAAc;AAAA,SAC7D;AAEA,UAAA;AAEF,QAAA,MAAM,eAAA,GAAkB,OAAO,SAAS,CAAA;AACxC,QAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,IAAA,EAAsB,SAAS,CAAA;AACtE,QAAA,MAAM,WAAA,GACJ,eAAA,KAAoB,MAAA,GAAY,mBAAA,CAAoB,eAAe,CAAA,GAAI,MAAA;AAEzE,QAAA,IAAI,CAAC,UAAA,IAAc,CAAC,WAAA,EAAa;AAC/B,UAAA,IAAI,YAAA,CAAa,QAAQ,CAAA,EAAG;AAC1B,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,eAAA,CAAgB,QAAQ,CAAA;AAAA,UACnD,CAAA,MAAO;AACL,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,QAAA;AAAA,UAC3B;AACA,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,eAAe,IAAA,EAAM;AAEvB,UAAA,IAAI,WAAW,OAAA,EAAS;AACtB,YAAA,MAAM,MAAM,YAAA,CAAa,QAAQ,CAAA,GAC7B,eAAA,CAAgB,QAAQ,CAAA,GACvB,QAAA;AACL,YAAA,MAAM,SAAmB,EAAC;AAC1B,YAAA,KAAA,MAAW,QAAQ,GAAA,EAAK;AACtB,cAAA,MAAM,IAAA,GAAO,MAAM,IAAc,CAAA;AACjC,cAAA,IAAI,SAAS,MAAA,EAAW;AACtB,gBAAA,OAAOJ,KAAAA;AAAA,kBACL,IAAI,sCAAA,CAAuC,SAAA,EAAW,SAAA,EAAW,IAAc;AAAA,iBACjF;AAAA,cACF;AACA,cAAA,MAAA,CAAO,KAAK,IAAI,CAAA;AAAA,YAClB;AACA,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,MAAA;AAAA,UAC3B,CAAA,MAAO;AAIL,YAAA,IAAI,aAAa,IAAA,EAAM;AACvB,YAAA,MAAM,IAAA,GAAO,MAAM,QAAkB,CAAA;AACrC,YAAA,IAAI,SAAS,MAAA,EAAW;AACtB,cAAA,OAAOA,KAAAA;AAAA,gBACL,IAAI,sCAAA;AAAA,kBACF,SAAA;AAAA,kBACA,SAAA;AAAA,kBACA;AAAA;AACF,eACF;AAAA,YACF;AACA,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,IAAA;AAAA,UAC3B;AAAA,QACF,CAAA,MAAO;AASL,UAAA,MAAM,aAAa,YAAA,CAAa,QAAQ,CAAA,GAAI,eAAA,CAAgB,QAAQ,CAAA,GAAI,QAAA;AACxE,UAAA,IAAI,gBAAgB,MAAA,EAAW;AAE7B,YAAA,WAAA,CAAY,SAAS,CAAA,GAAI,UAAA;AACzB,YAAA;AAAA,UACF;AACA,UAAA,MAAM,IAAA,GAAO,0BAAA;AAAA,YACX,KAAA;AAAA,YACA,QAAA;AAAA,YACA,WAAA;AAAA,YACA,UAAA;AAAA,YACA;AAAA,WACF;AACA,UAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA;AACrB,UAAA,IAAI,WAAA,CAAY,MAAA,IAAU,IAAA,CAAK,KAAA,KAAU,MAAA,EAAW;AACpD,UAAA,WAAA,CAAY,SAAS,IAAI,IAAA,CAAK,KAAA;AAAA,QAChC;AAAA,MACF;AAEA,MAAA,IAAI,MAAA,CAAO,KAAK,WAAW,CAAA,CAAE,SAAS,CAAA,EAAG,UAAA,CAAW,QAAQ,CAAA,GAAI,WAAA;AAAA,IAClE;AAEA,IAAA,QAAA,CAAS,IAAA,CAAK,EAAE,OAAA,EAAS,GAAA,EAAsB,YAA2B,CAAA;AAAA,EAC5E;AAEA,EAAA,OAAOD,IAAAA,CAAG;AAAA,IACR,IAAA,EAAM,OAAA;AAAA,IACN,QAAA;AAAA,IACA,GAAI,UAAU,MAAA,GAAS,CAAA,GAAI,EAAE,MAAA,EAAQ,SAAA,KAAc;AAAC,GACrD,CAAA;AACH","file":"index.mjs","sourcesContent":["import {\n type AssetDecoderContribution,\n type AssetKind,\n type AudioClipAsset,\n err,\n ok,\n} from '@forgeax/engine-types';\n\nexport const audioContribution: AssetDecoderContribution<AudioClipAsset, 'audio'> = {\n kind: { kind: 'audio' } as AssetKind<AudioClipAsset, 'audio'>,\n consumer: 'AudioBackend',\n decoder: {\n async decode({ envelope, artifacts }) {\n const payload = envelope.payload as unknown;\n if (payload !== null && typeof payload === 'object') {\n const source = payload as Record<string, unknown>;\n let bytes =\n source.bytes instanceof Uint8Array\n ? source.bytes\n : Array.isArray(source.bytes)\n ? Uint8Array.from(source.bytes as number[])\n : undefined;\n const body = envelope.artifacts.body ?? envelope.artifacts.source;\n if (body !== undefined) {\n const bodyBytes = await artifacts.read(body);\n if (!bodyBytes.ok) return bodyBytes;\n bytes = bodyBytes.value;\n }\n if (\n source.kind === 'audio' &&\n typeof source.mediaType === 'string' &&\n source.mediaType.startsWith('audio/') &&\n bytes !== undefined &&\n bytes.byteLength > 0\n ) {\n return ok({\n kind: 'audio',\n sourceKey:\n typeof source.sourceKey === 'string' && source.sourceKey.length > 0\n ? source.sourceKey\n : envelope.guid,\n mediaType: source.mediaType as `audio/${string}`,\n bytes,\n });\n }\n }\n return err({\n code: 'asset-package-invalid',\n expected: 'an audio payload with non-empty source bytes and audio mediaType',\n hint: 'recook the audio source with a browser-supported media type',\n detail: { guid: envelope.guid, reason: 'audio owner validation failed' },\n });\n },\n },\n};\n","// @forgeax/engine-audio -- AudioSource + AudioListener ECS components (feat-20260527-audio-system M1 / w9)\n//\n// Decision anchors:\n// - requirements S-3 (AudioSource single-component surface, 6 fields)\n// - requirements S-4 (AudioListener independent marker component)\n// - plan-strategy D-4 (edge-detection tick system; AudioSource.playing drives play/stop edges)\n// - plan-strategy D-5 (AudioSource.bus defaults to 'sfx'; BusName is 'sfx' | 'music')\n// - plan-strategy section 3.1 (6-field AudioSource + marker AudioListener)\n// - charter P1 (progressive disclosure: 3-symbol core surface)\n// - charter P4 (consistent abstraction: same defineComponent pattern as Transform/Camera)\n\nimport { defineComponent } from '@forgeax/engine-ecs';\n\nexport const AudioSource = defineComponent('AudioSource', {\n clip: { type: 'shared<AudioClipAsset>' },\n playing: { type: 'bool', default: false },\n loop: { type: 'bool', default: false },\n volume: { type: 'f32', default: 1.0 },\n spatialBlend: { type: 'f32', default: 0 },\n bus: { type: 'string', default: 'sfx' },\n});\n\nexport const AudioListener = defineComponent('AudioListener', {});\n","import { animationClipContribution, animationGraphContribution } from '@forgeax/engine-animation';\nimport { audioContribution } from '@forgeax/engine-audio';\nimport { fontContribution } from '@forgeax/engine-font';\nimport { meshAssetContribution } from '@forgeax/engine-geometry';\nimport { tilesetContribution, videoContribution } from '@forgeax/engine-graphics-extras';\nimport { equirectContribution, textureContribution } from '@forgeax/engine-image';\nimport {\n materialContribution,\n renderPipelineContribution,\n samplerContribution,\n} from '@forgeax/engine-render';\nimport { sceneAssetContribution } from '@forgeax/engine-scene';\nimport { skeletonContribution, skinContribution } from '@forgeax/engine-skinning';\nimport type { AssetDecoderContributionRef } from '@forgeax/engine-types';\nimport { particleEffectContribution } from '@forgeax/engine-vfx';\n\n/**\n * The built-in decoder set assembled by the host/runtime boundary.\n *\n * Each entry remains owned by its domain package; this list is only the one\n * default lease assembly for an App realm. A caller-provided contribution for\n * a built-in kind replaces that default entry for the current realm.\n */\nconst typedDefaultAssetDecoderContributions = [\n meshAssetContribution,\n materialContribution,\n sceneAssetContribution,\n textureContribution,\n equirectContribution,\n samplerContribution,\n fontContribution,\n renderPipelineContribution,\n tilesetContribution,\n videoContribution,\n skeletonContribution,\n skinContribution,\n animationClipContribution,\n animationGraphContribution,\n audioContribution,\n particleEffectContribution,\n] as const;\n\n// The registry installation seam intentionally erases the payload type while\n// it stores heterogeneous owner contributions. Each owner contribution above\n// remains typed at its source and is checked again by its decoder.\nexport const defaultAssetDecoderContributions = Object.freeze(\n typedDefaultAssetDecoderContributions as unknown as readonly AssetDecoderContributionRef[],\n);\n","import type { RendererOptions } from '@forgeax/engine-render';\nimport type { RhiBackendPack } from '@forgeax/engine-render/internal/construct-renderer';\nimport { err, ok, RhiError } from '@forgeax/engine-rhi';\nimport * as rhiWebgpu from '@forgeax/engine-rhi-webgpu';\n\nexport function loadRhiPack(\n mod: Record<string, unknown>,\n instrumentation?: RhiBackendPack['instrumentation'],\n): RhiBackendPack {\n const rhi = mod.rhi as unknown as RhiBackendPack['rhi'];\n const createShaderModule = mod.createShaderModule as\n | RhiBackendPack['createShaderModule']\n | undefined;\n const createShaderModuleImmediate = mod.createShaderModuleImmediate as\n | RhiBackendPack['createShaderModuleImmediate']\n | undefined;\n const translateErrorEventToRhiError = mod.translateErrorEventToRhiError as\n | RhiBackendPack['translateErrorEventToRhiError']\n | undefined;\n const rawDeviceAccessor = mod._internal_getRawDevice as unknown as\n | RhiBackendPack['_internal_getRawDevice']\n | undefined;\n const backendInstrumentation = mod.instrumentation as\n | RhiBackendPack['instrumentation']\n | undefined;\n const pack: RhiBackendPack = {\n rhi,\n ...(createShaderModule === undefined ? {} : { createShaderModule }),\n ...(createShaderModuleImmediate === undefined ? {} : { createShaderModuleImmediate }),\n ...(translateErrorEventToRhiError === undefined ? {} : { translateErrorEventToRhiError }),\n ...(rawDeviceAccessor === undefined ? {} : { _internal_getRawDevice: rawDeviceAccessor }),\n };\n const resolvedInstrumentation = instrumentation ?? backendInstrumentation;\n return resolvedInstrumentation === undefined\n ? pack\n : { ...pack, instrumentation: resolvedInstrumentation };\n}\n\n/** Selects one backend pack; render receives only this typed owner contract. */\nexport async function loadBackendPack(\n options: RendererOptions | undefined,\n preferWgpu = false,\n): Promise<\n | { readonly ok: true; readonly value: RhiBackendPack }\n | { readonly ok: false; readonly error: RhiError }\n> {\n const explicit = options?.rhi;\n if (explicit !== undefined && explicit !== null) {\n return ok(loadRhiPack({ rhi: explicit, ...(explicit as object) }, options?.rhiInstrumentation));\n }\n const nav =\n typeof globalThis === 'undefined'\n ? undefined\n : (globalThis as { navigator?: { gpu?: unknown } }).navigator;\n if (!preferWgpu && nav?.gpu !== undefined && nav.gpu !== null) {\n return ok(\n loadRhiPack(rhiWebgpu as unknown as Record<string, unknown>, options?.rhiInstrumentation),\n );\n }\n try {\n const mod = (await import('@forgeax/engine-rhi-wgpu')) as Record<string, unknown>;\n await (mod.ensureReady as () => Promise<unknown>)();\n return ok(loadRhiPack(mod, options?.rhiInstrumentation));\n } catch (cause) {\n return err(\n new RhiError({\n code: 'rhi-not-available',\n expected: 'a usable RHI backend is available',\n hint: `failed to load wgpu backend: ${String(cause)}`,\n }),\n );\n }\n}\n","import type { AssetRegistry } from '@forgeax/engine-assets-runtime';\nimport type { RenderError, RendererOptions, RenderResult } from '@forgeax/engine-render';\nimport type {\n BundlerOptions,\n RendererHostAssembly,\n} from '@forgeax/engine-render/internal/construct-renderer';\nimport {\n constructRendererHost,\n EngineEnvironmentError,\n} from '@forgeax/engine-render/internal/construct-renderer';\nimport { loadBackendPack } from './backend-selection';\n\nexport type {\n BundlerOptions,\n RendererHostAssembly,\n} from '@forgeax/engine-render/internal/construct-renderer';\n\nconst FALLBACK_ERROR_CODES = new Set([\n 'adapter-unavailable',\n 'request-adapter-threw',\n 'feature-not-enabled',\n 'limit-exceeded',\n 'rhi-not-available',\n 'device-lost',\n 'oom',\n]);\n\nfunction canFallbackToWgpu(error: unknown): boolean {\n if (!(error instanceof EngineEnvironmentError)) return false;\n const webgpuError = error.detail.webgpuError;\n if (webgpuError === undefined || typeof webgpuError !== 'object') return false;\n if (!('code' in webgpuError)) return false;\n const code = webgpuError.code;\n return typeof code === 'string' && FALLBACK_ERROR_CODES.has(code);\n}\n\n/** Assemble renderer plus asset services in the Runtime-owned backend host. */\nexport async function constructRuntimeRendererHost(\n canvas: unknown,\n options?: RendererOptions,\n bundler?: BundlerOptions,\n): Promise<RenderResult<RendererHostAssembly, RenderError | EngineEnvironmentError>> {\n const first = await loadBackendPack(options);\n if (!first.ok) throw first.error;\n const constructed = await constructRendererHost(canvas, options, bundler, first.value);\n if (\n constructed.ok ||\n options?.rhi !== undefined ||\n typeof globalThis === 'undefined' ||\n !canFallbackToWgpu(constructed.error)\n ) {\n return constructed;\n }\n const fallback = await loadBackendPack(options, true);\n if (!fallback.ok) return constructed;\n return constructRendererHost(canvas, options, bundler, fallback.value);\n}\n\nexport { loadRhiPack } from './backend-selection';\nexport type { AssetRegistry };\n","// Runtime is the host assembly facade. Concrete Renderer construction and\n// frame interpretation live in the render owner assembly.\nimport type { RenderError, Renderer, RendererOptions } from '@forgeax/engine-render';\nimport type { BundlerOptions } from '@forgeax/engine-render/internal/construct-renderer';\nimport { err, ok, type Result } from '@forgeax/engine-types';\nimport { EngineEnvironmentError } from './errors/environment';\nimport { constructRuntimeRendererHost } from './renderer-host';\n\n/**\n * Assemble the sole public renderer host.\n *\n * Runtime owns backend selection and partial-construction cleanup. Render owns\n * the scene/frame contract; successful construction returns the host that\n * exposes attach, draw, inspect, observe, and recover. Expected failures are\n * structured Result errors at the owning boundary; environment failures retain\n * EngineEnvironmentError recovery guidance for the caller.\n */\nexport async function createRenderer(\n canvas: HTMLCanvasElement | OffscreenCanvas,\n options?: RendererOptions,\n bundler?: BundlerOptions,\n): Promise<Result<Renderer, EngineEnvironmentError | RenderError>> {\n if (options !== undefined && 'rhi' in options && options.rhi === undefined) {\n return err(new EngineEnvironmentError('no usable rendering backend'));\n }\n const rendererOptions: RendererOptions | undefined =\n options === undefined\n ? undefined\n : {\n ...(options.rhi === undefined ? {} : { rhi: options.rhi }),\n ...(options.features === undefined ? {} : { features: options.features }),\n ...(options.profiler === undefined ? {} : { profiler: options.profiler }),\n ...(options.captureGpuTimings === undefined\n ? {}\n : { captureGpuTimings: options.captureGpuTimings }),\n ...(options.rhiInstrumentation === undefined\n ? {}\n : { rhiInstrumentation: options.rhiInstrumentation }),\n ...(options.standardProfile === undefined\n ? {}\n : { standardProfile: options.standardProfile }),\n ...(options.gpuPassTiming === undefined ? {} : { gpuPassTiming: options.gpuPassTiming }),\n };\n try {\n const constructed = await constructRuntimeRendererHost(canvas, rendererOptions, bundler);\n if (!constructed.ok) return err(constructed.error);\n return ok(constructed.value.renderer);\n } catch (cause) {\n if (cause instanceof EngineEnvironmentError) return err(cause);\n const detail = cause instanceof Error ? cause : new Error(String(cause));\n return err(new EngineEnvironmentError('renderer construction failed', { webgpuError: detail }));\n }\n}\n","// dev-import-transport.ts -- the dev-only ImportTransport adapter (M4 / w15,\n// AC-04). A host explicitly wires this into createRenderer / createApp so a\n// DDC miss at runtime triggers an on-demand import against the vite-plugin-pack\n// dev server (POST to the binding's scoped import endpoint). The shipped form\n// unwired so a miss fails fast with `asset-not-imported` (AC-08).\n//\n// Pure browser fetch -- no Node-only dependency (AC-04), no import.meta.env /\n// import.meta.hot / NODE_ENV probe (AC-05 / OOS-1: host-explicit assembly is\n// the only path, the library never auto-detects dev vs prod). The module also\n// never imports @forgeax/engine-image (image-pipeline-isolation: runtime/src\n// must not statically depend on the image package).\n\nimport type { ImportTransport, PackIndexEntry, RuntimeAssetBinding } from '@forgeax/engine-types';\n\nexport type DevImportTransportBinding = Pick<\n RuntimeAssetBinding,\n 'scopeId' | 'generation' | 'status' | 'importUrlBase'\n>;\n\n/**\n * Build the dev-only {@link ImportTransport}. A caller must provide the\n * current runtime binding; `fetchPack(guid)` then issues a scoped POST against\n * the vite-plugin-pack dev server, which imports\n * exactly that GUID's `.bin` and returns the single imported catalog row (+ any\n * sub-asset siblings). The caller patches those rows into its catalog cache\n * incrementally -- per-asset, never a whole-catalog re-fetch (the four-verb\n * redesign, 2026-06-06). On a non-2xx / network failure it reports\n * `{ ok: false }`.\n *\n * Aligns with the `wireDefaultLoaders` `create*` / `wire*` factory family so\n * IDE autocomplete on `@forgeax/engine-runtime` surfaces it.\n *\n * @example\n * import { createApp } from '@forgeax/engine-app';\n * import { createDevImportTransport } from '@forgeax/engine-runtime';\n * const app = await createApp(canvas, opts, {\n * importTransport: createDevImportTransport(runtimeBinding),\n * });\n */\nexport function createDevImportTransport(binding?: DevImportTransportBinding): ImportTransport {\n return {\n async fetchPack(\n guid: string,\n scope?: Pick<RuntimeAssetBinding, 'scopeId' | 'generation' | 'status'>,\n ): Promise<\n { readonly ok: true; readonly entries?: readonly PackIndexEntry[] } | { readonly ok: false }\n > {\n const active = binding;\n if (\n active === undefined ||\n active.status !== 'ready' ||\n scope === undefined ||\n scope.status !== 'ready' ||\n scope.scopeId !== active.scopeId ||\n scope.generation !== active.generation\n ) {\n return { ok: false };\n }\n try {\n const base = active.importUrlBase.replace(/\\/+$/, '');\n const response = await fetch(`${base}/${encodeURIComponent(guid)}`, { method: 'POST' });\n if (!response.ok) {\n // The ImportTransport contract has no error channel (returns only\n // ok:false), so the runtime would otherwise report a generic\n // `asset-not-imported`. Surface the dev server's structured failure\n // body (e.g. `code: fbx-mesh-type-unsupported`, reason, hint) to the\n // console so the actual cause is visible to AI/human users.\n try {\n const fail = (await response.json()) as {\n code?: string;\n reason?: string;\n hint?: string;\n };\n console.warn(\n `[forgeax] import failed for ${guid} (HTTP ${response.status}): ` +\n `${fail.code ?? 'import-failed'} - ${fail.reason ?? ''}` +\n (fail.hint ? ` | hint: ${fail.hint}` : ''),\n );\n } catch {\n // Non-JSON error body; nothing extra to surface.\n }\n return { ok: false };\n }\n try {\n const body = (await response.json()) as unknown;\n if (Array.isArray(body)) return { ok: true, entries: body as readonly PackIndexEntry[] };\n } catch {\n // Body was not JSON (or empty) -- success without inline rows; the\n // caller re-resolves the GUID from its cache.\n }\n return { ok: true };\n } catch {\n return { ok: false };\n }\n },\n };\n}\n","// @forgeax/engine-runtime - sprite-animation tick system (M4 / T-23).\n//\n// Walks every entity that carries `SpriteAnimation`, advances its dt\n// accumulator clock per Time.delta, and writes the current frame's UV slice\n// into the entity's `SpriteRegionOverride` column (auto-adding the\n// component on first observation when the entity does not yet carry it).\n// Designed to sit between `input` / `time` and `RenderSystem.extract` in\n// the schedule (plan-strategy section 2 D-7); the M3 sprite-bucket\n// extract branch (`render-system-extract.ts:861-870`) reads the override\n// column to materialise per-entity UV in the sprite snapshot.\n//\n// Why a stand-alone tick system instead of folding the dt accumulator\n// into the renderer? Charter P5 producer/consumer separation: the\n// renderer is a consumer of presentation state and never writes ECS\n// columns; the tick system owns the per-entity write so the\n// `SpriteRegionOverride.region` slot has exactly one writer (the tick\n// system) and zero readers in the writer tree (the extract branch is a\n// disjoint consumer). Plan-strategy section 1 + section 5 constraint #1\n// pin the boundary; this file is the producer half.\n//\n// Schedule positioning (informational; the App schedule is wired by the\n// host, not this file): input / time -> spriteAnimationTickSystem ->\n// RenderSystem.extract. The tick is `void`-returning under the\n// `Result<void, SpriteAnimationInvalidError>` shape so the schedule's\n// Layer-3 ErrorHandler observes a structured first-error signal without\n// the system aborting mid-pass on healthy entities (charter P3 explicit\n// failure + P4 consistent abstraction with `setTransparentSortConfig`'s\n// `Result<void, ResourceInvalidValueError>` shape).\n//\n// Invariants checked per-entity (AC-09 fail-fast paths; M1 T-05 added\n// `SpriteAnimationInvalidError`):\n// - `regions.length === frameCount * 4` -> detail.field='regions-length'\n// - `frameDuration > 0` -> detail.field='frame-duration'\n// First error wins; subsequent invalid entities still skip advance but\n// only the first surfaces in the returned Result.err. Healthy entities\n// continue to advance regardless of an invalid sibling (T-19 second\n// it() block locks this).\n//\n// Time.delta sourcing: `world.getResource(Time).delta`. When\n// the resource is missing (e.g. the tick system is invoked outside an\n// `App` rAF loop), dt defaults to 0 and the system runs as a no-op\n// schedule pass. Time.delta is already frame-loop clamped to a sane\n// ceiling by `@forgeax/engine-app frame-loop.ts`; the tick system MUST\n// NOT second-clamp (research F-3 + plan-strategy R-TIME-1). T-22 case\n// (1) feeds dt=30s directly to lock that contract.\n//\n// playbackMode dispatch: the per-entity `playbackMode: u32` column is\n// translated through `spritePlaybackModeFromU32` (M1 SSOT) into the\n// closed `'loop' | 'clamp'` literal union. The advance arm is selected\n// per-tick per-entity so AI users can mutate playbackMode at runtime\n// (e.g. swap LOOP for CLAMP on a death animation) and observe the\n// behavioural switch on the very next tick.\n//\n// Anchors: plan-strategy section 2 D-1 + D-5 + D-6 + D-7 + section 3.1\n// TICK + section 3.2 sequence diagram Tick->Ovr block + section 4 risk\n// R-TIME-1; plan-tasks.json T-23; requirements section 2.1 C system\n// surface + section AC-04 / AC-05 / AC-09 + section 7 boundary table;\n// charter P3 + P4 + P5 + F1.\n\nimport { type EntityHandle, Time, type World } from '@forgeax/engine-ecs';\nimport { SpriteAnimationInvalidError } from '@forgeax/engine-ecs/projection';\nimport {\n SpriteAnimation,\n SpriteRegionOverride,\n spritePlaybackModeFromU32,\n} from '@forgeax/engine-render/authoring';\nimport { err, ok, type Result } from '@forgeax/engine-types';\n\n/**\n * Walk every entity carrying `SpriteAnimation`, advance its dt\n * accumulator, and write the current frame's UV slice to the entity's\n * `SpriteRegionOverride` column.\n *\n * Returns `Result<void, SpriteAnimationInvalidError>`:\n *\n * - `ok(void)` when every observed entity satisfies both invariants\n * (`regions.length === frameCount * 4` and `frameDuration > 0`) — the\n * pass advanced every entity normally.\n * - `err(SpriteAnimationInvalidError)` carrying the FIRST entity-level\n * invariant violation observed during the pass. The offending entity\n * does not advance (its `currentFrame` / `accumDt` columns stay\n * untouched); every other healthy entity in the same pass still\n * advances normally so AI users observe a \"fail one, advance the\n * rest\" semantics rather than an all-or-nothing abort.\n *\n * The returned error is the canonical 4-field structured payload\n * (`.code` / `.expected` / `.hint` / `.detail`) — narrow on\n * `err.detail.field` (`'regions-length'` | `'frame-duration'`) to reach\n * the per-arm recovery hint without parsing the message string\n * (charter P3 + P4).\n *\n * @example Wire into an App schedule between input/time and the renderer:\n * ```ts\n * import { createApp } from '@forgeax/engine-app';\n * import { spriteAnimationTickSystem } from '@forgeax/engine-runtime';\n *\n * const app = createApp({ canvas, schedule: { update: [\n * spriteAnimationTickSystem,\n * // ... other systems\n * ] } });\n * ```\n *\n * @example Handle the first-error-wins surface:\n * ```ts\n * const r = spriteAnimationTickSystem(world);\n * if (!r.ok) {\n * // r.error.code === 'sprite-animation-invalid'\n * if (r.error.detail.field === 'regions-length') {\n * console.warn(`fix regions buffer length to ${r.error.detail.frameCount * 4}`);\n * }\n * }\n * ```\n */\nexport function spriteAnimationTickSystem(world: World): Result<void, SpriteAnimationInvalidError> {\n const dt = world.getResource(Time).delta;\n\n // Query filters entities carrying SpriteAnimation, so a World that never\n // spawned the component naturally yields an empty entity set (the pass is a\n // no-op).\n // Two-pass to avoid mid-iteration archetype migration. The auto-add\n // of `SpriteRegionOverride` migrates the entity into a new archetype\n // (SA + SRO) which a single-pass query would re-visit later in the same\n // pass — yielding double-advance\n // for any entity that did not yet carry the override. Collecting\n // every Entity handle first gives each entity a single tick.\n const entities = collectAnimEntities(world);\n\n let firstError: SpriteAnimationInvalidError | null = null;\n for (const entity of entities) {\n const entryError = tickEntity(world, entity, dt);\n if (entryError !== null && firstError === null) {\n firstError = entryError;\n }\n }\n\n if (firstError !== null) {\n return err(firstError);\n }\n return ok(undefined);\n}\n\n/**\n * First pass: collect every Entity handle from the ECS Query projection.\n * Handles remain valid across subsequent migrations because they are stable\n * index+generation identities, not archetype-row pointers.\n */\nfunction collectAnimEntities(world: World): EntityHandle[] {\n const queryResult = world.query({ with: [SpriteAnimation] });\n if (!queryResult.ok) return [];\n const entities: EntityHandle[] = [];\n for (const row of queryResult.value) entities.push(row.entity);\n return entities;\n}\n\n/**\n * Second pass: validate one entity's `SpriteAnimation` invariants,\n * advance its dt accumulator, and write the per-frame UV slice into\n * `SpriteRegionOverride`. Returns `null` when the entity advanced\n * normally; returns a structured `SpriteAnimationInvalidError` instance\n * when the entity's row violates an invariant (the caller stitches the\n * first such error into the system's Result.err).\n */\nfunction tickEntity(\n world: World,\n entity: EntityHandle,\n dt: number,\n): SpriteAnimationInvalidError | null {\n const snapRes = world.get(entity, SpriteAnimation);\n if (!snapRes.ok) {\n // Defensive: the alive-record check inside world.get already guards\n // stale handles; reaching here means something racier (component\n // sweep removed the column mid-pass). Skip silently — the route is\n // engine-internal, not an AI-user-visible failure mode.\n return null;\n }\n const snap = snapRes.value;\n const frameCount = snap.frameCount;\n const frameDuration = snap.frameDuration;\n const regions = snap.regions;\n\n // Invariant: regions.length === frameCount * 4 (D-1 fail-fast,\n // T-19 covers).\n if (regions.length !== frameCount * 4) {\n return new SpriteAnimationInvalidError({\n field: 'regions-length',\n regionsLength: regions.length,\n frameCount,\n });\n }\n // Invariant: frameDuration > 0 (covers both === 0 and < 0; T-20 +\n // T-21 lock both arms to the same .detail.field='frame-duration'\n // branch — charter P4 consistent abstraction).\n if (!(frameDuration > 0)) {\n return new SpriteAnimationInvalidError({\n field: 'frame-duration',\n frameDuration,\n });\n }\n\n const advanced = advanceFrame(\n snap.currentFrame,\n snap.accumDt + dt,\n frameDuration,\n frameCount,\n snap.playbackMode,\n );\n\n // Write the new clock state. Partial set leaves regions / frameCount\n // / frameDuration / playbackMode untouched (world.set iterates\n // Object.keys(value)).\n const writeAnim = world.set(entity, SpriteAnimation, {\n currentFrame: advanced.currentFrame,\n accumDt: advanced.accumDt,\n });\n if (!writeAnim.ok) return null;\n\n // Materialise the per-frame UV slice into SpriteRegionOverride.\n // The slice is guaranteed to be 4 floats by the regions-length\n // invariant above. A fresh Float32Array is allocated per write so\n // the column owner's BufferPool slot does not alias the\n // SpriteAnimation.regions backing array (charter P5 producer\n // boundary: the override slot is a snapshot, not a view).\n const sliceStart = advanced.currentFrame * 4;\n const region = new Float32Array([\n regions[sliceStart] ?? 0,\n regions[sliceStart + 1] ?? 0,\n regions[sliceStart + 2] ?? 0,\n regions[sliceStart + 3] ?? 0,\n ]);\n writeOverride(world, entity, region);\n return null;\n}\n\n/**\n * Advance `currentFrame` / `accumDt` per the dt accumulator clock model\n * (research F-3 + plan-strategy section 2 D-5). `dt` is the\n * already-frame-loop-clamped Time.delta; the inner while-loop drains\n * frameDuration units one at a time. The playbackMode discriminator\n * picks LOOP (wrap) vs CLAMP (halt at last frame) per-tick per-entity\n * (D-5).\n */\nfunction advanceFrame(\n currentFrameIn: number,\n accumDtIn: number,\n frameDuration: number,\n frameCount: number,\n playbackModeRaw: number,\n): { currentFrame: number; accumDt: number } {\n let currentFrame = currentFrameIn;\n let accumDt = accumDtIn;\n const playback = spritePlaybackModeFromU32(playbackModeRaw);\n while (accumDt >= frameDuration) {\n accumDt -= frameDuration;\n switch (playback) {\n case 'loop': {\n currentFrame = (currentFrame + 1) % frameCount;\n break;\n }\n case 'clamp': {\n // `min(currentFrame + 1, frameCount - 1)`; once at the last\n // frame the index stops advancing. The accumDt subtraction\n // continues so the residue does not pile up across ticks (T-18\n // second it() block + T-22 case (2b) lock the halt).\n if (currentFrame < frameCount - 1) {\n currentFrame += 1;\n }\n break;\n }\n }\n }\n return { currentFrame, accumDt };\n}\n\n/**\n * Write the per-entity UV region into `SpriteRegionOverride`,\n * add-or-set with no registration-concept probe.\n *\n * `addComponent` is the registration-agnostic entry point: it auto-adds\n * the `SpriteRegionOverride` column on first use, so a World that only ever\n * spawned `SpriteAnimation` reaches the override column through this single\n * call (requirements section 7 boundary table row 2 / charter P3). When the\n * entity already carries the column, `addComponent` returns\n * `err(component-already-present)` — the steady-state signal — and we\n * `set` the region in place. `SpriteRegionOverride` declares no\n * relationship, so the exclusive auto-reparent arm of `addComponent`\n * never fires and `component-already-present` is the only present-case\n * outcome.\n *\n * This replaces the former `_getComponentByName` registration gate: the\n * \"is it registered\" question is no longer asked at all — `addComponent`\n * owns registration, and column presence is read from its structured\n * `Result` rather than a per-World registry lookup.\n */\nfunction writeOverride(world: World, entity: EntityHandle, region: Float32Array): void {\n const added = world.addComponent(entity, {\n component: SpriteRegionOverride,\n data: { region },\n });\n if (!added.ok && added.error.code === 'component-already-present') {\n world.set(entity, SpriteRegionOverride, { region });\n }\n}\n","// feat-20260713-mount-override-component-add-and-shared-ref-round M5 / w20 —\n// collect fold: derive the runtime-authored MountOverride[] for one nested\n// SceneInstance anchor (plan-strategy D-3).\n//\n// ── What it does ──\n// Given a nested anchor's SceneInstanceState, walk each live member entity and\n// diff its live component columns against the member's authored baseline (the\n// source SceneAsset's layer-1 values, filled with schema defaults so the\n// comparison is against a fully-populated row). Every difference becomes a\n// MountOverride the collect step splices into the parent's `mounts[].overrides`:\n// - a component present live but absent in source -> component-ADD override\n// ({ localId, comp, value }) whose value is the whole filled component map;\n// - a field whose live value differs from baseline -> field-PATCH override\n// ({ localId, comp, field, value }) for that single field;\n// - a component present in source but absent live -> NOT emitted (OOS-6:\n// component-remove deltas do not fold back this feat).\n//\n// ── Value domain ──\n// The fold emits values in the LIVE domain: shared<T> fields carry numeric\n// handles, not GUID strings. The caller (rootsToSceneAsset / serialize wiring,\n// w21) performs the handle->GUID reverse-lookup with the two-state NULL-sentinel\n// handling (scalar handle 0 -> omit, array handle 0 -> keep positional 0),\n// reusing the same classifier the owned-entity serialization uses. Keeping the\n// fold registry-free means it stays a pure World+state read (D-3 / §2.5).\n//\n// ── localId namespace ──\n// Emitted `localId` is in the CHILD scene's namespace (0-based, exactly what\n// `state.entityToLocalId` maps to). The collect caller rebases it into the\n// parent namespace by adding the mount window's `memberFirst`, so the override\n// addresses the same slot the apply path validates against\n// (`_validateMountOverrides`: [memberFirst, memberFirst + memberCount)).\n//\n// ── Idempotency (AC-04) ──\n// A parent-authored mount-time override is applied to the child member's LIVE\n// column at instantiate time, and the child's source SceneAsset does not carry\n// it — so `live - source` re-derives it every round. Emitting it exactly once\n// (never separately re-passing state.mountTimeOverrides on top) keeps the\n// override entry set stable across save->load->save cycles: lossless without\n// doubling. (Runtime fact grounding this: parent-authored overrides on a nested\n// member land in the PARENT anchor's state, not the folded child anchor's; the\n// child anchor's own mountTimeOverrides is empty. See the M5 implement report.)\n\nimport { resolveAssetHandle } from '@forgeax/engine-assets-runtime';\nimport {\n componentDefinition,\n type Component as EcsComponent,\n type EntityHandle,\n type World,\n} from '@forgeax/engine-ecs';\nimport { componentSchema } from '@forgeax/engine-ecs/internal';\nimport { fillComponentDefaults } from '@forgeax/engine-ecs/projection';\nimport type {\n Handle,\n LocalEntityId,\n MountOverride,\n SceneAsset,\n SceneEntity,\n} from '@forgeax/engine-types';\n\n/** Minimal structural view of a SceneInstanceState the fold reads (D-4 boundary:\n * `world.getSceneInstanceState(root).value` is structurally assignable). */\nexport interface FoldSceneInstanceState {\n readonly source: Handle<'SceneAsset', 'shared'>;\n readonly entityToLocalId: Map<EntityHandle, LocalEntityId>;\n}\n\n/** Component names that never participate in an authored baseline diff: the\n * essential row-identity column, and structural hierarchy relationship\n * holders/mirrors (ChildOf/Children) whose live values are re-wired by\n * instantiate, not authored. */\nfunction excludedComponentNames(): Set<string> {\n return new Set<string>(['Entity', 'ChildOf', 'Children']);\n}\n\n/** Normalize an array-like (typed array or Array) to a plain array for\n * structural comparison; pass non-array values through unchanged. */\nfunction normalize(value: unknown): unknown {\n if (\n Array.isArray(value) ||\n value instanceof Uint32Array ||\n value instanceof Float32Array ||\n value instanceof Int32Array ||\n value instanceof Float64Array ||\n value instanceof Uint8Array ||\n value instanceof Int16Array ||\n value instanceof Uint16Array\n ) {\n return Array.from(value as ArrayLike<unknown>);\n }\n return value;\n}\n\n/** Structural value equality after array normalization (handles Float32Array vs\n * number[] and nested arrays via JSON). Both inputs are column-shape values. */\nfunction valuesEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(normalize(a)) === JSON.stringify(normalize(b));\n}\n\n/** Build the per-field baseline map for a member from its source node, filled\n * with schema defaults so it matches the fully-populated live row. Transient\n * fields are dropped (they are never authored / never serialized, D-5). */\nfunction baselineFields(\n comp: EcsComponent<string>,\n sourceRaw: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const filled = fillComponentDefaults(comp, sourceRaw ?? {});\n const out: Record<string, unknown> = {};\n const fields = componentDefinition(comp).fields;\n for (const fieldName of Object.keys(componentSchema(comp))) {\n if (fields[fieldName]?.transient) continue;\n out[fieldName] = filled[fieldName];\n }\n return out;\n}\n\n/** Read the live, non-transient, non-entity field values of a component on an\n * entity into a plain map. Entity-type fields are dropped: their live value is a\n * live EntityHandle while the source carries a LocalEntityId, so they cannot be\n * diffed without remap — entity-ref override deltas are out of scope this feat\n * (the AC set centers on shared/asset fields + component-add). */\nfunction liveFields(\n world: World,\n entity: EntityHandle,\n comp: EcsComponent<string>,\n): Record<string, unknown> | undefined {\n const res = world.get(entity, comp);\n if (!res.ok) return undefined;\n const val = res.value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n const fields = componentDefinition(comp).fields;\n const schema = componentSchema(comp) as Record<string, string>;\n for (const fieldName of Object.keys(schema)) {\n if (fields[fieldName]?.transient) continue;\n const fieldType = schema[fieldName];\n if (fieldType === 'entity' || fieldType === 'array<entity>') continue;\n out[fieldName] = normalize(val[fieldName]);\n }\n return out;\n}\n\n/**\n * Fold one nested anchor's live member state into the runtime-authored\n * MountOverride[] (child-namespace localIds, live value domain). See file\n * header for the full contract. Returns [] when nothing differs from source.\n */\nexport function foldMountOverrides(world: World, state: FoldSceneInstanceState): MountOverride[] {\n const sourceRes = resolveAssetHandle<SceneAsset>(\n world,\n state.source as unknown as Handle<string, 'shared'>,\n );\n if (!sourceRes.ok) return [];\n const source = sourceRes.value as SceneAsset;\n\n // Index source entities by localId for O(1) baseline lookup.\n const sourceByLid = new Map<number, SceneEntity>();\n for (const node of source.entities) {\n sourceByLid.set(node.localId as unknown as number, node);\n }\n\n const excluded = excludedComponentNames();\n const registered = world.components.entries();\n const overrides: MountOverride[] = [];\n\n // Deterministic member order (localId ascending) so collect output is a pure\n // function of the graph (mirrors rootsToSceneAsset D-7 ordering discipline).\n const members: Array<[EntityHandle, number]> = [];\n for (const [entity, lid] of state.entityToLocalId) {\n members.push([entity, lid as unknown as number]);\n }\n members.sort((a, b) => a[1] - b[1]);\n\n for (const [entity, lid] of members) {\n const sourceNode = sourceByLid.get(lid);\n const sourceComps = (sourceNode?.components ?? {}) as Record<string, Record<string, unknown>>;\n\n for (const [compName, compToken] of registered) {\n if (excluded.has(compName)) continue;\n if (componentDefinition(compToken).policy.transient) continue;\n const comp = compToken as EcsComponent<string>;\n if (Object.keys(componentSchema(comp)).length === 0) continue;\n\n const live = liveFields(world, entity, comp);\n if (live === undefined) continue; // component absent live\n\n const sourceRaw = sourceComps[compName];\n if (sourceRaw === undefined) {\n // Component present live but absent in source -> component-ADD override.\n // Emit the whole live component value map (apply upserts with defaults).\n overrides.push({\n localId: lid as unknown as LocalEntityId,\n comp: compName,\n value: live,\n });\n continue;\n }\n\n // Component present in both -> per-field diff (field-PATCH overrides).\n const baseline = baselineFields(comp, sourceRaw);\n for (const fieldName of Object.keys(live)) {\n if (!valuesEqual(live[fieldName], baseline[fieldName])) {\n overrides.push({\n localId: lid as unknown as LocalEntityId,\n comp: compName,\n field: fieldName,\n value: live[fieldName],\n });\n }\n }\n }\n }\n\n return overrides;\n}\n","// feat-20260623 M2 w11+w12 — SceneInstance to SceneAsset POD collection + pack\n// serialization (plan-strategy D-1: pure-data collector).\n//\n// feat-20260701-rootstosceneasset-forest-collect-schema-derived-ha:\n// rootsToSceneAsset(registry, world, roots) -> Result<SceneAsset, ...>\n// serializeSceneAssetToPack -> schema-derived refs[] index.\n//\n// feat-20260703-collect-nested-sceneinstance-to-mount-roundtrip M2 + M3:\n//\n// ── mount-collapse (M2) ──\n// rootsToSceneAsset detects entities carrying SceneInstance (anchors) and\n// folds each anchor's subtree into a mounts[] entry — the uplink inverse of\n// instantiateScene which expands mounts[] into live entities. Member\n// classification filter, not subtree pruning: BFS walks the full subtree\n// (collectSubtree unchanged, D-4), then anchors' members are folded into\n// mount windows, graft entities survive as owned, and cross-window entity\n// references are remapped to window LocalEntityIds. Two anchor forms:\n// Form 2 (root = instance) strips SceneInstance without self-mount; Form 1\n// (deep anchor) folds at the anchor site with mount.parent pointing to the\n// anchor's ChildOf parent. Window accounting (totalSlots = entities.length\n// + mounts.length + sum(memberCount)) preserves the child instance's full\n// totalSlots, never shrinking by surviving-member count (AC-03, #495 guard).\n//\n// ── serialize mounts (M3) ──\n// serializeSceneAssetToPack maps in-memory mounts[].source GUID strings to\n// refs[] indices, memberFirst/memberCount/localId/parent numeric pass-through.\n// _resolveSceneGuids (asset-registry.ts) carries mounts through the reload\n// chain: recursively resolves child scene GUIDs, registers child copies in\n// the origin reverse-index (D-7), and protects against mount-source cycles\n// (R-9). registry.instantiate wires an identity resolver so resolved mount\n// handles flow into instantiateScene transparently.\n//\n// ── round-trip closure ──\n// The round-trip instantiate -> collect (rootsToSceneAsset) -> serialize\n// (serializeSceneAssetToPack) -> reload (loadByGuid + registry.instantiate)\n// -> instantiate produces a structurally equivalent live subtree (AC-04).\n// The equivalence benchmark is a second collect (fixed-point): after the\n// first reload, the second collect output equals the first (D-9 normalization\n// converges after one cycle).\n//\n// ── known limitations ──\n// OOS-1: mount.overrides[] (Layer-0 diffs) are not folded back during collect.\n// D-9: Form 1 mount entity absorption — when the anchor parent cannot be\n// proven to be a mount entity, components is left undefined (one-time\n// normalization on first reload; fixed-point from second collect onward).\n\nimport {\n builtinMeshGuid,\n resolveAssetHandle,\n SceneCollectAssetGuidUnresolvedError,\n SceneCollectEntityRefOutOfClosureError,\n} from '@forgeax/engine-assets-runtime';\nimport {\n componentDefinition,\n type Component as EcsComponent,\n type EntityHandle,\n type World,\n} from '@forgeax/engine-ecs';\nimport { classifyEntityField } from '@forgeax/engine-ecs/externalization';\nimport { componentSchema } from '@forgeax/engine-ecs/internal';\nimport { SceneInstance } from '@forgeax/engine-render';\nimport { err, ok, type Result } from '@forgeax/engine-rhi';\nimport {\n collectSubtree,\n externalizeSceneAsset,\n SCENE_COLLECT_PROFILE,\n worldGetSceneAssetForInstance,\n worldGetSceneInstanceState,\n} from '@forgeax/engine-scene';\nimport type {\n Asset,\n Handle,\n LocalEntityId,\n MountOverride,\n SceneAsset,\n SceneEntity,\n SceneInstanceMount,\n} from '@forgeax/engine-types';\nimport { foldMountOverrides } from './scene-utils/mount-override-fold';\n\n/** The collector needs identity lookup, not an authoring registry implementation. */\nexport interface SceneAssetGuidLookup {\n guidOf(asset: Asset): string | undefined;\n}\n\n// Shared helpers\nfunction _isArrayLike(value: unknown): value is ArrayLike<unknown> {\n // SceneAsset values are ordinary JSON arrays at the boundary. Use the\n // platform view predicate so fixed-array component fields such as Fog.color\n // remain generic when their storage element type grows, while DataView (a\n // byte accessor without indexed array semantics) stays scalar.\n return Array.isArray(value) || (ArrayBuffer.isView(value) && !(value instanceof DataView));\n}\nfunction _normalizeArray(value: ArrayLike<unknown>): unknown[] {\n return Array.from(value);\n}\n\n// Schema-derived field classifier — shared kernel now owns entity classification.\n// Keep the local shared<T> classifier because the kernel only handles entity fields.\ntype SchemaFieldClass =\n | { kind: 'entity'; scalar: true }\n | { kind: 'entity'; scalar: false }\n | { kind: 'shared'; scalar: true }\n | { kind: 'shared'; scalar: false };\n\nfunction classifyFieldSchema(fieldType: string | undefined): SchemaFieldClass | undefined {\n if (fieldType === undefined) return undefined;\n if (fieldType.startsWith('shared<')) return { kind: 'shared', scalar: true };\n if (fieldType.startsWith('array<shared<')) return { kind: 'shared', scalar: false };\n return undefined;\n}\n\n// ── M5 (w21): override-value handle→GUID serialization ──\n//\n// Reverse-lookup one shared-field handle to its catalogued GUID string. Returns\n// `undefined` for the NULL sentinel (handle 0) so the caller applies the two\n// distinct sentinel semantics: scalar -> omit the field, array -> placeholder 0.\n// Any non-zero handle that fails to resolve is a fail-fast (D-2, no silent drop).\n// Shared kernel: both the owned-entity serialization loop (Step 4) and the M5\n// override-value serialization call this so the resolve/lookup/fail-fast idiom\n// lives in exactly one place; `field` names the failing field in the error.\nfunction _handleToGuid(\n world: World,\n registry: SceneAssetGuidLookup,\n handle: number,\n field: string,\n): Result<string | undefined, SceneCollectAssetGuidUnresolvedError> {\n if (handle === 0) return ok(undefined); // NULL sentinel\n const builtinGuid = builtinMeshGuid(handle as unknown as Handle<string, 'shared'>);\n if (builtinGuid !== undefined) return ok(builtinGuid);\n const assetRes = resolveAssetHandle(world, handle as unknown as Handle<string, 'shared'>);\n if (!assetRes.ok) return err(new SceneCollectAssetGuidUnresolvedError(field, handle));\n const guid = registry.guidOf(assetRes.value as Asset);\n if (guid === undefined) return err(new SceneCollectAssetGuidUnresolvedError(field, handle));\n return ok(guid);\n}\n\n// Convert one shared field value (scalar handle or array<handle>) from the live\n// handle domain to the serialized GUID domain, applying the two-state NULL\n// sentinel: scalar handle 0 -> undefined (caller omits the field); array handle\n// 0 -> numeric 0 kept in place (positional SoA alignment, #640). Non-shared\n// values pass through untouched.\nfunction _serializeSharedFieldValue(\n world: World,\n registry: SceneAssetGuidLookup,\n classification: SchemaFieldClass,\n value: unknown,\n field: string,\n): Result<unknown, SceneCollectAssetGuidUnresolvedError> {\n if (classification.scalar) {\n if (typeof value !== 'number') return ok(value);\n return _handleToGuid(world, registry, value, field); // undefined -> caller omits\n }\n if (!Array.isArray(value)) return ok(value);\n const mapped: Array<string | number> = [];\n for (const elem of value as ReadonlyArray<unknown>) {\n if (typeof elem !== 'number') {\n mapped.push(elem as number);\n continue;\n }\n const g = _handleToGuid(world, registry, elem, field);\n if (!g.ok) return g;\n mapped.push(g.value ?? 0); // NULL sentinel keeps positional 0\n }\n return ok(mapped);\n}\n\n// Convert an override's value from the live handle domain to the serialized GUID\n// domain (w21). Field-patch form (`ov.field` present) carries a single field\n// value; component-add form carries a per-field value map. Shared fields are\n// reverse-looked-up per {@link _serializeSharedFieldValue}; a scalar NULL\n// sentinel drops the key (component-add) or is kept as 0 (field-patch, where the\n// override IS that field so it cannot be omitted). Non-shared fields pass through.\nfunction _serializeOverrideValueHandles(\n world: World,\n registry: SceneAssetGuidLookup,\n ov: MountOverride,\n): Result<unknown, SceneCollectAssetGuidUnresolvedError> {\n const comp = world.components.resolve(ov.comp);\n const schema = comp === undefined ? undefined : (componentSchema(comp) as Record<string, string>);\n if (ov.field !== undefined) {\n const classification = schema ? classifyFieldSchema(schema[ov.field]) : undefined;\n if (!classification || classification.kind !== 'shared') return ok(ov.value);\n const conv = _serializeSharedFieldValue(world, registry, classification, ov.value, ov.field);\n if (!conv.ok) return conv;\n // Field-patch: keep the field even at NULL sentinel (the override IS the\n // field); undefined only arises for a scalar handle 0 -> emit 0.\n return ok(conv.value ?? 0);\n }\n // component-add: value is a per-field map.\n if (typeof ov.value !== 'object' || ov.value === null || Array.isArray(ov.value)) {\n return ok(ov.value);\n }\n const src = ov.value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const fieldName of Object.keys(src)) {\n const classification = schema ? classifyFieldSchema(schema[fieldName]) : undefined;\n if (!classification || classification.kind !== 'shared') {\n out[fieldName] = src[fieldName];\n continue;\n }\n const conv = _serializeSharedFieldValue(\n world,\n registry,\n classification,\n src[fieldName],\n fieldName,\n );\n if (!conv.ok) return conv;\n if (classification.scalar && conv.value === undefined) continue; // scalar 0 -> omit\n out[fieldName] = conv.value;\n }\n return ok(out);\n}\n\n// serializeSceneAssetToPack — emits the current Pack v2/local-artifact envelope.\nexport function serializeSceneAssetToPack(\n sceneAsset: SceneAsset,\n components: ReadonlyMap<string, EcsComponent>,\n guid?: string,\n): Result<Record<string, unknown>, SceneCollectAssetGuidUnresolvedError> {\n const externalized = externalizeSceneAsset(sceneAsset, (componentName) => {\n const component = components.get(componentName);\n return component === undefined ? undefined : componentSchema(component);\n });\n if (!externalized.ok) {\n const value = externalized.error.value;\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n externalized.error.field,\n typeof value === 'string' || typeof value === 'number' ? value : String(value),\n ),\n );\n }\n return ok({\n schemaVersion: '2.0.0',\n kind: 'internal-text-package',\n assets: [\n {\n guid: guid ?? crypto.randomUUID(),\n kind: 'scene',\n payload: externalized.value.payload,\n refs: externalized.value.refs.map((reference) => reference.guid),\n artifacts: {},\n },\n ],\n });\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// rootsToSceneAsset — with M2 mount-collapse\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Collect a forest of entity subtrees into a self-contained SceneAsset.\n *\n * M2 mount-collapse: entities carrying SceneInstance that are NOT roots\n * are folded into mount entries. Root anchors have their SceneInstance\n * row stripped without producing a self-mount. Member classification\n * filter (not subtree pruning): graft entities under members survive as owned.\n */\nexport function rootsToSceneAsset(\n registry: SceneAssetGuidLookup,\n world: World,\n roots: EntityHandle[],\n): Result<\n SceneAsset,\n SceneCollectEntityRefOutOfClosureError | SceneCollectAssetGuidUnresolvedError\n> {\n const collectProfile = SCENE_COLLECT_PROFILE;\n // ── Step 1: BFS closure ──\n const visited = new Set<number>();\n for (const root of roots) collectSubtree(world, root, visited);\n if (visited.size === 0) return ok({ kind: 'scene', entities: [] });\n\n const rootRawSet = new Set<number>();\n for (const r of roots) rootRawSet.add(r as number);\n\n // ── Step 1.5: Mount-collapse — identify anchors ──\n const anchorEntities = new Set<number>();\n for (const er of visited) {\n if (world.get(er as EntityHandle, SceneInstance).ok) anchorEntities.add(er);\n }\n\n // D-7 (feat-20260707) ordering robustness: the first-wins loops below\n // (memberEntities claim + carrier absorption) resolve ties by iteration\n // order. Iterating the anchorEntities Set directly ties the outcome to BFS\n // insertion order — deterministic within one run but fragile to Node/VM\n // changes. Sort by raw handle so \"which anchor claims a shared member / a\n // shared carrier\" is a deterministic function of the SceneAsset (§3.2\n // fixed-point premise: collect output must be a pure function of the graph).\n const anchorsSorted = [...anchorEntities].sort((a, b) => a - b);\n\n // Classify members for non-root anchors.\n const memberEntities = new Set<number>();\n const memberOrigin = new Map<number, { anchorRaw: number; memberLocalId: number }>();\n for (const er of anchorsSorted) {\n if (rootRawSet.has(er)) continue; // root anchor: don't classify members\n const sr = worldGetSceneInstanceState(world, er as EntityHandle);\n if (!sr.ok) continue;\n for (const [me, lid] of sr.value.entityToLocalId) {\n const mr = me as number;\n if (visited.has(mr) && !anchorEntities.has(mr) && !memberEntities.has(mr)) {\n memberEntities.add(mr);\n memberOrigin.set(mr, { anchorRaw: er, memberLocalId: lid as unknown as number });\n }\n }\n }\n\n // Remove inner anchors (members of outer anchors).\n for (const er of anchorEntities) {\n if (memberEntities.has(er) && !rootRawSet.has(er)) anchorEntities.delete(er);\n }\n\n // ── Step 1.75: Mount-carrier absorption ──\n //\n // worldInstantiateScene materialises each mounts[] entry as a plain \"mount\n // entity\" (`_spawnMountEntity` output: mount.components + a default Transform,\n // but NO SceneInstance) whose child is the mounted scene's synthetic root (the\n // real anchor, which DOES carry SceneInstance). So a `mounts[{parent: W}]`\n // whose parent W is an OWNED entity comes back on reload as the live chain\n // W (owned) -> carrier (plain mount entity) -> anchor (SceneInstance).\n // The carrier IS the re-materialised mount slot. If collect keeps it as an\n // owned entity (it has no SceneInstance, so Step 2 would), the next serialize→\n // reload inserts ANOTHER carrier under it, growing one nameless ghost node per\n // save→reload cycle — unbounded (the editor \"Add to Scene → save → reopen →\n // #N\" regression). Existing pure-mount round-trips don't hit this because they\n // use `mount.parent === undefined` (mount attaches to the synthetic root,\n // which is stripped, so no owned carrier survives).\n //\n // Fix: recognise a carrier and fold it back into its mount. A carrier is the\n // ChildOf-parent P of a non-root anchor A where P is a pure mount slot: not a\n // root, not itself an anchor/member, carries no authored identity (only the\n // structural Transform/Children/ChildOf/Entity that _spawnMountEntity leaves),\n // and its sole visited child is A. The mount for A then takes P's slot:\n // mount.parent = P's ChildOf parent, and any ref to P resolves to the mount.\n const childOfTk0 = world.components.resolve('ChildOf');\n const childrenTk0 = world.components.resolve('Children');\n const carrierAllowed = new Set(['Transform', 'Children', 'ChildOf', 'Entity']);\n const carrierForAnchor = new Map<number, number>(); // anchorRaw -> carrierRaw\n const carrierToAnchor = new Map<number, number>(); // carrierRaw -> anchorRaw\n const isMountCarrier = (p: number, anchorRaw: number): boolean => {\n if (rootRawSet.has(p)) return false;\n if (anchorEntities.has(p) || memberEntities.has(p)) return false;\n if (!visited.has(p)) return false;\n for (const [compName, compToken] of world.components.entries()) {\n if (carrierAllowed.has(compName)) continue;\n if (world.get(p as EntityHandle, compToken as EcsComponent<string>).ok) return false;\n }\n if (childrenTk0) {\n const cr = world.get(p as EntityHandle, childrenTk0 as EcsComponent<string>);\n if (cr.ok) {\n const kids = (cr.value as { entities?: ArrayLike<number> }).entities;\n if (kids) {\n let visitedKidCount = 0;\n let sawAnchor = false;\n for (let i = 0; i < kids.length; i++) {\n const k = kids[i] as number;\n if (!visited.has(k)) continue;\n visitedKidCount += 1;\n if (k === anchorRaw) sawAnchor = true;\n }\n if (!sawAnchor || visitedKidCount !== 1) return false;\n }\n }\n }\n return true;\n };\n if (childOfTk0) {\n // Deterministic order (D-7): a carrier shared by two anchors is claimed by\n // the lowest-handle anchor regardless of Set iteration order.\n for (const anchorRaw of anchorsSorted) {\n if (!anchorEntities.has(anchorRaw)) continue; // pruned inner anchor\n if (rootRawSet.has(anchorRaw)) continue;\n const cr = world.get(anchorRaw as EntityHandle, childOfTk0 as EcsComponent<string>);\n if (!cr.ok) continue;\n const pRaw = (cr.value as Record<string, unknown>).parent as number | undefined;\n if (pRaw === undefined) continue;\n if (!carrierToAnchor.has(pRaw) && isMountCarrier(pRaw, anchorRaw)) {\n carrierForAnchor.set(anchorRaw, pRaw);\n carrierToAnchor.set(pRaw, anchorRaw);\n }\n }\n }\n\n // ── Step 2: Filter owned & build mounts for non-root anchors ──\n const orderedEntities = [...visited];\n const ownedEntities: number[] = [];\n for (const er of orderedEntities) {\n if (carrierToAnchor.has(er)) continue; // absorbed into its mount\n if ((!anchorEntities.has(er) || rootRawSet.has(er)) && !memberEntities.has(er)) {\n ownedEntities.push(er);\n }\n }\n\n const entityToLocalId = new Map<number, number>();\n for (let i = 0; i < ownedEntities.length; i++) {\n const e = ownedEntities[i];\n if (e !== undefined) entityToLocalId.set(e, i);\n }\n\n // Build non-root anchor info + resolve GUIDs.\n const nonRootAnchors: Array<{ entityRaw: number; sourceGuid: string; totalSlots: number }> = [];\n for (const er of anchorEntities) {\n if (rootRawSet.has(er)) continue;\n const sh = worldGetSceneAssetForInstance(world, er as EntityHandle);\n if (!sh.ok)\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n 'SceneInstance.source',\n sh.error as unknown as number,\n ),\n );\n const pr = resolveAssetHandle<SceneAsset>(\n world,\n sh.value as unknown as Handle<string, 'shared'>,\n );\n if (!pr.ok)\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n 'SceneInstance.source',\n sh.value as unknown as number,\n ),\n );\n const g = registry.guidOf(pr.value as Asset);\n if (g === undefined)\n return err(\n new SceneCollectAssetGuidUnresolvedError(\n 'SceneInstance.source',\n sh.value as unknown as number,\n ),\n );\n const sr = worldGetSceneInstanceState(world, er as EntityHandle);\n if (!sr.ok)\n return err(new SceneCollectAssetGuidUnresolvedError('SceneInstance.source', 'state'));\n nonRootAnchors.push({ entityRaw: er, sourceGuid: g, totalSlots: sr.value.totalSlots });\n }\n\n // Sort by BFS order.\n const bfsIdx = new Map<number, number>();\n for (let i = 0; i < orderedEntities.length; i++) {\n if (orderedEntities[i] !== undefined) bfsIdx.set(orderedEntities[i] as number, i);\n }\n nonRootAnchors.sort((a, b) => (bfsIdx.get(a.entityRaw) ?? 0) - (bfsIdx.get(b.entityRaw) ?? 0));\n\n // ── Step 3: Allocate mount windows ──\n const ownedCount = ownedEntities.length;\n const outMounts: SceneInstanceMount[] = [];\n let nextMF = ownedCount + nonRootAnchors.length;\n const childOfTk = world.components.resolve('ChildOf');\n\n const transformTk = world.components.resolve('Transform');\n for (const a of nonRootAnchors) {\n // When a mount carrier was absorbed (Step 1.75), the mount takes the\n // carrier's slot: resolve the ChildOf parent from the CARRIER (the anchor's\n // own parent IS the carrier, which no longer exists as an owned entity), and\n // carry the carrier's Transform as mount.components so placement round-trips.\n const carrierRaw = carrierForAnchor.get(a.entityRaw);\n const parentSourceRaw = carrierRaw ?? a.entityRaw;\n let mp: number | undefined;\n if (childOfTk) {\n const cr = world.get(parentSourceRaw as EntityHandle, childOfTk as EcsComponent<string>);\n if (cr.ok) {\n const pRaw = (cr.value as Record<string, unknown>).parent as number;\n if (pRaw !== undefined) {\n const ol = entityToLocalId.get(pRaw);\n if (ol !== undefined) mp = ol;\n else {\n const mo = memberOrigin.get(pRaw);\n if (mo !== undefined) {\n const ai = nonRootAnchors.findIndex((x) => x.entityRaw === mo.anchorRaw);\n if (ai >= 0) mp = ownedCount + ai;\n }\n }\n }\n }\n }\n let mountComponents: SceneInstanceMount['components'] | undefined;\n if (carrierRaw !== undefined && transformTk) {\n const tr = world.get(carrierRaw as EntityHandle, transformTk as EcsComponent<string>);\n if (tr.ok) {\n mountComponents = {\n Transform: { ...(tr.value as Record<string, unknown>) },\n } as SceneInstanceMount['components'];\n }\n }\n // ── M5 (w20 + w21): fold runtime-authored overrides into this mount ──\n // foldMountOverrides emits child-namespace localIds in the LIVE handle\n // domain; rebase each into the parent namespace (memberFirst + childLocalId)\n // and reverse-lookup shared-field handles to GUID strings (two-state\n // NULL-sentinel). Unresolvable handle -> SceneCollectAssetGuidUnresolvedError\n // (D-2 fail-fast, no silent drop).\n const memberFirst0 = nextMF;\n let mountOverrides: MountOverride[] | undefined;\n const foldStateRes = worldGetSceneInstanceState(world, a.entityRaw as EntityHandle);\n if (foldStateRes.ok) {\n const rawOverrides = foldMountOverrides(world, foldStateRes.value);\n if (rawOverrides.length > 0) {\n mountOverrides = [];\n for (const ov of rawOverrides) {\n const convRes = _serializeOverrideValueHandles(world, registry, ov);\n if (!convRes.ok) return convRes;\n mountOverrides.push({\n ...ov,\n localId: (memberFirst0 + (ov.localId as unknown as number)) as LocalEntityId,\n value: convRes.value,\n });\n }\n }\n }\n\n const mount: SceneInstanceMount = {\n localId: (ownedCount + outMounts.length) as LocalEntityId,\n source: a.sourceGuid,\n memberFirst: nextMF as LocalEntityId,\n memberCount: a.totalSlots,\n ...(mp !== undefined ? { parent: mp as LocalEntityId } : {}),\n ...(mountComponents !== undefined ? { components: mountComponents } : {}),\n ...(mountOverrides !== undefined && mountOverrides.length > 0\n ? { overrides: mountOverrides }\n : {}),\n };\n outMounts.push(mount);\n nextMF += a.totalSlots;\n }\n\n // Entity ref resolution helper.\n function _rlid(t: number): number | undefined {\n const ol = entityToLocalId.get(t);\n if (ol !== undefined) return ol;\n // An absorbed mount carrier resolves to its mount's localId (the mount took\n // the carrier's slot in Step 1.75), so refs to the carrier — e.g. the\n // wrapper's Children list — point at the mount rather than dangle.\n const absorbedAnchor = carrierToAnchor.get(t);\n if (absorbedAnchor !== undefined) {\n for (let i = 0; i < nonRootAnchors.length; i++) {\n if (nonRootAnchors[i]?.entityRaw === absorbedAnchor) return ownedCount + i;\n }\n }\n for (let i = 0; i < nonRootAnchors.length; i++) {\n if (nonRootAnchors[i]?.entityRaw === t) return ownedCount + i;\n }\n const mo = memberOrigin.get(t);\n if (mo !== undefined) {\n for (let i = 0; i < nonRootAnchors.length; i++) {\n if (nonRootAnchors[i]?.entityRaw === mo.anchorRaw) {\n let mf = ownedCount + nonRootAnchors.length;\n for (let j = 0; j < i; j++) mf += nonRootAnchors[j]?.totalSlots ?? 0;\n return mf + mo.memberLocalId;\n }\n }\n }\n return undefined;\n }\n\n // ── Step 4: Build SceneEntity rows ──\n const registeredComps = world.components.entries();\n const entities: SceneEntity[] = [];\n\n for (let lid = 0; lid < ownedEntities.length; lid++) {\n const entityRaw = ownedEntities[lid];\n if (entityRaw === undefined) continue;\n const entity = entityRaw as EntityHandle;\n const components: Record<string, Record<string, unknown>> = {};\n const isRoot = rootRawSet.has(entityRaw);\n\n for (const [compName, compToken] of registeredComps) {\n if (\n !collectProfile.includeComponent(\n compName,\n componentDefinition(compToken).policy.transient === true,\n )\n )\n continue;\n if (isRoot && compName === 'ChildOf') continue;\n\n const valRes = world.get(entity, compToken as EcsComponent<string>);\n if (!valRes.ok) continue;\n\n const val = valRes.value as Record<string, unknown>;\n const comp = compToken;\n if (comp === undefined) continue;\n\n const schema = componentSchema(comp);\n const schemaKeys = Object.keys(schema);\n // Empty-schema components are authored marker components, not absent\n // state. Preserve their presence through scene-pack round-trips (for\n // example AudioListener); transient markers have already been excluded\n // above and therefore remain derived-only by declaration.\n if (schemaKeys.length === 0) {\n components[compName] = {};\n continue;\n }\n\n const fieldValues: Record<string, unknown> = {};\n\n for (const fieldName of schemaKeys) {\n const rawValue = val[fieldName];\n if (rawValue === undefined) continue;\n\n // Field-level transient skip (D-5): a field declared `transient: true`\n // is derived/reconstructable and excluded from serialization, just as a\n // transient component (L554) is. Generic — reads the reflection flag for\n // any component/field; no hardcoded component or field name.\n if (\n !collectProfile.includeField(\n compName,\n fieldName,\n componentDefinition(comp).fields[fieldName]?.transient === true,\n )\n )\n continue;\n\n const schemaFieldType = schema[fieldName];\n const entityKind = classifyEntityField(comp as EcsComponent, fieldName);\n const sharedClass =\n schemaFieldType !== undefined ? classifyFieldSchema(schemaFieldType) : undefined;\n\n if (!entityKind && !sharedClass) {\n if (_isArrayLike(rawValue)) {\n fieldValues[fieldName] = _normalizeArray(rawValue);\n } else {\n fieldValues[fieldName] = rawValue;\n }\n continue;\n }\n\n if (entityKind !== null) {\n // Entity / array<entity> field — use shared kernel for remap\n if (entityKind.isArray) {\n const arr = _isArrayLike(rawValue)\n ? _normalizeArray(rawValue)\n : (rawValue as unknown[]);\n const mapped: number[] = [];\n for (const elem of arr) {\n const lid2 = _rlid(elem as number);\n if (lid2 === undefined) {\n return err(\n new SceneCollectEntityRefOutOfClosureError(entityRaw, fieldName, elem as number),\n );\n }\n mapped.push(lid2);\n }\n fieldValues[fieldName] = mapped;\n } else {\n // A nullable entity field uses the ECS null sentinel and is omitted\n // from the scene payload just like a null shared handle. It is not\n // an out-of-closure reference.\n if (rawValue === null) continue;\n const lid2 = _rlid(rawValue as number);\n if (lid2 === undefined) {\n return err(\n new SceneCollectEntityRefOutOfClosureError(\n entityRaw,\n fieldName,\n rawValue as number,\n ),\n );\n }\n fieldValues[fieldName] = lid2;\n }\n } else {\n // shared<T> field — reverse-lookup handle(s) to GUID(s) via the shared\n // kernel (same two-state NULL-sentinel the M5 override serializer uses).\n // scalar handle 0 -> undefined => omit the field (deserialize restores\n // the slot-0 default; emitting 0 would be misread as refs index 0 by\n // parseScenePayload HANDLE_FIELD_NAMES). array handle 0 -> positional 0\n // kept (paired SoA alignment, e.g. AnimationPlayer.clips = [h,0,0,0]).\n // AnimationPlayer.graph (shared<AnimationGraph> scalar, M4/w31) is\n // handled generically here — no special case needed.\n const normalized = _isArrayLike(rawValue) ? _normalizeArray(rawValue) : rawValue;\n if (sharedClass === undefined) {\n // Fallback: non-entity, non-shared — pass through\n fieldValues[fieldName] = normalized;\n continue;\n }\n const conv = _serializeSharedFieldValue(\n world,\n registry,\n sharedClass,\n normalized,\n fieldName,\n );\n if (!conv.ok) return conv;\n if (sharedClass.scalar && conv.value === undefined) continue; // NULL sentinel -> omit\n fieldValues[fieldName] = conv.value;\n }\n }\n\n if (Object.keys(fieldValues).length > 0) components[compName] = fieldValues;\n }\n\n entities.push({ localId: lid as LocalEntityId, components } as SceneEntity);\n }\n\n return ok({\n kind: 'scene',\n entities,\n ...(outMounts.length > 0 ? { mounts: outMounts } : {}),\n });\n}\n"]}
|