@woosh/meep-engine 3.14.1 → 3.14.2
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 +31 -24
- package/package.json +1 -1
- package/src/avif/native/DECISIONS.md +544 -536
- package/src/avif/native/heif/parse_avif_file.d.ts.map +1 -1
- package/src/avif/native/heif/parse_avif_file.js +384 -383
- package/src/avif/native/heif/parse_image_grid.d.ts.map +1 -1
- package/src/avif/native/heif/parse_image_grid.js +49 -48
- package/src/basis/BasisBitReader.d.ts +77 -0
- package/src/basis/BasisBitReader.d.ts.map +1 -0
- package/src/basis/BasisBitReader.js +231 -0
- package/src/basis/BasisHuffmanTable.d.ts +53 -0
- package/src/basis/BasisHuffmanTable.d.ts.map +1 -0
- package/src/basis/BasisHuffmanTable.js +263 -0
- package/src/basis/basis_read_huffman_table.d.ts +20 -0
- package/src/basis/basis_read_huffman_table.d.ts.map +1 -0
- package/src/basis/basis_read_huffman_table.js +187 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.d.ts +50 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.d.ts.map +1 -0
- package/src/basis/etc1s/Etc1sSelectorHistory.js +89 -0
- package/src/basis/etc1s/etc1s_block_colors.d.ts +14 -0
- package/src/basis/etc1s/etc1s_block_colors.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_block_colors.js +75 -0
- package/src/basis/etc1s/etc1s_decode_slice.d.ts +57 -0
- package/src/basis/etc1s/etc1s_decode_slice.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_decode_slice.js +258 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts +48 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_endpoint_codebook.js +111 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts +42 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_selector_codebook.js +127 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.d.ts +54 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.d.ts.map +1 -0
- package/src/basis/etc1s/etc1s_read_slice_tables.js +47 -0
- package/src/basis/transcode/build_range_plan.js +54 -0
- package/src/basis/transcode/etc1s_to_bc1.d.ts +24 -0
- package/src/basis/transcode/etc1s_to_bc1.d.ts.map +1 -0
- package/src/basis/transcode/etc1s_to_bc1.js +205 -0
- package/src/basis/transcode/etc1s_to_bc7.d.ts +30 -0
- package/src/basis/transcode/etc1s_to_bc7.d.ts.map +1 -0
- package/src/basis/transcode/etc1s_to_bc7.js +496 -0
- package/src/basis/transcode/fit_endpoints.d.ts +59 -0
- package/src/basis/transcode/fit_endpoints.d.ts.map +1 -0
- package/src/basis/transcode/fit_endpoints.js +226 -0
- package/src/{avif/native/isobmff → core/binary}/ByteCursor.d.ts +19 -6
- package/src/core/binary/ByteCursor.d.ts.map +1 -0
- package/src/{avif/native/isobmff → core/binary}/ByteCursor.js +41 -14
- package/src/engine/EngineHarness.js +1 -1
- package/src/engine/asset/codec/Codec.d.ts.map +1 -0
- package/src/engine/asset/codec/CodecWithFallback.d.ts.map +1 -0
- package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.js +2 -2
- package/src/engine/asset/loaders/image/IMAGE_CODEC_REVIEW_2026_08_28.md +4 -4
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/codec/NativeImageDecoder.js +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.d.ts.map +1 -1
- package/src/engine/asset/loaders/image/codec/ThreadedImageDecoder.js +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlas.d.ts.map +1 -1
- package/src/engine/graphics/texture/atlas/TextureAtlas.js +13 -0
- package/src/engine/physics/broadphase/generate_pairs.d.ts.map +1 -1
- package/src/engine/physics/broadphase/generate_pairs.js +7 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/ktx2/KTX2_IDENTIFIER.d.ts +14 -0
- package/src/ktx2/KTX2_IDENTIFIER.d.ts.map +1 -0
- package/src/ktx2/KTX2_IDENTIFIER.js +15 -0
- package/src/ktx2/KhrDfModel.d.ts +35 -0
- package/src/ktx2/KhrDfModel.d.ts.map +1 -0
- package/src/ktx2/KhrDfModel.js +49 -0
- package/src/ktx2/SupercompressionScheme.d.ts +16 -0
- package/src/ktx2/SupercompressionScheme.d.ts.map +1 -0
- package/src/ktx2/SupercompressionScheme.js +23 -0
- package/src/ktx2/ktx2_read.d.ts +71 -0
- package/src/ktx2/ktx2_read.d.ts.map +1 -0
- package/src/ktx2/ktx2_read.js +581 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts +27 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.d.ts.map +1 -0
- package/src/ktx2/ktx2_read_basis_lz_global_data.js +189 -0
- package/src/ktx2/vk_format_to_texture_format.d.ts +55 -0
- package/src/ktx2/vk_format_to_texture_format.d.ts.map +1 -0
- package/src/ktx2/vk_format_to_texture_format.js +290 -0
- package/src/shade/descriptor/GPUTextureUsage.d.ts +23 -0
- package/src/shade/descriptor/GPUTextureUsage.d.ts.map +1 -0
- package/src/shade/descriptor/GPUTextureUsage.js +24 -0
- package/src/shade/descriptor/WebGPUExtensionType.d.ts +3 -0
- package/src/shade/descriptor/WebGPUExtensionType.js +26 -0
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts +2 -6
- package/src/shade/descriptor/texture/TextureDescriptor.d.ts.map +1 -1
- package/src/shade/descriptor/texture/TextureDescriptor.js +24 -40
- package/src/shade/descriptor/texture/format/TextureFormat.d.ts +125 -0
- package/src/shade/descriptor/texture/format/TextureFormat.d.ts.map +1 -0
- package/src/shade/descriptor/texture/format/TextureFormat.js +146 -0
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts +60 -0
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.d.ts.map +1 -1
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +102 -0
- package/src/shade/device/graph/TextureResourceDescriptor.d.ts.map +1 -1
- package/src/shade/device/graph/TextureResourceDescriptor.js +160 -155
- package/src/shade/device/mock/SoftwareGPUQueue.d.ts +11 -4
- package/src/shade/device/mock/SoftwareGPUQueue.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUQueue.js +31 -37
- package/src/shade/device/mock/SoftwareGPUTexture.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUTexture.js +8 -4
- package/src/shade/device/timing/profile/frame_graph_extract_topology.d.ts.map +1 -1
- package/src/shade/device/timing/profile/frame_graph_extract_topology.js +164 -174
- package/src/shade/playground/ground_seam/README.md +235 -0
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts +45 -0
- package/src/shade/playground/ground_seam/capture_scene_color.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/capture_scene_color.js +242 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts +11 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/depth_step_across_seam.js +185 -0
- package/src/shade/playground/ground_seam/index.html +195 -0
- package/src/shade/playground/ground_seam/main.d.ts +2 -0
- package/src/shade/playground/ground_seam/main.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/main.js +879 -0
- package/src/shade/playground/ground_seam/make_grid_texture.d.ts +29 -0
- package/src/shade/playground/ground_seam/make_grid_texture.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/make_grid_texture.js +105 -0
- package/src/shade/playground/ground_seam/make_ground.d.ts +70 -0
- package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/make_ground.js +161 -0
- package/src/shade/playground/ground_seam/measure_flicker.d.ts +71 -0
- package/src/shade/playground/ground_seam/measure_flicker.d.ts.map +1 -0
- package/src/shade/playground/ground_seam/measure_flicker.js +531 -0
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +2519 -2511
- package/src/shade/renderer/hiz/HierarchicalZBuffer.d.ts.map +1 -1
- package/src/shade/renderer/hiz/HierarchicalZBuffer.js +275 -274
- package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/GPULightCollection.js +323 -314
- package/src/shade/renderer/lightmap/GPULightMap.js +336 -336
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +12 -2
- package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer.js +3 -1
- package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
- package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +3 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_brick4.js +3 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/native/oit/chunk_forward_shade_standard_fragment_ibl.js +3 -1
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts +28 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/normal/chunk_decode_tangent_normal.js +39 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts +45 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_full.js +94 -61
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts +24 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_barycentric_solve.js +43 -0
- package/src/shade/renderer/texture/COMPRESSED_TEXTURE_PLAN_2026_09_01.md +1462 -0
- package/src/shade/renderer/texture/TextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/TextureManager.js +20 -8
- package/src/shade/renderer/texture/TextureRole.d.ts +19 -0
- package/src/shade/renderer/texture/TextureRole.d.ts.map +1 -0
- package/src/shade/renderer/texture/TextureRole.js +26 -0
- package/src/shade/renderer/texture/TextureVariantSet.d.ts +71 -0
- package/src/shade/renderer/texture/TextureVariantSet.d.ts.map +1 -0
- package/src/shade/renderer/texture/TextureVariantSet.js +105 -0
- package/src/shade/renderer/texture/download_texture_data.d.ts.map +1 -1
- package/src/shade/renderer/texture/download_texture_data.js +22 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts +15 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/gpu_texture_compression_support.js +50 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts +27 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/gpu_texture_format_can_generate_mipmaps.js +65 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts +11 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/infer_format_from_parameters.js +88 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts +24 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_format_from_shade_image.js +71 -0
- package/src/shade/renderer/texture/format/texture_format_preference.d.ts +22 -0
- package/src/shade/renderer/texture/format/texture_format_preference.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_format_preference.js +89 -0
- package/src/shade/renderer/texture/format/texture_variant_select.d.ts +24 -0
- package/src/shade/renderer/texture/format/texture_variant_select.d.ts.map +1 -0
- package/src/shade/renderer/texture/format/texture_variant_select.js +38 -0
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts +9 -1
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.d.ts.map +1 -1
- package/src/shade/renderer/texture/shade_texture_might_have_alpha.js +73 -8
- package/src/shade/renderer/texture/source/AlphaMode.d.ts +27 -0
- package/src/shade/renderer/texture/source/AlphaMode.d.ts.map +1 -0
- package/src/shade/renderer/texture/source/AlphaMode.js +52 -0
- package/src/shade/renderer/texture/source/ShadeImage.d.ts +33 -0
- package/src/shade/renderer/texture/source/ShadeImage.d.ts.map +1 -1
- package/src/shade/renderer/texture/source/ShadeImage.js +74 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.d.ts +78 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.d.ts.map +1 -0
- package/src/shade/renderer/texture/source/ShadeTexelData.js +158 -0
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts +0 -10
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.d.ts.map +1 -1
- package/src/shade/renderer/texture/texture_descriptor_from_texture_shade.js +73 -175
- package/src/shade/renderer/texture/texture_write_level.d.ts +32 -0
- package/src/shade/renderer/texture/texture_write_level.d.ts.map +1 -0
- package/src/shade/renderer/texture/texture_write_level.js +77 -0
- package/src/shade/renderer/texture/texture_write_to_gpu.d.ts +8 -1
- package/src/shade/renderer/texture/texture_write_to_gpu.d.ts.map +1 -1
- package/src/shade/renderer/texture/texture_write_to_gpu.js +62 -37
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts +8 -0
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +8 -0
- package/src/shade/util/texture_mip_extent.d.ts +49 -0
- package/src/shade/util/texture_mip_extent.d.ts.map +1 -0
- package/src/shade/util/texture_mip_extent.js +87 -0
- package/src/avif/native/isobmff/ByteCursor.d.ts.map +0 -1
- package/src/engine/asset/loaders/image/codec/Codec.d.ts.map +0 -1
- package/src/engine/asset/loaders/image/codec/CodecWithFallback.d.ts.map +0 -1
- package/src/shade/util/compute_max_mip_count.d.ts +0 -8
- package/src/shade/util/compute_max_mip_count.d.ts.map +0 -1
- package/src/shade/util/compute_max_mip_count.js +0 -27
- /package/src/engine/asset/{loaders/image/codec → codec}/Codec.d.ts +0 -0
- /package/src/engine/asset/{loaders/image/codec → codec}/Codec.js +0 -0
- /package/src/engine/asset/{loaders/image/codec → codec}/CodecWithFallback.d.ts +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The albedo the ground plane wears.
|
|
3
|
+
*
|
|
4
|
+
* A grid rather than a photograph, because what is being measured is a *per-texel* instability: the
|
|
5
|
+
* signal only exists if the texture carries energy at the texel scale, and a smooth image would
|
|
6
|
+
* hide a mip level or an anisotropy ratio that moved by a fraction. A one-texel line on a flat
|
|
7
|
+
* field is the highest-contrast thing a 256² texture can hold at its own Nyquist limit, so it is
|
|
8
|
+
* the loudest possible witness to a sampler that is not landing in the same place twice.
|
|
9
|
+
*
|
|
10
|
+
* Every filter stays {@link TextureFilterType.Linear} deliberately —
|
|
11
|
+
* `sampler_descriptor_from_shade_texture` grants 16× anisotropy only when min, mag *and* mip are
|
|
12
|
+
* all linear, and the anisotropic path is one of the quantities under suspicion. Dropping any one
|
|
13
|
+
* of them to Nearest would quietly take the sampler down to 1× and change what is being observed.
|
|
14
|
+
*
|
|
15
|
+
* An `ImageBitmap` rather than the raw `ImageData` buffer: it is the path every glTF albedo takes,
|
|
16
|
+
* so the decode, the premultiplication rule and the `rgba8unorm-srgb` format selection are the ones
|
|
17
|
+
* a real asset gets rather than a second set reached only from here.
|
|
18
|
+
*
|
|
19
|
+
* @param {number} [size] edge length in texels; a power of two so the mip chain reaches 1×1 exactly
|
|
20
|
+
* @param {boolean} [anisotropic] when false, the mip filter drops to Nearest, which is the only
|
|
21
|
+
* handle {@link ShadeTexture} offers on anisotropy — `sampler_descriptor_from_shade_texture`
|
|
22
|
+
* grants 16× only while min, mag *and* mip are all Linear, and 1× otherwise. Not a
|
|
23
|
+
* single-variable control, and the trilinear blend goes with it; what it is good for is asking
|
|
24
|
+
* whether a difference depends on the gradient-derived footprint at all.
|
|
25
|
+
* @returns {Promise<ShadeTexture>}
|
|
26
|
+
*/
|
|
27
|
+
export function make_grid_texture(size?: number, anisotropic?: boolean): Promise<ShadeTexture>;
|
|
28
|
+
import { ShadeTexture } from "../../renderer/texture/ShadeTexture.js";
|
|
29
|
+
//# sourceMappingURL=make_grid_texture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make_grid_texture.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/ground_seam/make_grid_texture.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,yCARW,MAAM,gBACN,OAAO,GAKL,QAAQ,YAAY,CAAC,CA0EjC;6BAvG4B,wCAAwC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { ColorSpace } from "../../renderer/texture/ColorSpace.js";
|
|
2
|
+
import { ShadeTexture } from "../../renderer/texture/ShadeTexture.js";
|
|
3
|
+
import { ShadeImage } from "../../renderer/texture/source/ShadeImage.js";
|
|
4
|
+
import { TextureFilterType } from "../../renderer/texture/TextureFilterType.js";
|
|
5
|
+
import { TextureWrapType } from "../../renderer/texture/TextureWrapType.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The albedo the ground plane wears.
|
|
9
|
+
*
|
|
10
|
+
* A grid rather than a photograph, because what is being measured is a *per-texel* instability: the
|
|
11
|
+
* signal only exists if the texture carries energy at the texel scale, and a smooth image would
|
|
12
|
+
* hide a mip level or an anisotropy ratio that moved by a fraction. A one-texel line on a flat
|
|
13
|
+
* field is the highest-contrast thing a 256² texture can hold at its own Nyquist limit, so it is
|
|
14
|
+
* the loudest possible witness to a sampler that is not landing in the same place twice.
|
|
15
|
+
*
|
|
16
|
+
* Every filter stays {@link TextureFilterType.Linear} deliberately —
|
|
17
|
+
* `sampler_descriptor_from_shade_texture` grants 16× anisotropy only when min, mag *and* mip are
|
|
18
|
+
* all linear, and the anisotropic path is one of the quantities under suspicion. Dropping any one
|
|
19
|
+
* of them to Nearest would quietly take the sampler down to 1× and change what is being observed.
|
|
20
|
+
*
|
|
21
|
+
* An `ImageBitmap` rather than the raw `ImageData` buffer: it is the path every glTF albedo takes,
|
|
22
|
+
* so the decode, the premultiplication rule and the `rgba8unorm-srgb` format selection are the ones
|
|
23
|
+
* a real asset gets rather than a second set reached only from here.
|
|
24
|
+
*
|
|
25
|
+
* @param {number} [size] edge length in texels; a power of two so the mip chain reaches 1×1 exactly
|
|
26
|
+
* @param {boolean} [anisotropic] when false, the mip filter drops to Nearest, which is the only
|
|
27
|
+
* handle {@link ShadeTexture} offers on anisotropy — `sampler_descriptor_from_shade_texture`
|
|
28
|
+
* grants 16× only while min, mag *and* mip are all Linear, and 1× otherwise. Not a
|
|
29
|
+
* single-variable control, and the trilinear blend goes with it; what it is good for is asking
|
|
30
|
+
* whether a difference depends on the gradient-derived footprint at all.
|
|
31
|
+
* @returns {Promise<ShadeTexture>}
|
|
32
|
+
*/
|
|
33
|
+
export async function make_grid_texture(size = 256, anisotropic = true) {
|
|
34
|
+
const canvas = document.createElement('canvas');
|
|
35
|
+
|
|
36
|
+
canvas.width = size;
|
|
37
|
+
canvas.height = size;
|
|
38
|
+
|
|
39
|
+
const ctx = canvas.getContext('2d');
|
|
40
|
+
|
|
41
|
+
// olive base — dark enough that the grid is the only high-frequency content in the image
|
|
42
|
+
ctx.fillStyle = '#3c4838';
|
|
43
|
+
ctx.fillRect(0, 0, size, size);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Cell pitch, in texels. 32 divides 256 exactly, so the pattern is continuous across the wrap
|
|
47
|
+
* seam and a tile boundary is not itself a feature.
|
|
48
|
+
*/
|
|
49
|
+
const CELL = 32;
|
|
50
|
+
|
|
51
|
+
ctx.strokeStyle = '#ffffff';
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A half-texel offset puts a 1px stroke on a texel centre rather than straddling two, which
|
|
55
|
+
* keeps the line a genuine one-texel impulse instead of a two-texel ramp.
|
|
56
|
+
*
|
|
57
|
+
* @param {number} width
|
|
58
|
+
* @param {number} pitch
|
|
59
|
+
*/
|
|
60
|
+
function rule(width, pitch) {
|
|
61
|
+
ctx.lineWidth = width;
|
|
62
|
+
|
|
63
|
+
for (let i = 0; i <= size; i += pitch) {
|
|
64
|
+
ctx.beginPath();
|
|
65
|
+
ctx.moveTo(i + 0.5, 0);
|
|
66
|
+
ctx.lineTo(i + 0.5, size);
|
|
67
|
+
ctx.stroke();
|
|
68
|
+
|
|
69
|
+
ctx.beginPath();
|
|
70
|
+
ctx.moveTo(0, i + 0.5);
|
|
71
|
+
ctx.lineTo(size, i + 0.5);
|
|
72
|
+
ctx.stroke();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
rule(1, CELL);
|
|
77
|
+
|
|
78
|
+
// every fourth cell is heavier, so the pattern has structure at two scales and a mip slip reads
|
|
79
|
+
// as a change in which of the two dominates rather than as uniform blur
|
|
80
|
+
rule(1.5, CELL * 4);
|
|
81
|
+
|
|
82
|
+
const bitmap = await createImageBitmap(canvas, {
|
|
83
|
+
// premultiplication happens during texture upload
|
|
84
|
+
premultiplyAlpha: 'none'
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const image = ShadeImage.fromImageBitmap(bitmap);
|
|
88
|
+
|
|
89
|
+
// assigned after construction, exactly as `gltf_create_material` does it — this is what selects
|
|
90
|
+
// `rgba8unorm-srgb` and therefore the free sRGB decode on sample
|
|
91
|
+
image.color_space = ColorSpace.SRGB;
|
|
92
|
+
|
|
93
|
+
const texture = ShadeTexture.from(image);
|
|
94
|
+
|
|
95
|
+
texture.label = 'ground_seam/grid';
|
|
96
|
+
|
|
97
|
+
texture.wrapS = TextureWrapType.Repeat;
|
|
98
|
+
texture.wrapT = TextureWrapType.Repeat;
|
|
99
|
+
|
|
100
|
+
texture.minFilter = TextureFilterType.Linear;
|
|
101
|
+
texture.magFilter = TextureFilterType.Linear;
|
|
102
|
+
texture.mipmapFilter = anisotropic ? TextureFilterType.Linear : TextureFilterType.Nearest;
|
|
103
|
+
|
|
104
|
+
return texture;
|
|
105
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How many times the grid texture repeats across the quad.
|
|
3
|
+
*
|
|
4
|
+
* extent/16 — one texture tile every 16 world units, which puts the 256² grid somewhere around one
|
|
5
|
+
* texel per screen pixel in the middle distance of the view this page sets up. That is the band
|
|
6
|
+
* where mip selection and anisotropy actually have to make a decision, and therefore the band where
|
|
7
|
+
* an unstable decision is visible.
|
|
8
|
+
*
|
|
9
|
+
* @param {number} extent
|
|
10
|
+
* @returns {number}
|
|
11
|
+
*/
|
|
12
|
+
export function uv_scale_for(extent: number): number;
|
|
13
|
+
/**
|
|
14
|
+
* The ground plane, and nothing else — the brief's scene reproduces with this alone.
|
|
15
|
+
*
|
|
16
|
+
* @param {object} options
|
|
17
|
+
* @param {ShadeTexture} options.albedo
|
|
18
|
+
* @param {number} [options.extent] edge length of the quad in world units. Bigger is worse
|
|
19
|
+
* conditioned: at a fixed camera height a wider quad puts its far corner closer to the eye
|
|
20
|
+
* plane, so |w| there shrinks and everything derived from it grows. The UV scale is derived
|
|
21
|
+
* from the extent, so world-space texel density — and therefore the image in the middle
|
|
22
|
+
* distance — is the same at every size, which is what makes two extents comparable at all.
|
|
23
|
+
* @param {number} [options.segments] subdivision per axis; 1 is the default two-triangle quad
|
|
24
|
+
* @param {number[]} [options.indices] index buffer override, only meaningful when `segments === 1`
|
|
25
|
+
* @param {number} [options.yaw_degrees] rotation about +Y, applied after the quad is laid flat
|
|
26
|
+
* @param {number} [options.roughness]
|
|
27
|
+
* @param {number} [options.metallic]
|
|
28
|
+
* @returns {Mesh}
|
|
29
|
+
*/
|
|
30
|
+
export function make_ground({ albedo, segments, indices, extent, yaw_degrees, roughness, metallic, }: {
|
|
31
|
+
albedo: ShadeTexture;
|
|
32
|
+
extent?: number;
|
|
33
|
+
segments?: number;
|
|
34
|
+
indices?: number[];
|
|
35
|
+
yaw_degrees?: number;
|
|
36
|
+
roughness?: number;
|
|
37
|
+
metallic?: number;
|
|
38
|
+
}): Mesh;
|
|
39
|
+
/**
|
|
40
|
+
* Edge length of the ground quad, in world units.
|
|
41
|
+
* @type {number}
|
|
42
|
+
*/
|
|
43
|
+
export const GROUND_EXTENT: number;
|
|
44
|
+
/**
|
|
45
|
+
* How `make_plane_geometry` triangulates its default 1×1 quad, and the other way it could have.
|
|
46
|
+
*
|
|
47
|
+
* The vertices it emits, in the plane's own XY (before the −90° X rotation that lays it flat):
|
|
48
|
+
*
|
|
49
|
+
* ```
|
|
50
|
+
* v0 (−212.5, +212.5) v1 (+212.5, +212.5)
|
|
51
|
+
* v2 (−212.5, −212.5) v3 (+212.5, −212.5)
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* The default is `(0,2,1)` and `(2,3,1)`, whose shared edge is v2→v1 — the diagonal that becomes
|
|
55
|
+
* the world line **x = −z** once the quad is laid flat. {@link GROUND_TRIANGULATION.flipped } is the
|
|
56
|
+
* same four vertices, the same UVs and the same winding across the *other* diagonal, v0→v3, which
|
|
57
|
+
* is the world line **x = z**.
|
|
58
|
+
*
|
|
59
|
+
* Both windings were checked by hand: every triangle in both lists has a positive Z cross product
|
|
60
|
+
* in plane-local XY, so nothing here changes which face is front.
|
|
61
|
+
*/
|
|
62
|
+
export type GROUND_TRIANGULATION = number[];
|
|
63
|
+
export namespace GROUND_TRIANGULATION {
|
|
64
|
+
let _default: number[];
|
|
65
|
+
export { _default as default };
|
|
66
|
+
export let flipped: number[];
|
|
67
|
+
export let rotated: number[];
|
|
68
|
+
}
|
|
69
|
+
import { Mesh } from "../../renderer/scene/Mesh.js";
|
|
70
|
+
//# sourceMappingURL=make_ground.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make_ground.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/ground_seam/make_ground.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;GAUG;AACH,qCAHW,MAAM,GACJ,MAAM,CAIlB;AAyCD;;;;;;;;;;;;;;;;GAgBG;AACH;IAbiC,MAAM;IACX,MAAM,GAAvB,MAAM;IAKW,QAAQ,GAAzB,MAAM;IACa,OAAO,GAA1B,MAAM,EAAE;IACS,WAAW,GAA5B,MAAM;IACW,SAAS,GAA1B,MAAM;IACW,QAAQ,GAAzB,MAAM;IACJ,IAAI,CA2EhB;AAtJD;;;GAGG;AACH,4BAFU,MAAM,CAEiB;;;;;;;;;;;;;;;;;;;mCAmCvB,MAAM,EAAE;;;;;;;qBAzCG,8BAA8B"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
2
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
3
|
+
import { Attribute } from "../../renderer/geometry/Attribute.js";
|
|
4
|
+
import { meshlet_geometry_build_from_geometry } from "../../renderer/geometry/meshlet_geometry_build_from_geometry.js";
|
|
5
|
+
import { MeshletGeometry } from "../../renderer/geometry/MeshletGeometry.js";
|
|
6
|
+
import { make_plane_geometry } from "../../renderer/geometry/primitives/make_plane_geometry.js";
|
|
7
|
+
import { StandardAttributes } from "../../renderer/geometry/StandardAttributes.js";
|
|
8
|
+
import { StandardShadeMaterial } from "../../renderer/material/StandardShadeMaterial.js";
|
|
9
|
+
import { Mesh } from "../../renderer/scene/Mesh.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Edge length of the ground quad, in world units.
|
|
13
|
+
* @type {number}
|
|
14
|
+
*/
|
|
15
|
+
export const GROUND_EXTENT = 425;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* How many times the grid texture repeats across the quad.
|
|
19
|
+
*
|
|
20
|
+
* extent/16 — one texture tile every 16 world units, which puts the 256² grid somewhere around one
|
|
21
|
+
* texel per screen pixel in the middle distance of the view this page sets up. That is the band
|
|
22
|
+
* where mip selection and anisotropy actually have to make a decision, and therefore the band where
|
|
23
|
+
* an unstable decision is visible.
|
|
24
|
+
*
|
|
25
|
+
* @param {number} extent
|
|
26
|
+
* @returns {number}
|
|
27
|
+
*/
|
|
28
|
+
export function uv_scale_for(extent) {
|
|
29
|
+
return extent / 16;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* How `make_plane_geometry` triangulates its default 1×1 quad, and the other way it could have.
|
|
34
|
+
*
|
|
35
|
+
* The vertices it emits, in the plane's own XY (before the −90° X rotation that lays it flat):
|
|
36
|
+
*
|
|
37
|
+
* ```
|
|
38
|
+
* v0 (−212.5, +212.5) v1 (+212.5, +212.5)
|
|
39
|
+
* v2 (−212.5, −212.5) v3 (+212.5, −212.5)
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* The default is `(0,2,1)` and `(2,3,1)`, whose shared edge is v2→v1 — the diagonal that becomes
|
|
43
|
+
* the world line **x = −z** once the quad is laid flat. {@link GROUND_TRIANGULATION.flipped} is the
|
|
44
|
+
* same four vertices, the same UVs and the same winding across the *other* diagonal, v0→v3, which
|
|
45
|
+
* is the world line **x = z**.
|
|
46
|
+
*
|
|
47
|
+
* Both windings were checked by hand: every triangle in both lists has a positive Z cross product
|
|
48
|
+
* in plane-local XY, so nothing here changes which face is front.
|
|
49
|
+
*
|
|
50
|
+
* @enum {number[]}
|
|
51
|
+
*/
|
|
52
|
+
export const GROUND_TRIANGULATION = {
|
|
53
|
+
default: [0, 2, 1, 2, 3, 1],
|
|
54
|
+
flipped: [0, 2, 3, 0, 3, 1],
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The **same two triangles** as `default`, each cyclically rotated so a different corner is
|
|
58
|
+
* first. Same diagonal, same winding, same three vertices per face — only which one the
|
|
59
|
+
* reconstruction anchors on changes.
|
|
60
|
+
*
|
|
61
|
+
* `chunk_barycentric_full` builds every pixel's barycentric from `pixel - ndc0` and divides by
|
|
62
|
+
* `determinant(mat2x2(ndc2 - ndc1, ndc0 - ndc1))`, so vertex 0 is the origin the whole
|
|
63
|
+
* reconstruction is measured from and the other two set the scale. In exact arithmetic a
|
|
64
|
+
* rotation changes nothing. In f32 it changes which differences are formed and therefore how
|
|
65
|
+
* they round — which is exactly the quantity a per-triangle instability would be made of, and
|
|
66
|
+
* the one thing that can be varied without varying the geometry, the UVs or the coverage.
|
|
67
|
+
*/
|
|
68
|
+
rotated: [2, 1, 0, 3, 1, 2],
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The ground plane, and nothing else — the brief's scene reproduces with this alone.
|
|
73
|
+
*
|
|
74
|
+
* @param {object} options
|
|
75
|
+
* @param {ShadeTexture} options.albedo
|
|
76
|
+
* @param {number} [options.extent] edge length of the quad in world units. Bigger is worse
|
|
77
|
+
* conditioned: at a fixed camera height a wider quad puts its far corner closer to the eye
|
|
78
|
+
* plane, so |w| there shrinks and everything derived from it grows. The UV scale is derived
|
|
79
|
+
* from the extent, so world-space texel density — and therefore the image in the middle
|
|
80
|
+
* distance — is the same at every size, which is what makes two extents comparable at all.
|
|
81
|
+
* @param {number} [options.segments] subdivision per axis; 1 is the default two-triangle quad
|
|
82
|
+
* @param {number[]} [options.indices] index buffer override, only meaningful when `segments === 1`
|
|
83
|
+
* @param {number} [options.yaw_degrees] rotation about +Y, applied after the quad is laid flat
|
|
84
|
+
* @param {number} [options.roughness]
|
|
85
|
+
* @param {number} [options.metallic]
|
|
86
|
+
* @returns {Mesh}
|
|
87
|
+
*/
|
|
88
|
+
export function make_ground({
|
|
89
|
+
albedo,
|
|
90
|
+
segments = 1,
|
|
91
|
+
indices = GROUND_TRIANGULATION.default,
|
|
92
|
+
extent = GROUND_EXTENT,
|
|
93
|
+
yaw_degrees = 0,
|
|
94
|
+
roughness = 0.95,
|
|
95
|
+
metallic = 0,
|
|
96
|
+
}) {
|
|
97
|
+
|
|
98
|
+
const geometry = make_plane_geometry(extent, extent, segments, segments);
|
|
99
|
+
|
|
100
|
+
// The texture has to tile, and it has to tile by exactly the same amount however the quad is
|
|
101
|
+
// cut up — a subdivided plane that sampled the texture differently would confound "subdivision
|
|
102
|
+
// fixes it" with "subdivision changed the shading".
|
|
103
|
+
const uv = geometry.getAttribute(StandardAttributes.TextureCoordinates0);
|
|
104
|
+
|
|
105
|
+
for (let i = 0; i < uv.data.length; i++) {
|
|
106
|
+
uv.data[i] *= uv_scale_for(extent);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (segments === 1) {
|
|
110
|
+
/*
|
|
111
|
+
Same vertices, same UVs, same winding. Which pairs of corners are joined is the A/B the
|
|
112
|
+
brief calls its first positive result; which corner comes first within a face is the
|
|
113
|
+
finer one, and both are just this index buffer.
|
|
114
|
+
*/
|
|
115
|
+
geometry.index = Attribute.from(new Uint32Array(indices), 1, StandardAttributes.Index);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const mesh = new Mesh();
|
|
119
|
+
|
|
120
|
+
mesh.name = 'ground';
|
|
121
|
+
mesh.geometry = new MeshletGeometry();
|
|
122
|
+
|
|
123
|
+
meshlet_geometry_build_from_geometry(geometry, mesh.geometry);
|
|
124
|
+
|
|
125
|
+
const material = new StandardShadeMaterial();
|
|
126
|
+
|
|
127
|
+
material.texture_albedo = albedo;
|
|
128
|
+
material.roughness_factor = roughness;
|
|
129
|
+
material.metallic_factor = metallic;
|
|
130
|
+
|
|
131
|
+
mesh.material = material;
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
−90° about X lays the plane flat with its normal pointing at +Y.
|
|
135
|
+
|
|
136
|
+
A yaw on top of that is the control that separates *which diagonal the seam lies on* from
|
|
137
|
+
*which of the two triangles is which*. 180° is a symmetry of both the quad and the shared edge
|
|
138
|
+
— the world line x = −z maps to itself — but it exchanges the triangles' corners: the one whose
|
|
139
|
+
odd vertex sat behind the eye plane now has two there, and the other way round. So the seam
|
|
140
|
+
stays exactly where it was on screen while the two triangles swap roles, which is the one
|
|
141
|
+
experiment that can tell a property of the *edge* from a property of a *triangle*.
|
|
142
|
+
|
|
143
|
+
`Transform64` keeps its matrix by hand, so the write is only real after `updateMatrix`, and the
|
|
144
|
+
world bounds the `meshes` table publishes only exist after `updateMatrices` — a mesh added on
|
|
145
|
+
its own is never reached by the scene's hierarchy walk.
|
|
146
|
+
*/
|
|
147
|
+
const rotation = Quaternion.fromAxisAngle(Vector3.right, -Math.PI / 2);
|
|
148
|
+
|
|
149
|
+
if (yaw_degrees !== 0) {
|
|
150
|
+
const yaw = Quaternion.fromAxisAngle(Vector3.up, yaw_degrees * Math.PI / 180);
|
|
151
|
+
|
|
152
|
+
rotation.multiplyQuaternions(yaw, rotation);
|
|
153
|
+
rotation.normalize();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
mesh.transform_local.setRotation(rotation.x, rotation.y, rotation.z, rotation.w);
|
|
157
|
+
mesh.transform_local.updateMatrix();
|
|
158
|
+
mesh.updateMatrices();
|
|
159
|
+
|
|
160
|
+
return mesh;
|
|
161
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which of the ground quad's two triangles covers each pixel, and where on the plane it lands.
|
|
3
|
+
*
|
|
4
|
+
* The classification is `sign(x + z)`: the default triangulation's shared edge is the world line
|
|
5
|
+
* `x = −z` (v2→v1 of `make_plane_geometry`'s 1×1 quad, laid flat by the −90° X rotation), so the
|
|
6
|
+
* two triangles are exactly the two sides of `x + z = 0`. For the flipped index buffer the shared
|
|
7
|
+
* edge is `x = z` instead, so `side_flipped` carries `sign(x − z)` alongside it and a caller can
|
|
8
|
+
* ask about whichever diagonal is currently in the mesh.
|
|
9
|
+
*
|
|
10
|
+
* @param {PerspectiveCamera} camera must already have had `update_matrices` run for this frame
|
|
11
|
+
* @param {number} width in pixels
|
|
12
|
+
* @param {number} height in pixels
|
|
13
|
+
* @param {number} [extent] half-width of the quad; pixels outside it are not ground
|
|
14
|
+
* @returns {{side: Int8Array, side_flipped: Int8Array, round_trip_error_px: number, covered: number}}
|
|
15
|
+
* `side` is −1, +1 or 0 (not ground). `round_trip_error_px` is the worst error, in pixels, from
|
|
16
|
+
* projecting a recovered world point back through the forward matrix — a sanity check on the whole
|
|
17
|
+
* convention, which should be a small fraction of a pixel.
|
|
18
|
+
*/
|
|
19
|
+
export function classify_ground(camera: PerspectiveCamera, width: number, height: number, extent?: number): {
|
|
20
|
+
side: Int8Array;
|
|
21
|
+
side_flipped: Int8Array;
|
|
22
|
+
round_trip_error_px: number;
|
|
23
|
+
covered: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Owns the render target, the readback buffer, and the frame-driving loop.
|
|
27
|
+
*
|
|
28
|
+
* @param {object} context
|
|
29
|
+
* @param {Renderer} context.renderer
|
|
30
|
+
* @param {Scene} context.scene
|
|
31
|
+
* @param {PerspectiveCamera} context.camera
|
|
32
|
+
*/
|
|
33
|
+
export function attach_measurement({ renderer, scene, camera }: {
|
|
34
|
+
renderer: Renderer;
|
|
35
|
+
scene: Scene;
|
|
36
|
+
camera: PerspectiveCamera;
|
|
37
|
+
}): {
|
|
38
|
+
frame: (time_delta_s?: number) => void;
|
|
39
|
+
settle: (n: number) => Promise<void>;
|
|
40
|
+
burst: ({ settle_frames, frames }?: {
|
|
41
|
+
settle_frames?: number;
|
|
42
|
+
frames?: number;
|
|
43
|
+
}) => Promise<{
|
|
44
|
+
spread: Float32Array;
|
|
45
|
+
mean: Float32Array;
|
|
46
|
+
width: number;
|
|
47
|
+
height: number;
|
|
48
|
+
}>;
|
|
49
|
+
read_depth: () => Promise<{
|
|
50
|
+
depth: Float32Array;
|
|
51
|
+
width: number;
|
|
52
|
+
height: number;
|
|
53
|
+
}>;
|
|
54
|
+
readonly capture: any;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Where a world-space line on the ground plane lands on screen, as a signed-distance function.
|
|
58
|
+
*
|
|
59
|
+
* A projective map takes a straight line to a straight line, so two projected points are the whole
|
|
60
|
+
* of it. This exists so a profile can be taken *across* the seam in pixels: the half-plane means a
|
|
61
|
+
* split reports cannot tell a step at the boundary from a smooth gradient over the whole frame, and
|
|
62
|
+
* that is exactly the difference between "a seam" and "one half of the view is more oblique".
|
|
63
|
+
*
|
|
64
|
+
* @param {PerspectiveCamera} camera
|
|
65
|
+
* @param {number} width
|
|
66
|
+
* @param {number} height
|
|
67
|
+
* @param {number[]} direction unit direction of the line in the XZ plane
|
|
68
|
+
* @returns {function(number, number): number} pixel → signed perpendicular distance, in pixels
|
|
69
|
+
*/
|
|
70
|
+
export function screen_line_distance(camera: PerspectiveCamera, width: number, height: number, direction: number[]): (arg0: number, arg1: number) => number;
|
|
71
|
+
//# sourceMappingURL=measure_flicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measure_flicker.d.ts","sourceRoot":"","sources":["../../../../../src/shade/playground/ground_seam/measure_flicker.js"],"names":[],"mappings":"AAkDA;;;;;;;;;;;;;;;;;GAiBG;AACH,kEARW,MAAM,UACN,MAAM,WACN,MAAM;UACG,SAAS;kBAAgB,SAAS;yBAAuB,MAAM;aAAW,MAAM;EAmHnG;AAED;;;;;;;GAOG;AACH;IAJ6B,QAAQ;IACX,KAAK;IACO,MAAM;;2BAqE7B,MAAM;gBAQN,MAAM;;QAoFW,aAAa,GAA9B,MAAM;QACW,MAAM,GAAvB,MAAM;;gBACa,YAAY;cAAQ,YAAY;eAAS,MAAM;gBAAU,MAAM;;;eA4DhE,YAAY;eAAS,MAAM;gBAAU,MAAM;;;EAkE3E;AAED;;;;;;;;;;;;;GAaG;AACH,uEALW,MAAM,UACN,MAAM,aACN,MAAM,EAAE,UACG,MAAM,QAAE,MAAM,KAAG,MAAM,CAyC5C"}
|