@luma.gl/gltf 9.3.0-alpha.8 → 9.3.0
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/dist/dist.dev.js +4396 -3081
- package/dist/dist.min.js +33 -14
- package/dist/gltf/animations/animations.d.ts +43 -3
- package/dist/gltf/animations/animations.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.d.ts +2 -0
- package/dist/gltf/animations/interpolate.d.ts.map +1 -1
- package/dist/gltf/animations/interpolate.js +27 -22
- package/dist/gltf/animations/interpolate.js.map +1 -1
- package/dist/gltf/create-gltf-model.d.ts.map +1 -1
- package/dist/gltf/create-gltf-model.js +29 -10
- package/dist/gltf/create-gltf-model.js.map +1 -1
- package/dist/gltf/create-scenegraph-from-gltf.js +2 -2
- package/dist/gltf/create-scenegraph-from-gltf.js.map +1 -1
- package/dist/gltf/gltf-animator.d.ts +12 -1
- package/dist/gltf/gltf-animator.d.ts.map +1 -1
- package/dist/gltf/gltf-animator.js +98 -6
- package/dist/gltf/gltf-animator.js.map +1 -1
- package/dist/gltf/gltf-extension-support.d.ts +3 -0
- package/dist/gltf/gltf-extension-support.d.ts.map +1 -1
- package/dist/gltf/gltf-extension-support.js +10 -5
- package/dist/gltf/gltf-extension-support.js.map +1 -1
- package/dist/index.cjs +763 -272
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/parsers/parse-gltf-animations.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-animations.js +319 -18
- package/dist/parsers/parse-gltf-animations.js.map +1 -1
- package/dist/parsers/parse-gltf-lights.d.ts +6 -2
- package/dist/parsers/parse-gltf-lights.d.ts.map +1 -1
- package/dist/parsers/parse-gltf-lights.js +9 -6
- package/dist/parsers/parse-gltf-lights.js.map +1 -1
- package/dist/parsers/parse-gltf.d.ts +2 -0
- package/dist/parsers/parse-gltf.d.ts.map +1 -1
- package/dist/parsers/parse-gltf.js +21 -7
- package/dist/parsers/parse-gltf.js.map +1 -1
- package/dist/parsers/parse-pbr-material.d.ts.map +1 -1
- package/dist/parsers/parse-pbr-material.js +114 -81
- package/dist/parsers/parse-pbr-material.js.map +1 -1
- package/dist/pbr/pbr-environment.d.ts.map +1 -1
- package/dist/pbr/pbr-environment.js +7 -3
- package/dist/pbr/pbr-environment.js.map +1 -1
- package/dist/pbr/texture-transform.d.ts +24 -0
- package/dist/pbr/texture-transform.d.ts.map +1 -0
- package/dist/pbr/texture-transform.js +98 -0
- package/dist/pbr/texture-transform.js.map +1 -0
- package/dist/webgl-to-webgpu/convert-webgl-topology.js +1 -1
- package/dist/webgl-to-webgpu/convert-webgl-topology.js.map +1 -1
- package/package.json +5 -5
- package/src/gltf/animations/animations.ts +73 -3
- package/src/gltf/animations/interpolate.ts +50 -43
- package/src/gltf/create-gltf-model.ts +29 -10
- package/src/gltf/create-scenegraph-from-gltf.ts +2 -2
- package/src/gltf/gltf-animator.ts +177 -8
- package/src/gltf/gltf-extension-support.ts +17 -5
- package/src/index.ts +1 -1
- package/src/parsers/parse-gltf-animations.ts +461 -21
- package/src/parsers/parse-gltf-lights.ts +27 -8
- package/src/parsers/parse-gltf.ts +23 -7
- package/src/parsers/parse-pbr-material.ts +184 -79
- package/src/pbr/pbr-environment.ts +10 -3
- package/src/pbr/texture-transform.ts +263 -0
- package/src/webgl-to-webgpu/convert-webgl-topology.ts +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/index.ts", "../src/pbr/pbr-environment.ts", "../src/parsers/parse-pbr-material.ts", "../src/webgl-to-webgpu/gltf-webgl-constants.ts", "../src/webgl-to-webgpu/convert-webgl-sampler.ts", "../src/parsers/parse-gltf-lights.ts", "../src/parsers/parse-gltf.ts", "../src/webgl-to-webgpu/convert-webgl-topology.ts", "../src/gltf/create-gltf-model.ts", "../src/gltf/gltf-animator.ts", "../src/gltf/animations/interpolate.ts", "../src/parsers/parse-gltf-animations.ts", "../src/
|
|
4
|
-
"sourcesContent": ["// luma.gl, MIT license\n\nexport {loadPBREnvironment, type PBREnvironment} from './pbr/pbr-environment';\nexport {type ParsedPBRMaterial} from './pbr/pbr-material';\nexport {parsePBRMaterial, type ParsePBRMaterialOptions} from './parsers/parse-pbr-material';\nexport {parseGLTFLights} from './parsers/parse-gltf-lights';\n\n// glTF Scenegraph Instantiator\nexport {\n createScenegraphsFromGLTF,\n type GLTFScenegraphBounds,\n type GLTFScenegraphs\n} from './gltf/create-scenegraph-from-gltf';\nexport {\n getGLTFExtensionSupport,\n type GLTFExtensionSupport,\n type GLTFExtensionSupportLevel\n} from './gltf/gltf-extension-support';\nexport {GLTFAnimator} from './gltf/gltf-animator';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, SamplerProps} from '@luma.gl/core';\nimport {\n DynamicTexture,\n type Texture2DData,\n type TextureCubeData,\n type TextureCubeFace\n} from '@luma.gl/engine';\nimport {loadImageTexture} from '@loaders.gl/textures';\n\n/** Environment textures for PBR module */\nexport type PBREnvironment = {\n /** Bi-directional Reflectance Distribution Function (BRDF) lookup table */\n brdfLutTexture: DynamicTexture;\n /** Diffuse irradiance cubemap. */\n diffuseEnvSampler: DynamicTexture;\n /** Specular reflection cubemap with mip chain. */\n specularEnvSampler: DynamicTexture;\n};\n\n/** Configuration used to load an image-based lighting environment. */\nexport type PBREnvironmentProps = {\n /** URL of the BRDF lookup texture. */\n brdfLutUrl: string;\n /** Callback that returns the URL for a diffuse or specular cubemap face and mip level. */\n getTexUrl: (name: string, dir: number, level: number) => string;\n /** Number of mip levels in the specular environment map. */\n specularMipLevels?: number;\n};\n\n/** Loads textures for PBR environment */\nexport function loadPBREnvironment(device: Device, props: PBREnvironmentProps): PBREnvironment {\n const specularMipLevels = props.specularMipLevels ?? 1;\n\n const brdfLutTexture = new DynamicTexture(device, {\n id: 'brdfLUT',\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps,\n // Texture accepts a promise that returns an image as data (Async Textures)\n data: loadImageTexture(props.brdfLutUrl)\n });\n\n const diffuseEnvSampler = makeCube(device, {\n id: 'DiffuseEnvSampler',\n getTextureForFace: face =>\n loadImageTexture(\n props.getTexUrl('diffuse', FACES.indexOf(face), 0)\n ) as Promise<Texture2DData>,\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n const specularEnvSampler = makeCube(device, {\n id: 'SpecularEnvSampler',\n getTextureForFace: (face: TextureCubeFace) => {\n const imageArray: Array<Promise<unknown>> = [];\n const direction = FACES.indexOf(face);\n for (let lod = 0; lod < specularMipLevels; lod++) {\n imageArray.push(loadImageTexture(props.getTexUrl('specular', direction, lod)));\n }\n return Promise.all(imageArray) as Promise<Texture2DData>;\n },\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear', // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR_MIPMAP_LINEAR,\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n return {\n brdfLutTexture,\n diffuseEnvSampler,\n specularEnvSampler\n };\n}\n\n// TODO put somewhere common\nconst FACES: TextureCubeFace[] = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'];\n\n/** Construction props for an asynchronously loaded cubemap. */\nfunction makeCube(\n device: Device,\n {\n id,\n getTextureForFace,\n sampler\n }: {\n /** Debug id assigned to the created texture. */\n id: string;\n /** Returns the image or mip-array promise for one cubemap face. */\n getTextureForFace: (face: TextureCubeFace) => Promise<Texture2DData>;\n /** Sampler configuration shared across faces. */\n sampler: SamplerProps;\n }\n): DynamicTexture {\n const data: Promise<TextureCubeData> = Promise.all(\n FACES.map(face => getTextureForFace(face))\n ).then(faceDataArray => {\n const cubeData = {} as TextureCubeData;\n FACES.forEach((face, index) => {\n cubeData[face] = faceDataArray[index];\n });\n return cubeData;\n });\n return new DynamicTexture(device, {\n id,\n dimension: 'cube',\n mipmaps: false,\n sampler,\n data\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Device, SamplerProps, TextureFormat, TypedArray} from '@luma.gl/core';\nimport {Texture, log, textureFormatDecoder} from '@luma.gl/core';\nimport type {GLTFPostprocessed, GLTFSampler} from '@loaders.gl/gltf';\n\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {type PBRMaterialBindings} from '@luma.gl/shadertools';\nimport {GLEnum} from '../webgl-to-webgpu/gltf-webgl-constants';\nimport {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';\n\n// TODO - synchronize the GLTF... types with loaders.gl\n// TODO - remove the glParameters, use only parameters\n\n/* eslint-disable camelcase */\n\ntype GLTFTexture = {\n id: string;\n index?: number;\n texture: {source: {image: any}; sampler: {parameters: any}};\n uniformName?: string;\n // is this on all textures?\n scale?: number;\n // is this on all textures?\n strength?: number;\n};\n\ntype GLTFPBRMetallicRoughness = {\n baseColorTexture?: GLTFTexture;\n baseColorFactor?: [number, number, number, number];\n metallicRoughnessTexture?: GLTFTexture;\n metallicFactor?: number;\n roughnessFactor?: number;\n};\n\ntype GLTFPBRMaterial = {\n extensions?: GLTFMaterialExtensions;\n unlit?: boolean;\n pbrMetallicRoughness?: GLTFPBRMetallicRoughness;\n normalTexture?: GLTFTexture;\n occlusionTexture?: GLTFTexture;\n emissiveTexture?: GLTFTexture;\n emissiveFactor?: [number, number, number];\n alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';\n doubleSided?: boolean;\n alphaCutoff?: number;\n};\n\ntype GLTFMaterialSpecularExtension = {\n specularFactor?: number;\n specularTexture?: GLTFTexture;\n specularColorFactor?: [number, number, number];\n specularColorTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialIorExtension = {\n ior?: number;\n};\n\ntype GLTFMaterialTransmissionExtension = {\n transmissionFactor?: number;\n transmissionTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialVolumeExtension = {\n thicknessFactor?: number;\n thicknessTexture?: GLTFTexture;\n attenuationDistance?: number;\n attenuationColor?: [number, number, number];\n};\n\ntype GLTFMaterialClearcoatExtension = {\n clearcoatFactor?: number;\n clearcoatTexture?: GLTFTexture;\n clearcoatRoughnessFactor?: number;\n clearcoatRoughnessTexture?: GLTFTexture;\n clearcoatNormalTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialSheenExtension = {\n sheenColorFactor?: [number, number, number];\n sheenColorTexture?: GLTFTexture;\n sheenRoughnessFactor?: number;\n sheenRoughnessTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialIridescenceExtension = {\n iridescenceFactor?: number;\n iridescenceTexture?: GLTFTexture;\n iridescenceIor?: number;\n iridescenceThicknessMinimum?: number;\n iridescenceThicknessMaximum?: number;\n iridescenceThicknessTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialAnisotropyExtension = {\n anisotropyStrength?: number;\n anisotropyRotation?: number;\n anisotropyTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialEmissiveStrengthExtension = {\n emissiveStrength?: number;\n};\n\ntype GLTFMaterialExtensions = {\n KHR_materials_unlit?: Record<string, never>;\n KHR_materials_specular?: GLTFMaterialSpecularExtension;\n KHR_materials_ior?: GLTFMaterialIorExtension;\n KHR_materials_transmission?: GLTFMaterialTransmissionExtension;\n KHR_materials_volume?: GLTFMaterialVolumeExtension;\n KHR_materials_clearcoat?: GLTFMaterialClearcoatExtension;\n KHR_materials_sheen?: GLTFMaterialSheenExtension;\n KHR_materials_iridescence?: GLTFMaterialIridescenceExtension;\n KHR_materials_anisotropy?: GLTFMaterialAnisotropyExtension;\n KHR_materials_emissive_strength?: GLTFMaterialEmissiveStrengthExtension;\n};\n\ntype TextureEnabledUniformName =\n | 'baseColorMapEnabled'\n | 'normalMapEnabled'\n | 'emissiveMapEnabled'\n | 'metallicRoughnessMapEnabled'\n | 'occlusionMapEnabled'\n | 'specularColorMapEnabled'\n | 'specularIntensityMapEnabled'\n | 'transmissionMapEnabled'\n | 'clearcoatMapEnabled'\n | 'clearcoatRoughnessMapEnabled'\n | 'sheenColorMapEnabled'\n | 'sheenRoughnessMapEnabled'\n | 'iridescenceMapEnabled'\n | 'anisotropyMapEnabled';\n\ntype TextureFeatureOptions = {\n define?: string;\n enabledUniformName?: TextureEnabledUniformName;\n};\n\ntype TextureParseOptions = {\n featureOptions?: TextureFeatureOptions;\n gltf?: GLTFPostprocessed;\n};\n\nexport type ParsePBRMaterialOptions = {\n /** Debug PBR shader */\n pbrDebug?: boolean;\n /** Enable lights */\n lights?: any;\n /** Use tangents */\n useTangents?: boolean;\n /** provide an image based (texture cube) lighting environment */\n imageBasedLightingEnvironment?: PBREnvironment;\n /** parent post-processed glTF, used to resolve extension texture infos */\n gltf?: GLTFPostprocessed;\n /** run primitive-attribute diagnostics such as missing TEXCOORD_0 / NORMAL */\n validateAttributes?: boolean;\n};\n\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n */\nexport function parsePBRMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n attributes: Record<string, any>,\n options: ParsePBRMaterialOptions\n): ParsedPBRMaterial {\n const parsedMaterial: ParsedPBRMaterial = {\n defines: {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n },\n bindings: {},\n uniforms: {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n },\n parameters: {},\n glParameters: {},\n generatedTextures: []\n };\n\n // TODO - always available\n parsedMaterial.defines['USE_TEX_LOD'] = true;\n\n const {imageBasedLightingEnvironment} = options;\n if (imageBasedLightingEnvironment) {\n parsedMaterial.bindings.pbr_diffuseEnvSampler =\n imageBasedLightingEnvironment.diffuseEnvSampler.texture;\n parsedMaterial.bindings.pbr_specularEnvSampler =\n imageBasedLightingEnvironment.specularEnvSampler.texture;\n parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;\n parsedMaterial.uniforms.IBLenabled = true;\n parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (options?.pbrDebug) {\n parsedMaterial.defines['PBR_DEBUG'] = true;\n // Override final color for reference app visualization of various parameters in the lighting equation.\n parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n if (attributes['NORMAL']) parsedMaterial.defines['HAS_NORMALS'] = true;\n if (attributes['TANGENT'] && options?.useTangents) parsedMaterial.defines['HAS_TANGENTS'] = true;\n if (attributes['TEXCOORD_0']) parsedMaterial.defines['HAS_UV'] = true;\n if (attributes['JOINTS_0'] && attributes['WEIGHTS_0']) parsedMaterial.defines['HAS_SKIN'] = true;\n if (attributes['COLOR_0']) parsedMaterial.defines['HAS_COLORS'] = true;\n\n if (options?.imageBasedLightingEnvironment) parsedMaterial.defines['USE_IBL'] = true;\n if (options?.lights) parsedMaterial.defines['USE_LIGHTS'] = true;\n\n if (material) {\n if (options.validateAttributes !== false) {\n warnOnMissingExpectedAttributes(material, attributes);\n }\n parseMaterial(device, material, parsedMaterial, options.gltf);\n }\n\n return parsedMaterial;\n}\n\nfunction warnOnMissingExpectedAttributes(\n material: GLTFPBRMaterial,\n attributes: Record<string, any>\n): void {\n const uvDependentTextureSlots = getUvDependentTextureSlots(material);\n if (uvDependentTextureSlots.length > 0 && !attributes['TEXCOORD_0']) {\n log.warn(\n `glTF material uses ${uvDependentTextureSlots.join(', ')} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`\n )();\n }\n\n const isUnlitMaterial = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);\n if (isUnlitMaterial || attributes['NORMAL']) {\n return;\n }\n\n const missingNormalReason = material.normalTexture\n ? 'lit PBR shading with normalTexture'\n : 'lit PBR shading';\n log.warn(\n `glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`\n )();\n}\n\nfunction getUvDependentTextureSlots(material: GLTFPBRMaterial): string[] {\n const uvDependentTextureSlots: string[] = [];\n\n if (material.pbrMetallicRoughness?.baseColorTexture) {\n uvDependentTextureSlots.push('baseColorTexture');\n }\n if (material.pbrMetallicRoughness?.metallicRoughnessTexture) {\n uvDependentTextureSlots.push('metallicRoughnessTexture');\n }\n if (material.normalTexture) {\n uvDependentTextureSlots.push('normalTexture');\n }\n if (material.occlusionTexture) {\n uvDependentTextureSlots.push('occlusionTexture');\n }\n if (material.emissiveTexture) {\n uvDependentTextureSlots.push('emissiveTexture');\n }\n if (material.extensions?.KHR_materials_specular?.specularTexture) {\n uvDependentTextureSlots.push('KHR_materials_specular.specularTexture');\n }\n if (material.extensions?.KHR_materials_specular?.specularColorTexture) {\n uvDependentTextureSlots.push('KHR_materials_specular.specularColorTexture');\n }\n if (material.extensions?.KHR_materials_transmission?.transmissionTexture) {\n uvDependentTextureSlots.push('KHR_materials_transmission.transmissionTexture');\n }\n if (material.extensions?.KHR_materials_clearcoat?.clearcoatTexture) {\n uvDependentTextureSlots.push('KHR_materials_clearcoat.clearcoatTexture');\n }\n if (material.extensions?.KHR_materials_clearcoat?.clearcoatRoughnessTexture) {\n uvDependentTextureSlots.push('KHR_materials_clearcoat.clearcoatRoughnessTexture');\n }\n if (material.extensions?.KHR_materials_sheen?.sheenColorTexture) {\n uvDependentTextureSlots.push('KHR_materials_sheen.sheenColorTexture');\n }\n if (material.extensions?.KHR_materials_sheen?.sheenRoughnessTexture) {\n uvDependentTextureSlots.push('KHR_materials_sheen.sheenRoughnessTexture');\n }\n if (material.extensions?.KHR_materials_iridescence?.iridescenceTexture) {\n uvDependentTextureSlots.push('KHR_materials_iridescence.iridescenceTexture');\n }\n if (material.extensions?.KHR_materials_anisotropy?.anisotropyTexture) {\n uvDependentTextureSlots.push('KHR_materials_anisotropy.anisotropyTexture');\n }\n\n return uvDependentTextureSlots;\n}\n\n/** Parse GLTF material record */\nfunction parseMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n parsedMaterial.uniforms.unlit = Boolean(\n material.unlit || material.extensions?.KHR_materials_unlit\n );\n\n if (material.pbrMetallicRoughness) {\n parsePbrMetallicRoughness(device, material.pbrMetallicRoughness, parsedMaterial, gltf);\n }\n if (material.normalTexture) {\n addTexture(device, material.normalTexture, 'pbr_normalSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_NORMALMAP',\n enabledUniformName: 'normalMapEnabled'\n },\n gltf\n });\n\n const {scale = 1} = material.normalTexture;\n parsedMaterial.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n addTexture(device, material.occlusionTexture, 'pbr_occlusionSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_OCCLUSIONMAP',\n enabledUniformName: 'occlusionMapEnabled'\n },\n gltf\n });\n\n const {strength = 1} = material.occlusionTexture;\n parsedMaterial.uniforms.occlusionStrength = strength;\n }\n parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n if (material.emissiveTexture) {\n addTexture(device, material.emissiveTexture, 'pbr_emissiveSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_EMISSIVEMAP',\n enabledUniformName: 'emissiveMapEnabled'\n },\n gltf\n });\n }\n\n parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf);\n\n switch (material.alphaMode || 'OPAQUE') {\n case 'OPAQUE':\n break;\n case 'MASK': {\n const {alphaCutoff = 0.5} = material;\n parsedMaterial.defines['ALPHA_CUTOFF'] = true;\n parsedMaterial.uniforms.alphaCutoffEnabled = true;\n parsedMaterial.uniforms.alphaCutoff = alphaCutoff;\n break;\n }\n case 'BLEND':\n log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();\n applyAlphaBlendParameters(parsedMaterial);\n\n break;\n }\n}\n\nfunction applyAlphaBlendParameters(parsedMaterial: ParsedPBRMaterial): void {\n parsedMaterial.parameters.blend = true;\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GLEnum.SRC_ALPHA,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ];\n}\n\nfunction applyTransmissionBlendApproximation(parsedMaterial: ParsedPBRMaterial): void {\n parsedMaterial.parameters.blend = true;\n parsedMaterial.parameters.depthWriteEnabled = false;\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'one';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['depthMask'] = false;\n parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ];\n}\n\n/** Parse GLTF material sub record */\nfunction parsePbrMetallicRoughness(\n device: Device,\n pbrMetallicRoughness: GLTFPBRMetallicRoughness,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (pbrMetallicRoughness.baseColorTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_BASECOLORMAP',\n enabledUniformName: 'baseColorMapEnabled'\n },\n gltf\n }\n );\n }\n parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_METALROUGHNESSMAP',\n enabledUniformName: 'metallicRoughnessMapEnabled'\n },\n gltf\n }\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n}\n\nfunction parseMaterialExtensions(\n device: Device,\n extensions: GLTFMaterialExtensions | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extensions) {\n return;\n }\n\n if (hasMaterialExtensionShading(extensions)) {\n parsedMaterial.defines['USE_MATERIAL_EXTENSIONS'] = true;\n }\n\n parseSpecularExtension(device, extensions.KHR_materials_specular, parsedMaterial, gltf);\n parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);\n parseTransmissionExtension(device, extensions.KHR_materials_transmission, parsedMaterial, gltf);\n parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf);\n parseClearcoatExtension(device, extensions.KHR_materials_clearcoat, parsedMaterial, gltf);\n parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf);\n parseIridescenceExtension(device, extensions.KHR_materials_iridescence, parsedMaterial, gltf);\n parseAnisotropyExtension(device, extensions.KHR_materials_anisotropy, parsedMaterial, gltf);\n parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);\n}\n\nfunction hasMaterialExtensionShading(extensions: GLTFMaterialExtensions): boolean {\n return Boolean(\n extensions.KHR_materials_specular ||\n extensions.KHR_materials_ior ||\n extensions.KHR_materials_transmission ||\n extensions.KHR_materials_volume ||\n extensions.KHR_materials_clearcoat ||\n extensions.KHR_materials_sheen ||\n extensions.KHR_materials_iridescence ||\n extensions.KHR_materials_anisotropy\n );\n}\n\nfunction parseSpecularExtension(\n device: Device,\n extension: GLTFMaterialSpecularExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.specularColorFactor) {\n parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;\n }\n if (extension.specularFactor !== undefined) {\n parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;\n }\n if (extension.specularColorTexture) {\n addTexture(device, extension.specularColorTexture, 'pbr_specularColorSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SPECULARCOLORMAP',\n enabledUniformName: 'specularColorMapEnabled'\n },\n gltf\n });\n }\n if (extension.specularTexture) {\n addTexture(device, extension.specularTexture, 'pbr_specularIntensitySampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SPECULARINTENSITYMAP',\n enabledUniformName: 'specularIntensityMapEnabled'\n },\n gltf\n });\n }\n}\n\nfunction parseIorExtension(\n extension: GLTFMaterialIorExtension | undefined,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (extension?.ior !== undefined) {\n parsedMaterial.uniforms.ior = extension.ior;\n }\n}\n\nfunction parseTransmissionExtension(\n device: Device,\n extension: GLTFMaterialTransmissionExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.transmissionFactor !== undefined) {\n parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;\n }\n if (extension.transmissionTexture) {\n addTexture(device, extension.transmissionTexture, 'pbr_transmissionSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_TRANSMISSIONMAP',\n enabledUniformName: 'transmissionMapEnabled'\n },\n gltf\n });\n }\n\n if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {\n log.warn(\n 'KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting'\n )();\n applyTransmissionBlendApproximation(parsedMaterial);\n }\n}\n\nfunction parseVolumeExtension(\n device: Device,\n extension: GLTFMaterialVolumeExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.thicknessFactor !== undefined) {\n parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;\n }\n if (extension.thicknessTexture) {\n addTexture(device, extension.thicknessTexture, 'pbr_thicknessSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_THICKNESSMAP'\n },\n gltf\n });\n }\n if (extension.attenuationDistance !== undefined) {\n parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;\n }\n if (extension.attenuationColor) {\n parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;\n }\n}\n\nfunction parseClearcoatExtension(\n device: Device,\n extension: GLTFMaterialClearcoatExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.clearcoatFactor !== undefined) {\n parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;\n }\n if (extension.clearcoatRoughnessFactor !== undefined) {\n parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;\n }\n if (extension.clearcoatTexture) {\n addTexture(device, extension.clearcoatTexture, 'pbr_clearcoatSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_CLEARCOATMAP',\n enabledUniformName: 'clearcoatMapEnabled'\n },\n gltf\n });\n }\n if (extension.clearcoatRoughnessTexture) {\n addTexture(\n device,\n extension.clearcoatRoughnessTexture,\n 'pbr_clearcoatRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_CLEARCOATROUGHNESSMAP',\n enabledUniformName: 'clearcoatRoughnessMapEnabled'\n },\n gltf\n }\n );\n }\n if (extension.clearcoatNormalTexture) {\n addTexture(\n device,\n extension.clearcoatNormalTexture,\n 'pbr_clearcoatNormalSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_CLEARCOATNORMALMAP'\n },\n gltf\n }\n );\n }\n}\n\nfunction parseSheenExtension(\n device: Device,\n extension: GLTFMaterialSheenExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.sheenColorFactor) {\n parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;\n }\n if (extension.sheenRoughnessFactor !== undefined) {\n parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;\n }\n if (extension.sheenColorTexture) {\n addTexture(device, extension.sheenColorTexture, 'pbr_sheenColorSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SHEENCOLORMAP',\n enabledUniformName: 'sheenColorMapEnabled'\n },\n gltf\n });\n }\n if (extension.sheenRoughnessTexture) {\n addTexture(\n device,\n extension.sheenRoughnessTexture,\n 'pbr_sheenRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_SHEENROUGHNESSMAP',\n enabledUniformName: 'sheenRoughnessMapEnabled'\n },\n gltf\n }\n );\n }\n}\n\nfunction parseIridescenceExtension(\n device: Device,\n extension: GLTFMaterialIridescenceExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.iridescenceFactor !== undefined) {\n parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;\n }\n if (extension.iridescenceIor !== undefined) {\n parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;\n }\n if (\n extension.iridescenceThicknessMinimum !== undefined ||\n extension.iridescenceThicknessMaximum !== undefined\n ) {\n parsedMaterial.uniforms.iridescenceThicknessRange = [\n extension.iridescenceThicknessMinimum ?? 100,\n extension.iridescenceThicknessMaximum ?? 400\n ];\n }\n if (extension.iridescenceTexture) {\n addTexture(device, extension.iridescenceTexture, 'pbr_iridescenceSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_IRIDESCENCEMAP',\n enabledUniformName: 'iridescenceMapEnabled'\n },\n gltf\n });\n }\n if (extension.iridescenceThicknessTexture) {\n addTexture(\n device,\n extension.iridescenceThicknessTexture,\n 'pbr_iridescenceThicknessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_IRIDESCENCETHICKNESSMAP'\n },\n gltf\n }\n );\n }\n}\n\nfunction parseAnisotropyExtension(\n device: Device,\n extension: GLTFMaterialAnisotropyExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.anisotropyStrength !== undefined) {\n parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;\n }\n if (extension.anisotropyRotation !== undefined) {\n parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;\n }\n if (extension.anisotropyTexture) {\n addTexture(device, extension.anisotropyTexture, 'pbr_anisotropySampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_ANISOTROPYMAP',\n enabledUniformName: 'anisotropyMapEnabled'\n },\n gltf\n });\n }\n}\n\nfunction parseEmissiveStrengthExtension(\n extension: GLTFMaterialEmissiveStrengthExtension | undefined,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (extension?.emissiveStrength !== undefined) {\n parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;\n }\n}\n\n/** Create a texture from a glTF texture/sampler/image combo and add it to bindings */\nfunction addTexture(\n device: Device,\n gltfTexture: GLTFTexture,\n uniformName: keyof PBRMaterialBindings,\n parsedMaterial: ParsedPBRMaterial,\n textureParseOptions: TextureParseOptions = {}\n): void {\n const {featureOptions = {}, gltf} = textureParseOptions;\n const {define, enabledUniformName} = featureOptions;\n const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);\n const image = resolvedTextureInfo.texture?.source?.image;\n if (!image) {\n log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();\n return;\n }\n\n const gltfSampler = {\n wrapS: 10497, // default REPEAT S (U) wrapping mode.\n wrapT: 10497, // default REPEAT T (V) wrapping mode.\n minFilter: 9729, // default LINEAR filtering\n magFilter: 9729, // default LINEAR filtering\n ...resolvedTextureInfo?.texture?.sampler\n } as GLTFSampler;\n\n const baseOptions = {\n id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,\n sampler: convertSampler(gltfSampler)\n };\n\n let texture: Texture;\n\n if (image.compressed) {\n texture = createCompressedTexture(device, image, baseOptions);\n } else {\n const {width, height} = device.getExternalImageSize(image);\n texture = device.createTexture({\n ...baseOptions,\n width,\n height,\n data: image\n });\n }\n\n parsedMaterial.bindings[uniformName] = texture;\n if (define) parsedMaterial.defines[define] = true;\n if (enabledUniformName) {\n parsedMaterial.uniforms[enabledUniformName] = true;\n }\n parsedMaterial.generatedTextures.push(texture);\n}\n\nfunction resolveTextureInfo(gltfTexture: GLTFTexture, gltf?: GLTFPostprocessed): GLTFTexture {\n if (gltfTexture.texture || gltfTexture.index === undefined || !gltf?.textures) {\n return gltfTexture;\n }\n\n const resolvedTextureEntry = gltf.textures[gltfTexture.index] as\n | Partial<GLTFTexture>\n | GLTFTexture['texture']\n | undefined;\n if (!resolvedTextureEntry) {\n return gltfTexture;\n }\n\n if ('texture' in resolvedTextureEntry && resolvedTextureEntry.texture) {\n return {\n ...resolvedTextureEntry,\n ...gltfTexture,\n texture: resolvedTextureEntry.texture\n } as GLTFTexture;\n }\n\n if (!('source' in resolvedTextureEntry)) {\n return gltfTexture;\n }\n\n return {\n ...gltfTexture,\n texture: resolvedTextureEntry\n };\n}\n\n/** One mip level as produced by loaders.gl compressed texture parsers */\nexport type CompressedMipLevel = {\n data: TypedArray;\n width: number;\n height: number;\n textureFormat?: TextureFormat;\n};\n\n/**\n * Compressed image from current loaders.gl releases.\n * - `mipmaps` is a boolean (true), NOT an array\n * - `data` is an Array of TextureLevel-like objects\n * - Per-level `textureFormat` is already a luma.gl TextureFormat\n * - Top-level `width`/`height` may be undefined\n */\nexport type CompressedImageDataArray = {\n compressed: true;\n mipmaps?: boolean;\n width?: number;\n height?: number;\n data: CompressedMipLevel[];\n};\n\n/**\n * Hypothetical future format where `mipmaps` is an actual array.\n * Kept for forward compatibility.\n */\nexport type CompressedImageMipmapArray = {\n compressed: true;\n width?: number;\n height?: number;\n mipmaps: CompressedMipLevel[];\n};\n\n/** Union of all known loaders.gl compressed image shapes */\nexport type CompressedImage = CompressedImageDataArray | CompressedImageMipmapArray;\n\nfunction createCompressedTextureFallback(\n device: Device,\n baseOptions: {id: string; sampler: SamplerProps}\n): Texture {\n return device.createTexture({\n ...baseOptions,\n format: 'rgba8unorm',\n width: 1,\n height: 1,\n mipLevels: 1\n });\n}\n\nfunction resolveCompressedTextureFormat(level: CompressedMipLevel): TextureFormat | undefined {\n return level.textureFormat;\n}\n\n/**\n * Maximum mip levels that can be filled for a compressed texture.\n * texStorage2D allocates level i at (baseW >> i) \u00D7 (baseH >> i).\n * Compressed formats can't upload data for levels smaller than one block,\n * so we stop before either dimension drops below the block size.\n */\nfunction getMaxCompressedMipLevels(\n baseWidth: number,\n baseHeight: number,\n format: TextureFormat\n): number {\n const {blockWidth = 1, blockHeight = 1} = textureFormatDecoder.getInfo(format);\n let count = 1;\n for (let i = 1; ; i++) {\n const w = Math.max(1, baseWidth >> i);\n const h = Math.max(1, baseHeight >> i);\n if (w < blockWidth || h < blockHeight) break;\n count++;\n }\n return count;\n}\n\n/**\n * Create a texture from compressed image data produced by loaders.gl.\n * Handles current loaders.gl compressed image layouts:\n *\n * current: {compressed, mipmaps: true, data: [{data, width, height, textureFormat}, ...]}\n * forward: {compressed, mipmaps: [{data, width, height, textureFormat}, ...]}\n */\nexport function createCompressedTexture(\n device: Device,\n image: CompressedImage,\n baseOptions: {id: string; sampler: SamplerProps}\n): Texture {\n // Normalize mip levels from all known loaders.gl formats\n let levels: CompressedMipLevel[];\n\n if (Array.isArray((image as any).data) && (image as any).data[0]?.data) {\n // loaders.gl current format: image.data is Array of mip-level objects\n levels = (image as CompressedImageDataArray).data;\n } else if ('mipmaps' in image && Array.isArray((image as CompressedImageMipmapArray).mipmaps)) {\n // Hypothetical future format: image.mipmaps is an Array\n levels = (image as CompressedImageMipmapArray).mipmaps;\n } else {\n levels = [];\n }\n\n if (levels.length === 0 || !levels[0]?.data) {\n log.warn(\n 'createCompressedTexture: compressed image has no valid mip levels, creating fallback'\n )();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n const baseLevel = levels[0];\n const baseWidth = baseLevel.width ?? (image as any).width ?? 0;\n const baseHeight = baseLevel.height ?? (image as any).height ?? 0;\n\n if (baseWidth <= 0 || baseHeight <= 0) {\n log.warn('createCompressedTexture: base level has invalid dimensions, creating fallback')();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n const format = resolveCompressedTextureFormat(baseLevel);\n\n if (!format) {\n log.warn('createCompressedTexture: compressed image has no textureFormat, creating fallback')();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n // Validate mip levels: truncate chain at first invalid level.\n // Levels must be contiguous, so we stop at the first level that has\n // a format mismatch, missing data, non-positive dimensions, or\n // dimensions that don't match what texStorage2D will allocate.\n //\n // For block-compressed formats (ASTC, BC, ETC2), texStorage2D allocates\n // mip levels down to 1\u00D71 texels, but compressed data can't be smaller\n // than one block (e.g. 4\u00D74 for ASTC-4x4). Cap the chain so we never\n // try to upload data whose block-aligned size exceeds the allocated level.\n const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);\n const levelLimit = Math.min(levels.length, maxMipLevels);\n\n let validLevelCount = 1;\n for (let i = 1; i < levelLimit; i++) {\n const level = levels[i];\n if (!level.data || level.width <= 0 || level.height <= 0) {\n log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();\n break;\n }\n const levelFormat = resolveCompressedTextureFormat(level);\n if (levelFormat && levelFormat !== format) {\n log.warn(\n `createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`\n )();\n break;\n }\n const expectedW = Math.max(1, baseWidth >> i);\n const expectedH = Math.max(1, baseHeight >> i);\n if (level.width !== expectedW || level.height !== expectedH) {\n log.warn(\n `createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} ` +\n `don't match expected ${expectedW}x${expectedH}, truncating`\n )();\n break;\n }\n validLevelCount++;\n }\n\n const texture = device.createTexture({\n ...baseOptions,\n format,\n usage: Texture.TEXTURE | Texture.COPY_DST,\n width: baseWidth,\n height: baseHeight,\n mipLevels: validLevelCount,\n data: baseLevel.data\n });\n\n // Upload additional validated mip levels\n for (let i = 1; i < validLevelCount; i++) {\n texture.writeData(levels[i].data, {\n width: levels[i].width,\n height: levels[i].height,\n mipLevel: i\n });\n }\n\n return texture;\n}\n\n/*\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n *\nexport class PBRMaterialParser {\n readonly device: Device;\n\n readonly defines: Record<string, boolean>;\n readonly bindings: Record<string, Binding>;\n readonly uniforms: Record<string, any>;\n readonly parameters: Record<string, any>;\n\n /** Hold on to generated textures, we destroy them in the destroy method *\n readonly generatedTextures: Texture[];\n\n constructor(device: Device, props: PBRMaterialParserProps) {\n const {attributes, material, pbrDebug, imageBasedLightingEnvironment, lights, useTangents} =\n props;\n this.device = device;\n\n this.defines = {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n };\n\n if (this.device.features.has('glsl-texture-lod')) {\n this.defines.USE_TEX_LOD = true;\n }\n\n this.uniforms = {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n };\n\n this.bindings = {};\n\n this.parameters = {};\n this.generatedTextures = [];\n\n if (imageBasedLightingEnvironment) {\n this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();\n this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();\n this.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.getBrdfTexture();\n this.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (pbrDebug) {\n // Override final color for reference app visualization\n // of various parameters in the lighting equation.\n this.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n this.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n this.defineIfPresent(attributes.NORMAL, 'HAS_NORMALS');\n this.defineIfPresent(attributes.TANGENT && useTangents, 'HAS_TANGENTS');\n this.defineIfPresent(attributes.TEXCOORD_0, 'HAS_UV');\n this.defineIfPresent(attributes.COLOR_0, 'HAS_COLORS');\n\n this.defineIfPresent(imageBasedLightingEnvironment, 'USE_IBL');\n this.defineIfPresent(lights, 'USE_LIGHTS');\n this.defineIfPresent(pbrDebug, 'PBR_DEBUG');\n\n if (material) {\n this.parseMaterial(material);\n }\n }\n\n /**\n * Destroy all generated resources to release memory.\n *\n destroy(): void {\n this.generatedTextures.forEach(texture => texture.destroy());\n }\n\n /** Add a define if the the value is non-nullish *\n defineIfPresent(value: unknown, name: string): void {\n if (value) {\n this.defines[name] = 1;\n }\n }\n\n /** Parse GLTF material record *\n parseMaterial(material) {\n this.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n this.parsePbrMetallicRoughness(material.pbrMetallicRoughness);\n }\n if (material.normalTexture) {\n this.addTexture(material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP');\n\n const {scale = 1} = material.normalTexture;\n this.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n this.addTexture(material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP');\n\n const {strength = 1} = material.occlusionTexture;\n this.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n this.addTexture(material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP');\n this.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n if (material.alphaMode === 'MASK') {\n const {alphaCutoff = 0.5} = material;\n this.defines.ALPHA_CUTOFF = true;\n this.uniforms.u_AlphaCutoff = alphaCutoff;\n } else if (material.alphaMode === 'BLEND') {\n log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();\n Object.assign(this.parameters, {\n blend: true,\n blendEquation: GLEnum.FUNC_ADD,\n blendFunc: [\n GLEnum.SRC_ALPHA,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ]\n });\n }\n }\n\n /** Parse GLTF material sub record *\n parsePbrMetallicRoughness(pbrMetallicRoughness) {\n if (pbrMetallicRoughness.baseColorTexture) {\n this.addTexture(\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP'\n );\n }\n this.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n this.addTexture(\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP'\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n this.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n }\n\n /** Create a texture from a glTF texture/sampler/image combo and add it to bindings *\n addTexture(gltfTexture, name, define = null) {\n const parameters = gltfTexture?.texture?.sampler?.parameters || {};\n\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n let specialTextureParameters = {};\n if (image.compressed) {\n textureOptions = image;\n specialTextureParameters = {\n [GLEnum.TEXTURE_MIN_FILTER]:\n image.data.length > 1 ? GLEnum.LINEAR_MIPMAP_NEAREST : GLEnum.LINEAR\n };\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const texture: Texture = this.device.createTexture({\n id: gltfTexture.name || gltfTexture.id,\n parameters: {\n ...parameters,\n ...specialTextureParameters\n },\n pixelStore: {\n [GLEnum.UNPACK_FLIP_Y_WEBGL]: false\n },\n ...textureOptions\n });\n this.bindings[name] = texture;\n this.defineIfPresent(define, define);\n this.generatedTextures.push(texture);\n }\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// NOTE: `@luma.gl/gltf` intentionally keeps this as a local enum subset so it\n// does not need to depend on `@luma.gl/webgl` for a handful of stable WebGL values.\n// eslint-disable-next-line no-shadow\nexport enum GLEnum {\n POINTS = 0x0,\n LINES = 0x1,\n LINE_LOOP = 0x2,\n LINE_STRIP = 0x3,\n TRIANGLES = 0x4,\n TRIANGLE_STRIP = 0x5,\n TRIANGLE_FAN = 0x6,\n\n ONE = 1,\n SRC_ALPHA = 0x0302,\n ONE_MINUS_SRC_ALPHA = 0x0303,\n FUNC_ADD = 0x8006,\n\n LINEAR = 0x2601,\n NEAREST = 0x2600,\n NEAREST_MIPMAP_NEAREST = 0x2700,\n LINEAR_MIPMAP_NEAREST = 0x2701,\n NEAREST_MIPMAP_LINEAR = 0x2702,\n LINEAR_MIPMAP_LINEAR = 0x2703,\n TEXTURE_MIN_FILTER = 0x2801,\n TEXTURE_WRAP_S = 0x2802,\n TEXTURE_WRAP_T = 0x2803,\n REPEAT = 0x2901,\n CLAMP_TO_EDGE = 0x812f,\n MIRRORED_REPEAT = 0x8370,\n UNPACK_FLIP_Y_WEBGL = 0x9240\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\n\nimport type {SamplerProps} from '@luma.gl/core';\nimport {GLEnum} from './gltf-webgl-constants';\n\n/** Minimal glTF sampler representation used during conversion. */\ntype GLTFSampler = {\n /** Horizontal wrap mode. */\n wrapS?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;\n /** Vertical wrap mode. */\n wrapT?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;\n /** Magnification filter. */\n magFilter?: GLEnum.NEAREST | GLEnum.LINEAR;\n /** Minification and mip filter combination. */\n minFilter?:\n | GLEnum.NEAREST\n | GLEnum.LINEAR\n | GLEnum.NEAREST_MIPMAP_NEAREST\n | GLEnum.LINEAR_MIPMAP_NEAREST\n | GLEnum.NEAREST_MIPMAP_LINEAR\n | GLEnum.LINEAR_MIPMAP_LINEAR;\n};\n\n/** Converts a glTF sampler into luma.gl sampler props. */\nexport function convertSampler(gltfSampler: GLTFSampler): SamplerProps {\n return {\n addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),\n addressModeV: convertSamplerWrapMode(gltfSampler.wrapT),\n magFilter: convertSamplerMagFilter(gltfSampler.magFilter),\n ...convertSamplerMinFilter(gltfSampler.minFilter)\n };\n}\n\n/** Converts a glTF wrap enum into a luma.gl address mode. */\nfunction convertSamplerWrapMode(\n mode: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT | undefined\n): 'clamp-to-edge' | 'repeat' | 'mirror-repeat' | undefined {\n switch (mode) {\n case GLEnum.CLAMP_TO_EDGE:\n return 'clamp-to-edge';\n case GLEnum.REPEAT:\n return 'repeat';\n case GLEnum.MIRRORED_REPEAT:\n return 'mirror-repeat';\n default:\n return undefined;\n }\n}\n\n/** Converts a glTF mag filter enum into a luma.gl mag filter. */\nfunction convertSamplerMagFilter(\n mode: GLEnum.NEAREST | GLEnum.LINEAR | undefined\n): 'nearest' | 'linear' | undefined {\n switch (mode) {\n case GLEnum.NEAREST:\n return 'nearest';\n case GLEnum.LINEAR:\n return 'linear';\n default:\n return undefined;\n }\n}\n\n/** Converts a glTF min filter enum into luma.gl minification and mipmap filters. */\nfunction convertSamplerMinFilter(\n mode:\n | GLEnum.NEAREST\n | GLEnum.LINEAR\n | GLEnum.NEAREST_MIPMAP_NEAREST\n | GLEnum.LINEAR_MIPMAP_NEAREST\n | GLEnum.NEAREST_MIPMAP_LINEAR\n | GLEnum.LINEAR_MIPMAP_LINEAR\n | undefined\n): {minFilter?: 'nearest' | 'linear'; mipmapFilter?: 'nearest' | 'linear'} {\n switch (mode) {\n case GLEnum.NEAREST:\n return {minFilter: 'nearest'};\n case GLEnum.LINEAR:\n return {minFilter: 'linear'};\n case GLEnum.NEAREST_MIPMAP_NEAREST:\n return {minFilter: 'nearest', mipmapFilter: 'nearest'};\n case GLEnum.LINEAR_MIPMAP_NEAREST:\n return {minFilter: 'linear', mipmapFilter: 'nearest'};\n case GLEnum.NEAREST_MIPMAP_LINEAR:\n return {minFilter: 'nearest', mipmapFilter: 'linear'};\n case GLEnum.LINEAR_MIPMAP_LINEAR:\n return {minFilter: 'linear', mipmapFilter: 'linear'};\n default:\n return {};\n }\n}\n", "import {Matrix4} from '@math.gl/core';\nimport type {GLTFNodePostprocessed, GLTFPostprocessed} from '@loaders.gl/gltf';\nimport type {DirectionalLight, Light, PointLight, SpotLight} from '@luma.gl/shadertools';\n\nconst GLTF_COLOR_FACTOR = 255;\n\n/** Parse KHR_lights_punctual extension into luma.gl light definitions */\nexport function parseGLTFLights(gltf: GLTFPostprocessed): Light[] {\n const lightDefs =\n // `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.\n (gltf as GLTFPostprocessed & {lights?: any[]}).lights ||\n gltf.extensions?.['KHR_lights_punctual']?.['lights'];\n if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {\n return [];\n }\n\n const lights: Light[] = [];\n const parentNodeById = createParentNodeMap(gltf.nodes || []);\n const worldMatrixByNodeId = new Map<string, Matrix4>();\n\n for (const node of gltf.nodes || []) {\n const lightIndex =\n (node as GLTFNodePostprocessed & {light?: number}).light ??\n node.extensions?.KHR_lights_punctual?.light;\n if (typeof lightIndex !== 'number') {\n // eslint-disable-next-line no-continue\n continue;\n }\n const gltfLight = lightDefs[lightIndex];\n if (!gltfLight) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const color = normalizeGLTFLightColor(\n (gltfLight.color || [1, 1, 1]) as [number, number, number]\n );\n const intensity = gltfLight.intensity ?? 1;\n const range = gltfLight.range;\n const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);\n\n switch (gltfLight.type) {\n case 'directional':\n lights.push(parseDirectionalLight(worldMatrix, color, intensity));\n break;\n case 'point':\n lights.push(parsePointLight(worldMatrix, color, intensity, range));\n break;\n case 'spot':\n lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));\n break;\n default:\n // Unsupported light type\n break;\n }\n }\n\n return lights;\n}\n\n/**\n * Converts glTF colors from the 0-1 spec range to luma.gl's 0-255 light convention.\n */\nfunction normalizeGLTFLightColor(color: [number, number, number]): [number, number, number] {\n return color.map(component => component * GLTF_COLOR_FACTOR) as [number, number, number];\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a point light.\n */\nfunction parsePointLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number,\n range?: number\n): PointLight {\n const position = getLightPosition(worldMatrix);\n\n let attenuation: Readonly<[number, number, number]> = [1, 0, 0];\n if (range !== undefined && range > 0) {\n attenuation = [1, 0, 1 / (range * range)] as [number, number, number];\n }\n\n return {\n type: 'point',\n position,\n color,\n intensity,\n attenuation\n };\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a directional light.\n */\nfunction parseDirectionalLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number\n): DirectionalLight {\n const direction = getLightDirection(worldMatrix);\n\n return {\n type: 'directional',\n direction,\n color,\n intensity\n };\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a spot light.\n */\nfunction parseSpotLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number,\n range?: number,\n spot: {innerConeAngle?: number; outerConeAngle?: number} = {}\n): SpotLight {\n const position = getLightPosition(worldMatrix);\n const direction = getLightDirection(worldMatrix);\n\n let attenuation: Readonly<[number, number, number]> = [1, 0, 0];\n if (range !== undefined && range > 0) {\n attenuation = [1, 0, 1 / (range * range)] as [number, number, number];\n }\n\n return {\n type: 'spot',\n position,\n direction,\n color,\n intensity,\n attenuation,\n innerConeAngle: spot.innerConeAngle ?? 0,\n outerConeAngle: spot.outerConeAngle ?? Math.PI / 4\n };\n}\n\n/**\n * Builds a parent lookup so punctual lights can be resolved in world space.\n */\nfunction createParentNodeMap(nodes: GLTFNodePostprocessed[]): Map<string, GLTFNodePostprocessed> {\n const parentNodeById = new Map<string, GLTFNodePostprocessed>();\n\n for (const node of nodes) {\n for (const childNode of node.children || []) {\n parentNodeById.set(childNode.id, node);\n }\n }\n\n return parentNodeById;\n}\n\n/**\n * Resolves a glTF node's world matrix from its local transform and parent chain.\n */\nfunction getNodeWorldMatrix(\n node: GLTFNodePostprocessed,\n parentNodeById: Map<string, GLTFNodePostprocessed>,\n worldMatrixByNodeId: Map<string, Matrix4>\n): Matrix4 {\n const cachedWorldMatrix = worldMatrixByNodeId.get(node.id);\n if (cachedWorldMatrix) {\n return cachedWorldMatrix;\n }\n\n const localMatrix = getNodeLocalMatrix(node);\n const parentNode = parentNodeById.get(node.id);\n const worldMatrix = parentNode\n ? new Matrix4(\n getNodeWorldMatrix(parentNode, parentNodeById, worldMatrixByNodeId)\n ).multiplyRight(localMatrix)\n : localMatrix;\n\n worldMatrixByNodeId.set(node.id, worldMatrix);\n return worldMatrix;\n}\n\n/**\n * Resolves a glTF node's local matrix from its matrix or TRS components.\n */\nfunction getNodeLocalMatrix(node: GLTFNodePostprocessed): Matrix4 {\n if (node.matrix) {\n return new Matrix4(node.matrix);\n }\n\n const matrix = new Matrix4();\n\n if (node.translation) {\n matrix.translate(node.translation);\n }\n\n if (node.rotation) {\n matrix.multiplyRight(new Matrix4().fromQuaternion(node.rotation));\n }\n\n if (node.scale) {\n matrix.scale(node.scale);\n }\n\n return matrix;\n}\n\n/**\n * Resolves the world-space position of a glTF light node.\n */\nfunction getLightPosition(worldMatrix: Matrix4): [number, number, number] {\n return worldMatrix.transformAsPoint([0, 0, 0]) as [number, number, number];\n}\n\n/**\n * Resolves the world-space forward direction of a glTF light node.\n */\nfunction getLightDirection(worldMatrix: Matrix4): [number, number, number] {\n return worldMatrix.transformDirection([0, 0, -1]) as [number, number, number];\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type PrimitiveTopology} from '@luma.gl/core';\nimport {\n Geometry,\n GeometryAttribute,\n GroupNode,\n Material,\n MaterialFactory,\n ModelNode,\n type ModelProps\n} from '@luma.gl/engine';\nimport {\n type GLTFMaterialPostprocessed,\n type GLTFMeshPostprocessed,\n type GLTFNodePostprocessed,\n type GLTFPostprocessed\n} from '@loaders.gl/gltf';\nimport {pbrMaterial} from '@luma.gl/shadertools';\n\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {convertGLDrawModeToTopology} from '../webgl-to-webgpu/convert-webgl-topology';\nimport {createGLTFMaterial, createGLTFModel} from '../gltf/create-gltf-model';\n\nimport {parsePBRMaterial} from './parse-pbr-material';\n\n/** Options that influence how a post-processed glTF is turned into a luma.gl scenegraph. */\nexport type ParseGLTFOptions = {\n /** Additional model props applied to each generated primitive model. */\n modelOptions?: Partial<ModelProps>;\n /** Enables shader-level PBR debug output. */\n pbrDebug?: boolean;\n /** Optional image-based lighting environment. */\n imageBasedLightingEnvironment?: PBREnvironment;\n /** Enables punctual light extraction. */\n lights?: boolean;\n /** Enables tangent usage when available. */\n useTangents?: boolean;\n};\n\nconst defaultOptions: Required<ParseGLTFOptions> = {\n modelOptions: {},\n pbrDebug: false,\n imageBasedLightingEnvironment: undefined!,\n lights: true,\n useTangents: false\n};\n\n/**\n * GLTF instantiator for luma.gl\n * Walks the parsed and resolved glTF structure and builds a luma.gl scenegraph\n */\nexport function parseGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options: ParseGLTFOptions = {}\n): {\n /** Scene roots generated from `gltf.scenes`. */\n scenes: GroupNode[];\n /** Materials aligned with the source `gltf.materials` array. */\n materials: Material[];\n /** Map from glTF mesh ids to generated mesh group nodes. */\n gltfMeshIdToNodeMap: Map<string, GroupNode>;\n /** Map from glTF node indices to generated scenegraph nodes. */\n gltfNodeIndexToNodeMap: Map<number, GroupNode>;\n /** Map from glTF node ids to generated scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n} {\n const combinedOptions = {...defaultOptions, ...options};\n const materialFactory = new MaterialFactory(device, {modules: [pbrMaterial]});\n const materials = (gltf.materials || []).map((gltfMaterial, materialIndex) =>\n createGLTFMaterial(device, {\n id: getGLTFMaterialId(gltfMaterial, materialIndex),\n parsedPPBRMaterial: parsePBRMaterial(\n device,\n gltfMaterial as any,\n {},\n {\n ...combinedOptions,\n gltf,\n validateAttributes: false\n }\n ),\n materialFactory\n })\n );\n const gltfMaterialIdToMaterialMap = new Map<string, Material>();\n (gltf.materials || []).forEach((gltfMaterial, materialIndex) => {\n gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);\n });\n\n const gltfMeshIdToNodeMap = new Map<string, GroupNode>();\n gltf.meshes.forEach((gltfMesh, idx) => {\n const newMesh = createNodeForGLTFMesh(\n device,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n combinedOptions\n );\n gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);\n });\n\n const gltfNodeIndexToNodeMap = new Map<number, GroupNode>();\n const gltfNodeIdToNodeMap = new Map<string, GroupNode>();\n // Step 1/2: Generate a GroupNode for each gltf node. (1:1 mapping).\n gltf.nodes.forEach((gltfNode, idx) => {\n const newNode = createNodeForGLTFNode(device, gltfNode, combinedOptions);\n gltfNodeIndexToNodeMap.set(idx, newNode);\n gltfNodeIdToNodeMap.set(gltfNode.id, newNode);\n });\n\n // Step 2/2: Go though each gltf node and attach the children.\n // This guarantees that each gltf node will have exactly one luma GroupNode.\n gltf.nodes.forEach((gltfNode, idx) => {\n gltfNodeIndexToNodeMap.get(idx)!.add(\n (gltfNode.children ?? []).map(({id}) => {\n const child = gltfNodeIdToNodeMap.get(id);\n if (!child) throw new Error(`Cannot find child ${id} of node ${idx}`);\n return child;\n })\n );\n\n // Nodes can have children nodes and one optional child mesh at the same time.\n if (gltfNode.mesh) {\n const mesh = gltfMeshIdToNodeMap.get(gltfNode.mesh.id);\n if (!mesh) {\n throw new Error(`Cannot find mesh child ${gltfNode.mesh.id} of node ${idx}`);\n }\n gltfNodeIndexToNodeMap.get(idx)!.add(mesh);\n }\n });\n\n const scenes = gltf.scenes.map(gltfScene => {\n const children = (gltfScene.nodes || []).map(({id}) => {\n const child = gltfNodeIdToNodeMap.get(id);\n if (!child)\n throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);\n return child;\n });\n return new GroupNode({\n id: gltfScene.name || gltfScene.id,\n children\n });\n });\n\n return {scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap};\n}\n\n/** Creates a `GroupNode` for one glTF node transform. */\nfunction createNodeForGLTFNode(\n device: Device,\n gltfNode: GLTFNodePostprocessed,\n options: Required<ParseGLTFOptions>\n): GroupNode {\n return new GroupNode({\n id: gltfNode.name || gltfNode.id,\n children: [],\n matrix: gltfNode.matrix,\n position: gltfNode.translation,\n rotation: gltfNode.rotation,\n scale: gltfNode.scale\n });\n}\n\n/** Creates a mesh group node containing one model node per glTF primitive. */\nfunction createNodeForGLTFMesh(\n device: Device,\n gltfMesh: GLTFMeshPostprocessed,\n gltf: GLTFPostprocessed,\n gltfMaterialIdToMaterialMap: Map<string, Material>,\n options: Required<ParseGLTFOptions>\n): GroupNode {\n const gltfPrimitives = gltfMesh.primitives || [];\n const primitives = gltfPrimitives.map((gltfPrimitive, i) =>\n createNodeForGLTFPrimitive({\n device,\n gltfPrimitive,\n primitiveIndex: i,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n options\n })\n );\n const mesh = new GroupNode({\n id: gltfMesh.name || gltfMesh.id,\n children: primitives\n });\n\n return mesh;\n}\n\n/** Input options for creating one renderable glTF primitive model node. */\ntype CreateNodeForGLTFPrimitiveOptions = {\n device: Device;\n gltfPrimitive: any;\n primitiveIndex: number;\n gltfMesh: GLTFMeshPostprocessed;\n gltf: GLTFPostprocessed;\n gltfMaterialIdToMaterialMap: Map<string, Material>;\n options: Required<ParseGLTFOptions>;\n};\n\n/** Creates a renderable model node for one glTF primitive. */\nfunction createNodeForGLTFPrimitive({\n device,\n gltfPrimitive,\n primitiveIndex,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n options\n}: CreateNodeForGLTFPrimitiveOptions): ModelNode {\n const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${primitiveIndex}`;\n const topology = convertGLDrawModeToTopology(gltfPrimitive.mode || 4);\n const vertexCount = gltfPrimitive.indices\n ? gltfPrimitive.indices.count\n : getVertexCount(gltfPrimitive.attributes);\n\n const geometry = createGeometry(id, gltfPrimitive, topology);\n\n const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {\n ...options,\n gltf\n });\n\n const modelNode = createGLTFModel(device, {\n id,\n geometry: createGeometry(id, gltfPrimitive, topology),\n material: gltfPrimitive.material\n ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null\n : null,\n parsedPPBRMaterial,\n modelOptions: options.modelOptions,\n vertexCount\n });\n\n modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];\n // TODO this holds on to all the CPU side texture and attribute data\n // modelNode.material = gltfPrimitive.material;\n\n return modelNode;\n}\n\n/** Computes the vertex count for a primitive without indices. */\nfunction getVertexCount(attributes: any) {\n throw new Error('getVertexCount not implemented');\n}\n\n/** Converts glTF primitive attributes and indices into a luma.gl `Geometry`. */\nfunction createGeometry(id: string, gltfPrimitive: any, topology: PrimitiveTopology): Geometry {\n const attributes: Record<string, GeometryAttribute> = {};\n for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {\n const {components, size, value} = attribute as GeometryAttribute;\n\n attributes[attributeName] = {size: size ?? components, value};\n }\n\n return new Geometry({\n id,\n topology,\n indices: gltfPrimitive.indices.value,\n attributes\n });\n}\n\nfunction getGLTFMaterialId(gltfMaterial: GLTFMaterialPostprocessed, materialIndex: number): string {\n return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PrimitiveTopology} from '@luma.gl/core';\nimport {GLEnum} from './gltf-webgl-constants';\n\n/** Converts a WebGL draw mode into a luma.gl primitive topology string. */\nexport function convertGLDrawModeToTopology(\n drawMode:\n | GLEnum.POINTS\n | GLEnum.LINES\n | GLEnum.LINE_STRIP\n | GLEnum.LINE_LOOP\n | GLEnum.TRIANGLES\n | GLEnum.TRIANGLE_STRIP\n | GLEnum.TRIANGLE_FAN\n): PrimitiveTopology {\n // prettier-ignore\n switch (drawMode) {\n case GLEnum.POINTS: return 'point-list';\n case GLEnum.LINES: return 'line-list';\n case GLEnum.LINE_STRIP: return 'line-strip';\n case GLEnum.TRIANGLES: return 'triangle-list';\n case GLEnum.TRIANGLE_STRIP: return 'triangle-strip';\n default: throw new Error(String(drawMode));\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {\n Buffer,\n Device,\n Sampler,\n Texture,\n TextureView,\n type Binding,\n type RenderPipelineParameters,\n log\n} from '@luma.gl/core';\nimport {DynamicTexture} from '@luma.gl/engine';\nimport {pbrMaterial, skin} from '@luma.gl/shadertools';\nimport {\n Geometry,\n Material,\n MaterialFactory,\n Model,\n ModelNode,\n type ModelProps\n} from '@luma.gl/engine';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\n\nconst SHADER = /* WGSL */ `\nstruct VertexInputs {\n @location(0) positions: vec3f,\n#ifdef HAS_NORMALS\n @location(1) normals: vec3f,\n#endif\n#ifdef HAS_TANGENTS\n @location(2) TANGENT: vec4f,\n#endif\n#ifdef HAS_UV\n @location(3) texCoords: vec2f,\n#endif\n#ifdef HAS_SKIN\n @location(4) JOINTS_0: vec4u,\n @location(5) WEIGHTS_0: vec4f,\n#endif\n};\n\nstruct FragmentInputs {\n @builtin(position) position: vec4f,\n @location(0) pbrPosition: vec3f,\n @location(1) pbrUV: vec2f,\n @location(2) pbrNormal: vec3f,\n#ifdef HAS_TANGENTS\n @location(3) pbrTangent: vec4f,\n#endif\n};\n\n@vertex\nfn vertexMain(inputs: VertexInputs) -> FragmentInputs {\n var outputs: FragmentInputs;\n var position = vec4f(inputs.positions, 1.0);\n var normal = vec3f(0.0, 0.0, 1.0);\n var tangent = vec4f(1.0, 0.0, 0.0, 1.0);\n var uv = vec2f(0.0, 0.0);\n\n#ifdef HAS_NORMALS\n normal = inputs.normals;\n#endif\n#ifdef HAS_UV\n uv = inputs.texCoords;\n#endif\n#ifdef HAS_TANGENTS\n tangent = inputs.TANGENT;\n#endif\n#ifdef HAS_SKIN\n let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);\n position = skinMatrix * position;\n normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);\n#ifdef HAS_TANGENTS\n tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);\n#endif\n#endif\n\n let worldPosition = pbrProjection.modelMatrix * position;\n\n#ifdef HAS_NORMALS\n normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);\n#endif\n#ifdef HAS_TANGENTS\n let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);\n outputs.pbrTangent = vec4f(worldTangent, tangent.w);\n#endif\n\n outputs.position = pbrProjection.modelViewProjectionMatrix * position;\n outputs.pbrPosition = worldPosition.xyz / worldPosition.w;\n outputs.pbrUV = uv;\n outputs.pbrNormal = normal;\n return outputs;\n}\n\n@fragment\nfn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {\n fragmentInputs.pbr_vPosition = inputs.pbrPosition;\n fragmentInputs.pbr_vUV = inputs.pbrUV;\n fragmentInputs.pbr_vNormal = inputs.pbrNormal;\n#ifdef HAS_TANGENTS\n let tangent = normalize(inputs.pbrTangent.xyz);\n let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;\n fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);\n#endif\n return pbr_filterColor(vec4f(1.0));\n}\n`;\n\n// TODO rename attributes to POSITION/NORMAL etc\n// See gpu-geometry.ts: getAttributeBuffersFromGeometry()\nconst vs = /* glsl */ `\\\n#version 300 es\n\n // in vec4 POSITION;\n in vec4 positions;\n\n #ifdef HAS_NORMALS\n // in vec4 NORMAL;\n in vec4 normals;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n #ifdef HAS_SKIN\n in uvec4 JOINTS_0;\n in vec4 WEIGHTS_0;\n #endif\n\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n vec4 pos = positions;\n\n #ifdef HAS_SKIN\n mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);\n pos = skinMat * pos;\n _NORMAL = skinMat * _NORMAL;\n _TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);\n #endif\n\n pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0);\n gl_Position = pbrProjection.modelViewProjectionMatrix * pos;\n }\n`;\n\nconst fs = /* glsl */ `\\\n#version 300 es\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\n/** Options used to instantiate a `ModelNode` for one glTF primitive. */\nexport type CreateGLTFModelOptions = {\n /** Optional id assigned to the generated model. */\n id?: string;\n /** Vertex count override for non-indexed primitives. */\n vertexCount?: number;\n /** Geometry converted from the glTF primitive. */\n geometry: Geometry;\n /** Parsed PBR material state for the primitive. */\n parsedPPBRMaterial: ParsedPBRMaterial;\n /** Pre-created material aligned with the source glTF material entry, when available. */\n material?: Material | null;\n /** Additional model props merged into the generated model. */\n modelOptions?: Partial<ModelProps>;\n};\n\nexport type CreateGLTFMaterialOptions = {\n id?: string;\n parsedPPBRMaterial: ParsedPBRMaterial;\n materialFactory?: MaterialFactory;\n};\n\nexport function createGLTFMaterial(device: Device, options: CreateGLTFMaterialOptions): Material {\n const materialFactory =\n options.materialFactory || new MaterialFactory(device, {modules: [pbrMaterial]});\n\n const pbrMaterialProps = {...options.parsedPPBRMaterial.uniforms};\n delete pbrMaterialProps.camera;\n const materialBindings = Object.fromEntries(\n Object.entries({\n ...pbrMaterialProps,\n ...options.parsedPPBRMaterial.bindings\n }).filter(\n ([name, value]) => materialFactory.ownsBinding(name) && isMaterialBindingResource(value)\n )\n ) as Record<string, Binding | DynamicTexture>;\n\n const material = materialFactory.createMaterial({\n id: options.id,\n bindings: materialBindings\n });\n material.setProps({pbrMaterial: pbrMaterialProps});\n\n return material;\n}\n\n/** Creates a luma.gl Model from GLTF data*/\nexport function createGLTFModel(device: Device, options: CreateGLTFModelOptions): ModelNode {\n const {id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {}} = options;\n\n log.info(4, 'createGLTFModel defines: ', parsedPPBRMaterial.defines)();\n\n // Calculate managedResources\n // TODO: Implement resource management logic that will\n // not deallocate resources/textures/buffers that are shared\n const managedResources: any[] = [];\n // managedResources.push(...parsedMaterial.generatedTextures);\n // managedResources.push(...Object.values(attributes).map((attribute) => attribute.buffer));\n\n const parameters: RenderPipelineParameters = {\n depthWriteEnabled: true,\n depthCompare: 'less',\n depthFormat: 'depth24plus',\n cullMode: 'back'\n };\n\n const modelProps: ModelProps = {\n id,\n source: SHADER,\n vs,\n fs,\n geometry,\n topology: geometry.topology,\n vertexCount,\n modules: [pbrMaterial, skin],\n ...modelOptions,\n\n defines: {...parsedPPBRMaterial.defines, ...modelOptions.defines},\n parameters: {...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters}\n };\n\n const material =\n options.material ||\n createGLTFMaterial(device, {\n id: id ? `${id}-material` : undefined,\n parsedPPBRMaterial\n });\n modelProps.material = material;\n\n const model = new Model(device, modelProps);\n\n const sceneShaderInputValues = {\n ...parsedPPBRMaterial.uniforms,\n ...modelOptions.uniforms,\n ...parsedPPBRMaterial.bindings,\n ...modelOptions.bindings\n };\n const sceneShaderInputProps = getSceneShaderInputProps(\n model.shaderInputs.getModules(),\n material,\n sceneShaderInputValues\n );\n model.shaderInputs.setProps(sceneShaderInputProps);\n return new ModelNode({managedResources, model});\n}\n\nfunction isMaterialBindingResource(value: unknown): boolean {\n return (\n value instanceof Buffer ||\n value instanceof DynamicTexture ||\n value instanceof Sampler ||\n value instanceof Texture ||\n value instanceof TextureView\n );\n}\n\nfunction getSceneShaderInputProps(\n modules: Array<{\n name: string;\n uniformTypes?: Readonly<Record<string, unknown>>;\n bindingLayout?: ReadonlyArray<{name: string}>;\n }>,\n material: Material,\n shaderInputValues: Record<string, unknown>\n): Record<string, Record<string, unknown>> {\n const propertyToModuleNameMap = new Map<string, string>();\n for (const module of modules) {\n for (const uniformName of Object.keys(module.uniformTypes || {})) {\n propertyToModuleNameMap.set(uniformName, module.name);\n }\n for (const binding of module.bindingLayout || []) {\n propertyToModuleNameMap.set(binding.name, module.name);\n }\n }\n\n const sceneShaderInputProps: Record<string, Record<string, unknown>> = {};\n for (const [propertyName, value] of Object.entries(shaderInputValues)) {\n if (value === undefined) {\n continue;\n }\n\n const moduleName = propertyToModuleNameMap.get(propertyName);\n if (!moduleName || material.ownsModule(moduleName)) {\n continue;\n }\n\n sceneShaderInputProps[moduleName] ||= {};\n sceneShaderInputProps[moduleName][propertyName] = value;\n }\n\n return sceneShaderInputProps;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {GroupNode} from '@luma.gl/engine';\nimport {GLTFAnimation} from './animations/animations';\nimport {interpolate} from './animations/interpolate';\n\n/** Construction props for a single glTF animation controller. */\ntype GLTFSingleAnimatorProps = {\n /** Animation data to evaluate. */\n animation: GLTFAnimation;\n /** Mapping from glTF node ids to scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n /** Start time in seconds. */\n startTime?: number;\n /** Whether playback is active. */\n playing?: boolean;\n /** Playback speed multiplier. */\n speed?: number;\n};\n\n/** Evaluates one glTF animation against the generated scenegraph. */\nclass GLTFSingleAnimator {\n /** Animation definition being played. */\n animation: GLTFAnimation;\n /** Target scenegraph lookup table. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n /** Playback start time in seconds. */\n startTime: number = 0;\n /** Whether playback is currently enabled. */\n playing: boolean = true;\n /** Playback speed multiplier. */\n speed: number = 1;\n\n /** Creates a single-animation controller. */\n constructor(props: GLTFSingleAnimatorProps) {\n this.animation = props.animation;\n this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;\n this.animation.name ||= 'unnamed';\n Object.assign(this, props);\n }\n\n /** Advances the animation to the supplied wall-clock time in milliseconds. */\n setTime(timeMs: number) {\n if (!this.playing) {\n return;\n }\n\n const absTime = timeMs / 1000;\n const time = (absTime - this.startTime) * this.speed;\n\n this.animation.channels.forEach(({sampler, targetNodeId, path}) => {\n const targetNode = this.gltfNodeIdToNodeMap.get(targetNodeId);\n if (!targetNode) {\n throw new Error(`Cannot find animation target node ${targetNodeId}`);\n }\n\n interpolate(time, sampler, targetNode, path);\n });\n }\n}\n\n/** Construction props for {@link GLTFAnimator}. */\nexport type GLTFAnimatorProps = {\n /** Parsed animations from the source glTF. */\n animations: GLTFAnimation[];\n /** Mapping from glTF node ids to scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n};\n\n/** Coordinates playback of every animation found in a glTF scene. */\nexport class GLTFAnimator {\n /** Individual animation controllers. */\n animations: GLTFSingleAnimator[];\n\n /** Creates an animator for the supplied glTF scenegraph. */\n constructor(props: GLTFAnimatorProps) {\n this.animations = props.animations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n return new GLTFSingleAnimator({\n gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,\n animation: {name, channels: animation.channels}\n });\n });\n }\n\n /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */\n animate(time: number): void {\n log.warn('GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead')();\n this.setTime(time);\n }\n\n /** Advances every animation to the supplied wall-clock time in milliseconds. */\n setTime(time: number): void {\n this.animations.forEach(animation => animation.setTime(time));\n }\n\n /** Returns the per-animation controllers managed by this animator. */\n getAnimations() {\n return this.animations;\n }\n}\n", "import {log} from '@luma.gl/core';\nimport {Quaternion} from '@math.gl/core';\nimport {GLTFAnimationPath, GLTFAnimationSampler} from './animations';\nimport {GroupNode} from '@luma.gl/engine';\n\n/** Applies an evaluated animation value to a scenegraph node. */\nfunction updateTargetPath(\n target: GroupNode,\n path: GLTFAnimationPath,\n newValue: number[]\n): GroupNode | null {\n switch (path) {\n case 'translation':\n return target.setPosition(newValue).updateMatrix();\n\n case 'rotation':\n return target.setRotation(newValue).updateMatrix();\n\n case 'scale':\n return target.setScale(newValue).updateMatrix();\n\n default:\n log.warn(`Bad animation path ${path}`)();\n return null;\n }\n}\n\n/** Evaluates a glTF animation sampler at the supplied time and applies the result to a node. */\nexport function interpolate(\n time: number,\n {input, interpolation, output}: GLTFAnimationSampler,\n target: GroupNode,\n path: GLTFAnimationPath\n) {\n const maxTime = input[input.length - 1];\n const animationTime = time % maxTime;\n\n const nextIndex = input.findIndex(t => t >= animationTime);\n const previousIndex = Math.max(0, nextIndex - 1);\n\n const previousTime = input[previousIndex];\n const nextTime = input[nextIndex];\n\n switch (interpolation) {\n case 'STEP':\n stepInterpolate(target, path, output[previousIndex]);\n break;\n\n case 'LINEAR':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n linearInterpolate(target, path, output[previousIndex], output[nextIndex], ratio);\n }\n break;\n\n case 'CUBICSPLINE':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n const tDiff = nextTime - previousTime;\n\n const p0 = output[3 * previousIndex + 1];\n const outTangent0 = output[3 * previousIndex + 2];\n const inTangent1 = output[3 * nextIndex + 0];\n const p1 = output[3 * nextIndex + 1];\n\n cubicsplineInterpolate(target, path, {p0, outTangent0, inTangent1, p1, tDiff, ratio});\n }\n break;\n\n default:\n log.warn(`Interpolation ${interpolation} not supported`)();\n break;\n }\n}\n\n/** Applies linear interpolation between two keyframes. */\nfunction linearInterpolate(\n target: GroupNode,\n path: GLTFAnimationPath,\n start: number[],\n stop: number[],\n ratio: number\n) {\n if (path === 'rotation') {\n // SLERP when path is rotation\n updateTargetPath(target, path, new Quaternion().slerp({start, target: stop, ratio}));\n } else {\n // regular interpolation\n const newVal = [];\n for (let i = 0; i < start.length; i++) {\n newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];\n }\n updateTargetPath(target, path, newVal);\n }\n}\n\n/** Applies glTF cubic spline interpolation between two keyframes. */\nfunction cubicsplineInterpolate(\n target: GroupNode,\n path: GLTFAnimationPath,\n {\n p0,\n outTangent0,\n inTangent1,\n p1,\n tDiff,\n ratio: t\n }: {\n p0: number[];\n outTangent0: number[];\n inTangent1: number[];\n p1: number[];\n tDiff: number;\n ratio: number;\n }\n) {\n // TODO: Quaternion might need normalization\n const newVal = [];\n for (let i = 0; i < p0.length; i++) {\n const m0 = outTangent0[i] * tDiff;\n const m1 = inTangent1[i] * tDiff;\n newVal[i] =\n (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +\n (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +\n (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +\n (Math.pow(t, 3) - Math.pow(t, 2)) * m1;\n }\n updateTargetPath(target, path, newVal);\n}\n\n/** Applies step interpolation by copying the current keyframe value. */\nfunction stepInterpolate(target: GroupNode, path: GLTFAnimationPath, value: number[]) {\n updateTargetPath(target, path, value);\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {type GLTFAccessorPostprocessed, type GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {\n GLTFAnimationPath,\n type GLTFAnimation,\n type GLTFAnimationChannel,\n type GLTFAnimationSampler\n} from '../gltf/animations/animations';\n\nimport {accessorToTypedArray} from '..//webgl-to-webgpu/convert-webgl-attribute';\n\n/** Parses glTF animation records into the runtime animation model used by `GLTFAnimator`. */\nexport function parseGLTFAnimations(gltf: GLTFPostprocessed): GLTFAnimation[] {\n const gltfAnimations = gltf.animations || [];\n const accessorCache1D = new Map<GLTFAccessorPostprocessed, number[]>();\n const accessorCache2D = new Map<GLTFAccessorPostprocessed, number[][]>();\n\n return gltfAnimations.flatMap((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n const samplerCache = new Map<number, GLTFAnimationSampler>();\n const channels: GLTFAnimationChannel[] = animation.channels.flatMap(({sampler, target}) => {\n const path = getSupportedAnimationPath(target.path);\n if (!path) {\n return [];\n }\n\n const targetNode = gltf.nodes[target.node ?? 0];\n if (!targetNode) {\n throw new Error(`Cannot find animation target ${target.node}`);\n }\n\n let parsedSampler = samplerCache.get(sampler);\n if (!parsedSampler) {\n const gltfSampler = animation.samplers[sampler];\n if (!gltfSampler) {\n throw new Error(`Cannot find animation sampler ${sampler}`);\n }\n const {input, interpolation = 'LINEAR', output} = gltfSampler;\n parsedSampler = {\n input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),\n interpolation,\n output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)\n };\n samplerCache.set(sampler, parsedSampler);\n }\n\n return {\n sampler: parsedSampler,\n targetNodeId: targetNode.id,\n path\n };\n });\n\n return channels.length ? [{name, channels}] : [];\n });\n}\n\nfunction getSupportedAnimationPath(path: string): GLTFAnimationPath | null {\n if (path === 'pointer') {\n log.warn('KHR_animation_pointer channels are not supported and will be skipped')();\n return null;\n }\n\n return path as GLTFAnimationPath;\n}\n\n/** Converts a scalar accessor into a cached JavaScript number array. */\nfunction accessorToJsArray1D(\n accessor: GLTFAccessorPostprocessed,\n accessorCache: Map<GLTFAccessorPostprocessed, number[]>\n): number[] {\n if (accessorCache.has(accessor)) {\n return accessorCache.get(accessor)!;\n }\n\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n assert(components === 1, 'accessorToJsArray1D must have exactly 1 component');\n const result = Array.from(array);\n\n accessorCache.set(accessor, result);\n return result;\n}\n\n/** Converts a scalar, vector, or matrix accessor into a cached JavaScript array-of-arrays. */\nfunction accessorToJsArray2D(\n accessor: GLTFAccessorPostprocessed,\n accessorCache: Map<GLTFAccessorPostprocessed, number[][]>\n): number[][] {\n if (accessorCache.has(accessor)) {\n return accessorCache.get(accessor)!;\n }\n\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n assert(components >= 1, 'accessorToJsArray2D must have at least 1 component');\n\n const result = [];\n\n // Slice array\n for (let i = 0; i < array.length; i += components) {\n result.push(Array.from(array.slice(i, i + components)));\n }\n\n accessorCache.set(accessor, result);\n return result;\n}\n\n/** Throws when the supplied condition is false. */\nfunction assert(condition: boolean, message?: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\nimport type {TypedArray} from '@math.gl/types';\n\n/** Maps glTF accessor type strings to their component counts. */\nexport const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16\n};\n\n/** Maps glTF accessor component-type enums to typed-array constructors. */\nexport const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\n/** Minimal accessor shape required to materialize a typed array. */\ntype GLTFAccessor = {\n /** Numeric component type enum. */\n componentType: number;\n /** Accessor type string such as `VEC3` or `SCALAR`. */\n type: string;\n /** Number of logical elements in the accessor. */\n count: number;\n /** Buffer view carrying the raw bytes. */\n bufferView?: {data: {buffer: ArrayBufferLike; byteOffset?: number}};\n /** Byte offset into the buffer view. */\n byteOffset?: number;\n};\n\n/** Converts a glTF accessor into a typed array plus its component count. */\nexport function accessorToTypedArray(accessor: GLTFAccessor): {\n /** Typed array view over the accessor data. */\n typedArray: TypedArray;\n /** Number of scalar components per element. */\n components: number;\n} {\n const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];\n const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];\n const length = components * accessor.count;\n const {buffer, byteOffset = 0} = accessor.bufferView?.data ?? {};\n\n const typedArray = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);\n\n return {typedArray, components};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {GLTFPostprocessed} from '@loaders.gl/gltf';\n\nexport type GLTFExtensionSupportLevel = 'built-in' | 'parsed-and-wired' | 'loader-only' | 'none';\n\nexport type GLTFExtensionSupport = {\n extensionName: string;\n supported: boolean;\n supportLevel: GLTFExtensionSupportLevel;\n comment: string;\n};\n\ntype GLTFExtensionSupportDefinition = Omit<GLTFExtensionSupport, 'extensionName' | 'supported'>;\n\ntype GLTFPostprocessedWithRemovedExtensions = GLTFPostprocessed & {\n extensionsRemoved?: string[];\n lights?: unknown[];\n};\n\nconst UNKNOWN_EXTENSION_SUPPORT: GLTFExtensionSupportDefinition = {\n supportLevel: 'none',\n comment: 'Not currently listed in the luma.gl glTF extension support registry.'\n};\n\nconst GLTF_EXTENSION_SUPPORT_REGISTRY: Record<string, GLTFExtensionSupportDefinition> = {\n KHR_draco_mesh_compression: {\n supportLevel: 'built-in',\n comment: 'Decoded by loaders.gl before luma.gl builds the scenegraph.'\n },\n EXT_meshopt_compression: {\n supportLevel: 'built-in',\n comment: 'Meshopt-compressed primitives are decoded during load.'\n },\n KHR_mesh_quantization: {\n supportLevel: 'built-in',\n comment: 'Quantized accessors are unpacked before geometry creation.'\n },\n KHR_lights_punctual: {\n supportLevel: 'built-in',\n comment: 'Parsed into luma.gl Light objects.'\n },\n KHR_materials_unlit: {\n supportLevel: 'built-in',\n comment: 'Unlit materials bypass the default lighting path.'\n },\n KHR_materials_emissive_strength: {\n supportLevel: 'built-in',\n comment: 'Applied by the stock PBR shader.'\n },\n KHR_texture_basisu: {\n supportLevel: 'built-in',\n comment: 'BasisU / KTX2 textures pass through when the device supports them.'\n },\n KHR_texture_transform: {\n supportLevel: 'built-in',\n comment: 'UV transforms are applied during load.'\n },\n EXT_texture_webp: {\n supportLevel: 'loader-only',\n comment:\n 'Texture source is resolved during load; final support depends on browser and device decode support.'\n },\n EXT_texture_avif: {\n supportLevel: 'loader-only',\n comment:\n 'Texture source is resolved during load; final support depends on browser and device decode support.'\n },\n KHR_materials_specular: {\n supportLevel: 'built-in',\n comment: 'The stock shader now applies specular factors and textures to the dielectric F0 term.'\n },\n KHR_materials_ior: {\n supportLevel: 'built-in',\n comment: 'The stock shader now drives dielectric reflectance from the glTF IOR value.'\n },\n KHR_materials_transmission: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now applies transmission to the base layer and exposes transparency through alpha, without a scene-color refraction buffer.'\n },\n KHR_materials_volume: {\n supportLevel: 'built-in',\n comment: 'Thickness and attenuation now tint transmitted light in the stock shader.'\n },\n KHR_materials_clearcoat: {\n supportLevel: 'built-in',\n comment: 'The stock shader now adds a secondary clearcoat specular lobe.'\n },\n KHR_materials_sheen: {\n supportLevel: 'built-in',\n comment: 'The stock shader now adds a sheen lobe for cloth-like materials.'\n },\n KHR_materials_iridescence: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now tints specular response with a view-dependent thin-film iridescence approximation.'\n },\n KHR_materials_anisotropy: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now shapes highlights and IBL response with an anisotropy-direction approximation.'\n },\n KHR_materials_pbrSpecularGlossiness: {\n supportLevel: 'loader-only',\n comment:\n 'Extension data can be loaded, but it is not translated into the default metallic-roughness material path.'\n },\n KHR_materials_variants: {\n supportLevel: 'loader-only',\n comment: 'Variant metadata can be loaded, but applications must choose and apply variants.'\n },\n EXT_mesh_gpu_instancing: {\n supportLevel: 'none',\n comment: 'GPU instancing data is not yet converted into luma.gl instanced draw setup.'\n },\n KHR_node_visibility: {\n supportLevel: 'none',\n comment: 'Node-visibility animations and toggles are not mapped onto runtime scenegraph state.'\n },\n KHR_animation_pointer: {\n supportLevel: 'none',\n comment: 'Animation pointers are not mapped onto runtime scenegraph updates.'\n },\n KHR_materials_diffuse_transmission: {\n supportLevel: 'none',\n comment: 'Diffuse-transmission shading is not implemented in the stock PBR shader.'\n },\n KHR_materials_dispersion: {\n supportLevel: 'none',\n comment: 'Chromatic dispersion is not implemented in the stock PBR shader.'\n },\n KHR_materials_volume_scatter: {\n supportLevel: 'none',\n comment: 'Volume scattering is not implemented in the stock PBR shader.'\n },\n KHR_xmp: {\n supportLevel: 'none',\n comment: 'Metadata payloads remain in the loaded glTF, but luma.gl does not interpret them.'\n },\n KHR_xmp_json_ld: {\n supportLevel: 'none',\n comment: 'Metadata is preserved in the glTF, but luma.gl does not interpret it.'\n },\n EXT_lights_image_based: {\n supportLevel: 'none',\n comment: 'Use loadPBREnvironment() or custom environment setup instead.'\n },\n EXT_texture_video: {\n supportLevel: 'none',\n comment: 'Video textures are not created automatically by the stock pipeline.'\n },\n MSFT_lod: {\n supportLevel: 'none',\n comment: 'Level-of-detail switching is not implemented in the stock scenegraph loader.'\n }\n};\n\nexport function getGLTFExtensionSupport(\n gltf: GLTFPostprocessed\n): Map<string, GLTFExtensionSupport> {\n const extensionNames = Array.from(collectGLTFExtensionNames(gltf)).sort();\n const extensionSupportEntries: [string, GLTFExtensionSupport][] = extensionNames.map(\n extensionName => {\n const extensionSupportDefinition =\n GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || UNKNOWN_EXTENSION_SUPPORT;\n\n return [\n extensionName,\n {\n extensionName,\n supported: extensionSupportDefinition.supportLevel === 'built-in',\n supportLevel: extensionSupportDefinition.supportLevel,\n comment: extensionSupportDefinition.comment\n }\n ];\n }\n );\n\n return new Map(extensionSupportEntries);\n}\n\nfunction collectGLTFExtensionNames(gltf: GLTFPostprocessed): Set<string> {\n const gltfWithRemovedExtensions = gltf as GLTFPostprocessedWithRemovedExtensions;\n const extensionNames = new Set<string>();\n\n addExtensionNames(extensionNames, gltf.extensionsUsed);\n addExtensionNames(extensionNames, gltf.extensionsRequired);\n addExtensionNames(extensionNames, gltfWithRemovedExtensions.extensionsRemoved);\n addExtensionNames(extensionNames, Object.keys(gltf.extensions || {}));\n\n if (gltfWithRemovedExtensions.lights?.length || gltf.nodes.some(node => 'light' in node)) {\n extensionNames.add('KHR_lights_punctual');\n }\n\n if (\n gltf.materials.some(material => {\n const gltfMaterial = material as typeof material & {unlit?: boolean};\n return gltfMaterial.unlit || gltfMaterial.extensions?.KHR_materials_unlit;\n })\n ) {\n extensionNames.add('KHR_materials_unlit');\n }\n\n return extensionNames;\n}\n\nfunction addExtensionNames(extensionNames: Set<string>, newExtensionNames: string[] = []): void {\n for (const extensionName of newExtensionNames) {\n extensionNames.add(extensionName);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device} from '@luma.gl/core';\nimport {GroupNode, Material} from '@luma.gl/engine';\nimport {GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {Light} from '@luma.gl/shadertools';\nimport {parseGLTF, type ParseGLTFOptions} from '../parsers/parse-gltf';\nimport {parseGLTFLights} from '../parsers/parse-gltf-lights';\nimport {GLTFAnimator} from './gltf-animator';\nimport {parseGLTFAnimations} from '../parsers/parse-gltf-animations';\nimport {getGLTFExtensionSupport, type GLTFExtensionSupport} from './gltf-extension-support';\n\nexport type GLTFScenegraphBounds = {\n /** World-space axis-aligned bounds for the scene or model. */\n bounds: [[number, number, number], [number, number, number]] | null;\n /** World-space center of the bounds. */\n center: [number, number, number];\n /** World-space bounds size on each axis. */\n size: [number, number, number];\n /** Half of the world-space bounds diagonal, clamped to a small practical minimum. */\n radius: number;\n /** Suggested orbit distance for a 60-degree field of view camera. */\n recommendedOrbitDistance: number;\n};\n\n/** Scenegraph bundle returned from a parsed glTF asset. */\nexport type GLTFScenegraphs = {\n /** Scene roots produced from the glTF scenes array. */\n scenes: GroupNode[];\n /** Materials aligned with the source glTF `materials` array. */\n materials: Material[];\n /** Animation controller for glTF animations. */\n animator: GLTFAnimator;\n /** Parsed punctual lights from the asset. */\n lights: Light[];\n /** Extensions reported by the asset and whether luma.gl supports them. */\n extensionSupport: Map<string, GLTFExtensionSupport>;\n /** Camera-friendly bounds for each scene in `scenes`, in matching order. */\n sceneBounds: GLTFScenegraphBounds[];\n /** Combined camera-friendly bounds for the entire loaded asset. */\n modelBounds: GLTFScenegraphBounds;\n\n /** Map from glTF mesh ids to generated mesh group nodes. */\n gltfMeshIdToNodeMap: Map<string, GroupNode>;\n /** Map from glTF node indices to generated scenegraph nodes. */\n gltfNodeIndexToNodeMap: Map<number, GroupNode>;\n /** Map from glTF node ids to generated scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n\n /** Original post-processed glTF document. */\n gltf: GLTFPostprocessed;\n};\n\n/** Converts a post-processed glTF asset into luma.gl scenegraph nodes and animation helpers. */\nexport function createScenegraphsFromGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options?: ParseGLTFOptions\n): GLTFScenegraphs {\n const {scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap} =\n parseGLTF(device, gltf, options);\n\n const animations = parseGLTFAnimations(gltf);\n const animator = new GLTFAnimator({animations, gltfNodeIdToNodeMap});\n const lights = parseGLTFLights(gltf);\n const extensionSupport = getGLTFExtensionSupport(gltf);\n const sceneBounds = scenes.map(scene => getScenegraphBounds(scene.getBounds()));\n const modelBounds = getCombinedScenegraphBounds(sceneBounds);\n\n return {\n scenes,\n materials,\n animator,\n lights,\n extensionSupport,\n sceneBounds,\n modelBounds,\n gltfMeshIdToNodeMap,\n gltfNodeIdToNodeMap,\n gltfNodeIndexToNodeMap,\n gltf\n };\n}\n\nfunction getScenegraphBounds(bounds: [number[], number[]] | null): GLTFScenegraphBounds {\n if (!bounds) {\n return {\n bounds: null,\n center: [0, 0, 0],\n size: [0, 0, 0],\n radius: 0.5,\n recommendedOrbitDistance: 1\n };\n }\n\n const normalizedBounds: [[number, number, number], [number, number, number]] = [\n [bounds[0][0], bounds[0][1], bounds[0][2]],\n [bounds[1][0], bounds[1][1], bounds[1][2]]\n ];\n const size: [number, number, number] = [\n normalizedBounds[1][0] - normalizedBounds[0][0],\n normalizedBounds[1][1] - normalizedBounds[0][1],\n normalizedBounds[1][2] - normalizedBounds[0][2]\n ];\n const center: [number, number, number] = [\n normalizedBounds[0][0] + size[0] * 0.5,\n normalizedBounds[0][1] + size[1] * 0.5,\n normalizedBounds[0][2] + size[2] * 0.5\n ];\n const maxHalfExtent = Math.max(size[0], size[1], size[2]) * 0.5;\n const radius = Math.max(0.5 * Math.hypot(size[0], size[1], size[2]), 0.001);\n\n return {\n bounds: normalizedBounds,\n center,\n size,\n radius,\n recommendedOrbitDistance: Math.max(\n (Math.max(maxHalfExtent, 0.001) / Math.tan(Math.PI / 6)) * 1.15,\n radius * 1.1\n )\n };\n}\n\nfunction getCombinedScenegraphBounds(sceneBounds: GLTFScenegraphBounds[]): GLTFScenegraphBounds {\n let combinedBounds: [[number, number, number], [number, number, number]] | null = null;\n\n for (const sceneBoundInfo of sceneBounds) {\n if (!sceneBoundInfo.bounds) {\n continue;\n }\n\n if (!combinedBounds) {\n combinedBounds = [\n [...sceneBoundInfo.bounds[0]] as [number, number, number],\n [...sceneBoundInfo.bounds[1]] as [number, number, number]\n ];\n continue;\n }\n\n for (let axis = 0; axis < 3; axis++) {\n combinedBounds[0][axis] = Math.min(combinedBounds[0][axis], sceneBoundInfo.bounds[0][axis]);\n combinedBounds[1][axis] = Math.max(combinedBounds[1][axis], sceneBoundInfo.bounds[1][axis]);\n }\n }\n\n return getScenegraphBounds(combinedBounds);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;ACKA,oBAKO;AACP,sBAA+B;AAuBzB,SAAU,mBAAmB,QAAgB,OAA0B;AAC3E,QAAM,oBAAoB,MAAM,qBAAqB;AAErD,QAAM,iBAAiB,IAAI,6BAAe,QAAQ;IAChD,IAAI;IACJ,SAAS;MACP,cAAc;MACd,cAAc;MACd,WAAW;MACX,WAAW;;;IAGb,UAAM,kCAAiB,MAAM,UAAU;GACxC;AAED,QAAM,oBAAoB,SAAS,QAAQ;IACzC,IAAI;IACJ,mBAAmB,cACjB,kCACE,MAAM,UAAU,WAAW,MAAM,QAAQ,IAAI,GAAG,CAAC,CAAC;IAEtD,SAAS;MACP,cAAc;MACd,cAAc;MACd,WAAW;MACX,WAAW;;GAEd;AAED,QAAM,qBAAqB,SAAS,QAAQ;IAC1C,IAAI;IACJ,mBAAmB,CAAC,SAAyB;AAC3C,YAAM,aAAsC,CAAA;AAC5C,YAAM,YAAY,MAAM,QAAQ,IAAI;AACpC,eAAS,MAAM,GAAG,MAAM,mBAAmB,OAAO;AAChD,mBAAW,SAAK,kCAAiB,MAAM,UAAU,YAAY,WAAW,GAAG,CAAC,CAAC;MAC/E;AACA,aAAO,QAAQ,IAAI,UAAU;IAC/B;IACA,SAAS;MACP,cAAc;MACd,cAAc;MACd,WAAW;;MACX,WAAW;;GAEd;AAED,SAAO;IACL;IACA;IACA;;AAEJ;AAGA,IAAM,QAA2B,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AAGpE,SAAS,SACP,QACA,EACE,IACA,mBACA,QAAO,GAQR;AAED,QAAM,OAAiC,QAAQ,IAC7C,MAAM,IAAI,UAAQ,kBAAkB,IAAI,CAAC,CAAC,EAC1C,KAAK,mBAAgB;AACrB,UAAM,WAAW,CAAA;AACjB,UAAM,QAAQ,CAAC,MAAM,UAAS;AAC5B,eAAS,IAAI,IAAI,cAAc,KAAK;IACtC,CAAC;AACD,WAAO;EACT,CAAC;AACD,SAAO,IAAI,6BAAe,QAAQ;IAChC;IACA,WAAW;IACX,SAAS;IACT;IACA;GACD;AACH;;;ACtHA,kBAAiD;;;ACEjD,IAAY;CAAZ,SAAYA,SAAM;AAChB,EAAAA,QAAAA,QAAA,QAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,OAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,WAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,YAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,WAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,gBAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,cAAA,IAAA,CAAA,IAAA;AAEA,EAAAA,QAAAA,QAAA,KAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,WAAA,IAAA,GAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,qBAAA,IAAA,GAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,UAAA,IAAA,KAAA,IAAA;AAEA,EAAAA,QAAAA,QAAA,QAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,SAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,wBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,uBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,uBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,sBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,oBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,gBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,gBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,QAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,eAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,iBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,qBAAA,IAAA,KAAA,IAAA;AACF,GA3BY,WAAA,SAAM,CAAA,EAAA;;;ACqBZ,SAAU,eAAe,aAAwB;AACrD,SAAO;IACL,cAAc,uBAAuB,YAAY,KAAK;IACtD,cAAc,uBAAuB,YAAY,KAAK;IACtD,WAAW,wBAAwB,YAAY,SAAS;IACxD,GAAG,wBAAwB,YAAY,SAAS;;AAEpD;AAGA,SAAS,uBACP,MAA+E;AAE/E,UAAQ,MAAM;IACZ,KAAK,OAAO;AACV,aAAO;IACT,KAAK,OAAO;AACV,aAAO;IACT,KAAK,OAAO;AACV,aAAO;IACT;AACE,aAAO;EACX;AACF;AAGA,SAAS,wBACP,MAAgD;AAEhD,UAAQ,MAAM;IACZ,KAAK,OAAO;AACV,aAAO;IACT,KAAK,OAAO;AACV,aAAO;IACT;AACE,aAAO;EACX;AACF;AAGA,SAAS,wBACP,MAOa;AAEb,UAAQ,MAAM;IACZ,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,UAAS;IAC9B,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,SAAQ;IAC7B,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,WAAW,cAAc,UAAS;IACvD,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,UAAU,cAAc,UAAS;IACtD,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,WAAW,cAAc,SAAQ;IACtD,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,UAAU,cAAc,SAAQ;IACrD;AACE,aAAO,CAAA;EACX;AACF;;;AFuEM,SAAU,iBACd,QACA,UACA,YACA,SAAgC;AAEhC,QAAM,iBAAoC;IACxC,SAAS;;MAEP,aAAa;MACb,yBAAyB;;IAE3B,UAAU,CAAA;IACV,UAAU;;MAER,QAAQ,CAAC,GAAG,GAAG,CAAC;;MAEhB,yBAAyB,CAAC,GAAG,CAAC;;;IAEhC,YAAY,CAAA;IACZ,cAAc,CAAA;IACd,mBAAmB,CAAA;;AAIrB,iBAAe,QAAQ,aAAa,IAAI;AAExC,QAAM,EAAC,8BAA6B,IAAI;AACxC,MAAI,+BAA+B;AACjC,mBAAe,SAAS,wBACtB,8BAA8B,kBAAkB;AAClD,mBAAe,SAAS,yBACtB,8BAA8B,mBAAmB;AACnD,mBAAe,SAAS,cAAc,8BAA8B,eAAe;AACnF,mBAAe,SAAS,aAAa;AACrC,mBAAe,SAAS,kBAAkB,CAAC,GAAG,CAAC;EACjD;AAEA,MAAI,mCAAS,UAAU;AACrB,mBAAe,QAAQ,WAAW,IAAI;AAEtC,mBAAe,SAAS,kBAAkB,CAAC,GAAG,GAAG,GAAG,CAAC;AACrD,mBAAe,SAAS,eAAe,CAAC,GAAG,GAAG,GAAG,CAAC;EACpD;AAEA,MAAI,WAAW,QAAQ;AAAG,mBAAe,QAAQ,aAAa,IAAI;AAClE,MAAI,WAAW,SAAS,MAAK,mCAAS;AAAa,mBAAe,QAAQ,cAAc,IAAI;AAC5F,MAAI,WAAW,YAAY;AAAG,mBAAe,QAAQ,QAAQ,IAAI;AACjE,MAAI,WAAW,UAAU,KAAK,WAAW,WAAW;AAAG,mBAAe,QAAQ,UAAU,IAAI;AAC5F,MAAI,WAAW,SAAS;AAAG,mBAAe,QAAQ,YAAY,IAAI;AAElE,MAAI,mCAAS;AAA+B,mBAAe,QAAQ,SAAS,IAAI;AAChF,MAAI,mCAAS;AAAQ,mBAAe,QAAQ,YAAY,IAAI;AAE5D,MAAI,UAAU;AACZ,QAAI,QAAQ,uBAAuB,OAAO;AACxC,sCAAgC,UAAU,UAAU;IACtD;AACA,kBAAc,QAAQ,UAAU,gBAAgB,QAAQ,IAAI;EAC9D;AAEA,SAAO;AACT;AAEA,SAAS,gCACP,UACA,YAA+B;AAvOjC;AAyOE,QAAM,0BAA0B,2BAA2B,QAAQ;AACnE,MAAI,wBAAwB,SAAS,KAAK,CAAC,WAAW,YAAY,GAAG;AACnE,oBAAI,KACF,sBAAsB,wBAAwB,KAAK,IAAI,gGAAgG,EACxJ;EACH;AAEA,QAAM,kBAAkB,QAAQ,SAAS,WAAS,cAAS,eAAT,mBAAqB,oBAAmB;AAC1F,MAAI,mBAAmB,WAAW,QAAQ,GAAG;AAC3C;EACF;AAEA,QAAM,sBAAsB,SAAS,gBACjC,uCACA;AACJ,kBAAI,KACF,gDAAgD,kEAAkE,EACnH;AACH;AAEA,SAAS,2BAA2B,UAAyB;AA7P7D;AA8PE,QAAM,0BAAoC,CAAA;AAE1C,OAAI,cAAS,yBAAT,mBAA+B,kBAAkB;AACnD,4BAAwB,KAAK,kBAAkB;EACjD;AACA,OAAI,cAAS,yBAAT,mBAA+B,0BAA0B;AAC3D,4BAAwB,KAAK,0BAA0B;EACzD;AACA,MAAI,SAAS,eAAe;AAC1B,4BAAwB,KAAK,eAAe;EAC9C;AACA,MAAI,SAAS,kBAAkB;AAC7B,4BAAwB,KAAK,kBAAkB;EACjD;AACA,MAAI,SAAS,iBAAiB;AAC5B,4BAAwB,KAAK,iBAAiB;EAChD;AACA,OAAI,oBAAS,eAAT,mBAAqB,2BAArB,mBAA6C,iBAAiB;AAChE,4BAAwB,KAAK,wCAAwC;EACvE;AACA,OAAI,oBAAS,eAAT,mBAAqB,2BAArB,mBAA6C,sBAAsB;AACrE,4BAAwB,KAAK,6CAA6C;EAC5E;AACA,OAAI,oBAAS,eAAT,mBAAqB,+BAArB,mBAAiD,qBAAqB;AACxE,4BAAwB,KAAK,gDAAgD;EAC/E;AACA,OAAI,oBAAS,eAAT,mBAAqB,4BAArB,mBAA8C,kBAAkB;AAClE,4BAAwB,KAAK,0CAA0C;EACzE;AACA,OAAI,oBAAS,eAAT,mBAAqB,4BAArB,mBAA8C,2BAA2B;AAC3E,4BAAwB,KAAK,mDAAmD;EAClF;AACA,OAAI,oBAAS,eAAT,mBAAqB,wBAArB,mBAA0C,mBAAmB;AAC/D,4BAAwB,KAAK,uCAAuC;EACtE;AACA,OAAI,oBAAS,eAAT,mBAAqB,wBAArB,mBAA0C,uBAAuB;AACnE,4BAAwB,KAAK,2CAA2C;EAC1E;AACA,OAAI,oBAAS,eAAT,mBAAqB,8BAArB,mBAAgD,oBAAoB;AACtE,4BAAwB,KAAK,8CAA8C;EAC7E;AACA,OAAI,oBAAS,eAAT,mBAAqB,6BAArB,mBAA+C,mBAAmB;AACpE,4BAAwB,KAAK,4CAA4C;EAC3E;AAEA,SAAO;AACT;AAGA,SAAS,cACP,QACA,UACA,gBACA,MAAwB;AAnT1B;AAqTE,iBAAe,SAAS,QAAQ,QAC9B,SAAS,WAAS,cAAS,eAAT,mBAAqB,oBAAmB;AAG5D,MAAI,SAAS,sBAAsB;AACjC,8BAA0B,QAAQ,SAAS,sBAAsB,gBAAgB,IAAI;EACvF;AACA,MAAI,SAAS,eAAe;AAC1B,eAAW,QAAQ,SAAS,eAAe,qBAAqB,gBAAgB;MAC9E,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;AAED,UAAM,EAAC,QAAQ,EAAC,IAAI,SAAS;AAC7B,mBAAe,SAAS,cAAc;EACxC;AACA,MAAI,SAAS,kBAAkB;AAC7B,eAAW,QAAQ,SAAS,kBAAkB,wBAAwB,gBAAgB;MACpF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;AAED,UAAM,EAAC,WAAW,EAAC,IAAI,SAAS;AAChC,mBAAe,SAAS,oBAAoB;EAC9C;AACA,iBAAe,SAAS,iBAAiB,SAAS,kBAAkB,CAAC,GAAG,GAAG,CAAC;AAC5E,MAAI,SAAS,iBAAiB;AAC5B,eAAW,QAAQ,SAAS,iBAAiB,uBAAuB,gBAAgB;MAClF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AAEA,0BAAwB,QAAQ,SAAS,YAAY,gBAAgB,IAAI;AAEzE,UAAQ,SAAS,aAAa,UAAU;IACtC,KAAK;AACH;IACF,KAAK,QAAQ;AACX,YAAM,EAAC,cAAc,IAAG,IAAI;AAC5B,qBAAe,QAAQ,cAAc,IAAI;AACzC,qBAAe,SAAS,qBAAqB;AAC7C,qBAAe,SAAS,cAAc;AACtC;IACF;IACA,KAAK;AACH,sBAAI,KAAK,2EAA2E,EAAC;AACrF,gCAA0B,cAAc;AAExC;EACJ;AACF;AAEA,SAAS,0BAA0B,gBAAiC;AAClE,iBAAe,WAAW,QAAQ;AAClC,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAEhD,iBAAe,aAAa,OAAO,IAAI;AACvC,iBAAe,aAAa,eAAe,IAAI,OAAO;AACtD,iBAAe,aAAa,WAAW,IAAI;IACzC,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;;AAEX;AAEA,SAAS,oCAAoC,gBAAiC;AAC5E,iBAAe,WAAW,QAAQ;AAClC,iBAAe,WAAW,oBAAoB;AAC9C,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAEhD,iBAAe,aAAa,OAAO,IAAI;AACvC,iBAAe,aAAa,WAAW,IAAI;AAC3C,iBAAe,aAAa,eAAe,IAAI,OAAO;AACtD,iBAAe,aAAa,WAAW,IAAI;IACzC,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;;AAEX;AAGA,SAAS,0BACP,QACA,sBACA,gBACA,MAAwB;AAExB,MAAI,qBAAqB,kBAAkB;AACzC,eACE,QACA,qBAAqB,kBACrB,wBACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EAEL;AACA,iBAAe,SAAS,kBAAkB,qBAAqB,mBAAmB,CAAC,GAAG,GAAG,GAAG,CAAC;AAE7F,MAAI,qBAAqB,0BAA0B;AACjD,eACE,QACA,qBAAqB,0BACrB,gCACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EAEL;AACA,QAAM,EAAC,iBAAiB,GAAG,kBAAkB,EAAC,IAAI;AAClD,iBAAe,SAAS,0BAA0B,CAAC,gBAAgB,eAAe;AACpF;AAEA,SAAS,wBACP,QACA,YACA,gBACA,MAAwB;AAExB,MAAI,CAAC,YAAY;AACf;EACF;AAEA,MAAI,4BAA4B,UAAU,GAAG;AAC3C,mBAAe,QAAQ,yBAAyB,IAAI;EACtD;AAEA,yBAAuB,QAAQ,WAAW,wBAAwB,gBAAgB,IAAI;AACtF,oBAAkB,WAAW,mBAAmB,cAAc;AAC9D,6BAA2B,QAAQ,WAAW,4BAA4B,gBAAgB,IAAI;AAC9F,uBAAqB,QAAQ,WAAW,sBAAsB,gBAAgB,IAAI;AAClF,0BAAwB,QAAQ,WAAW,yBAAyB,gBAAgB,IAAI;AACxF,sBAAoB,QAAQ,WAAW,qBAAqB,gBAAgB,IAAI;AAChF,4BAA0B,QAAQ,WAAW,2BAA2B,gBAAgB,IAAI;AAC5F,2BAAyB,QAAQ,WAAW,0BAA0B,gBAAgB,IAAI;AAC1F,iCAA+B,WAAW,iCAAiC,cAAc;AAC3F;AAEA,SAAS,4BAA4B,YAAkC;AACrE,SAAO,QACL,WAAW,0BACT,WAAW,qBACX,WAAW,8BACX,WAAW,wBACX,WAAW,2BACX,WAAW,uBACX,WAAW,6BACX,WAAW,wBAAwB;AAEzC;AAEA,SAAS,uBACP,QACA,WACA,gBACA,MAAwB;AAExB,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,qBAAqB;AACjC,mBAAe,SAAS,sBAAsB,UAAU;EAC1D;AACA,MAAI,UAAU,mBAAmB,QAAW;AAC1C,mBAAe,SAAS,0BAA0B,UAAU;EAC9D;AACA,MAAI,UAAU,sBAAsB;AAClC,eAAW,QAAQ,UAAU,sBAAsB,4BAA4B,gBAAgB;MAC7F,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AACA,MAAI,UAAU,iBAAiB;AAC7B,eAAW,QAAQ,UAAU,iBAAiB,gCAAgC,gBAAgB;MAC5F,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AACF;AAEA,SAAS,kBACP,WACA,gBAAiC;AAEjC,OAAI,uCAAW,SAAQ,QAAW;AAChC,mBAAe,SAAS,MAAM,UAAU;EAC1C;AACF;AAEA,SAAS,2BACP,QACA,WACA,gBACA,MAAwB;AAExB,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,uBAAuB,QAAW;AAC9C,mBAAe,SAAS,qBAAqB,UAAU;EACzD;AACA,MAAI,UAAU,qBAAqB;AACjC,eAAW,QAAQ,UAAU,qBAAqB,2BAA2B,gBAAgB;MAC3F,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AAEA,OAAK,UAAU,sBAAsB,KAAK,KAAK,UAAU,qBAAqB;AAC5E,oBAAI,KACF,2GAA2G,EAC5G;AACD,wCAAoC,cAAc;EACpD;AACF;AAEA,SAAS,qBACP,QACA,WACA,gBACA,MAAwB;AAExB,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,oBAAoB,QAAW;AAC3C,mBAAe,SAAS,kBAAkB,UAAU;EACtD;AACA,MAAI,UAAU,kBAAkB;AAC9B,eAAW,QAAQ,UAAU,kBAAkB,wBAAwB,gBAAgB;MACrF,gBAAgB;QACd,QAAQ;;MAEV;KACD;EACH;AACA,MAAI,UAAU,wBAAwB,QAAW;AAC/C,mBAAe,SAAS,sBAAsB,UAAU;EAC1D;AACA,MAAI,UAAU,kBAAkB;AAC9B,mBAAe,SAAS,mBAAmB,UAAU;EACvD;AACF;AAEA,SAAS,wBACP,QACA,WACA,gBACA,MAAwB;AAExB,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,oBAAoB,QAAW;AAC3C,mBAAe,SAAS,kBAAkB,UAAU;EACtD;AACA,MAAI,UAAU,6BAA6B,QAAW;AACpD,mBAAe,SAAS,2BAA2B,UAAU;EAC/D;AACA,MAAI,UAAU,kBAAkB;AAC9B,eAAW,QAAQ,UAAU,kBAAkB,wBAAwB,gBAAgB;MACrF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AACA,MAAI,UAAU,2BAA2B;AACvC,eACE,QACA,UAAU,2BACV,iCACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EAEL;AACA,MAAI,UAAU,wBAAwB;AACpC,eACE,QACA,UAAU,wBACV,8BACA,gBACA;MACE,gBAAgB;QACd,QAAQ;;MAEV;KACD;EAEL;AACF;AAEA,SAAS,oBACP,QACA,WACA,gBACA,MAAwB;AAExB,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,kBAAkB;AAC9B,mBAAe,SAAS,mBAAmB,UAAU;EACvD;AACA,MAAI,UAAU,yBAAyB,QAAW;AAChD,mBAAe,SAAS,uBAAuB,UAAU;EAC3D;AACA,MAAI,UAAU,mBAAmB;AAC/B,eAAW,QAAQ,UAAU,mBAAmB,yBAAyB,gBAAgB;MACvF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AACA,MAAI,UAAU,uBAAuB;AACnC,eACE,QACA,UAAU,uBACV,6BACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EAEL;AACF;AAEA,SAAS,0BACP,QACA,WACA,gBACA,MAAwB;AAExB,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,sBAAsB,QAAW;AAC7C,mBAAe,SAAS,oBAAoB,UAAU;EACxD;AACA,MAAI,UAAU,mBAAmB,QAAW;AAC1C,mBAAe,SAAS,iBAAiB,UAAU;EACrD;AACA,MACE,UAAU,gCAAgC,UAC1C,UAAU,gCAAgC,QAC1C;AACA,mBAAe,SAAS,4BAA4B;MAClD,UAAU,+BAA+B;MACzC,UAAU,+BAA+B;;EAE7C;AACA,MAAI,UAAU,oBAAoB;AAChC,eAAW,QAAQ,UAAU,oBAAoB,0BAA0B,gBAAgB;MACzF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AACA,MAAI,UAAU,6BAA6B;AACzC,eACE,QACA,UAAU,6BACV,mCACA,gBACA;MACE,gBAAgB;QACd,QAAQ;;MAEV;KACD;EAEL;AACF;AAEA,SAAS,yBACP,QACA,WACA,gBACA,MAAwB;AAExB,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,uBAAuB,QAAW;AAC9C,mBAAe,SAAS,qBAAqB,UAAU;EACzD;AACA,MAAI,UAAU,uBAAuB,QAAW;AAC9C,mBAAe,SAAS,qBAAqB,UAAU;EACzD;AACA,MAAI,UAAU,mBAAmB;AAC/B,eAAW,QAAQ,UAAU,mBAAmB,yBAAyB,gBAAgB;MACvF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;KACD;EACH;AACF;AAEA,SAAS,+BACP,WACA,gBAAiC;AAEjC,OAAI,uCAAW,sBAAqB,QAAW;AAC7C,mBAAe,SAAS,mBAAmB,UAAU;EACvD;AACF;AAGA,SAAS,WACP,QACA,aACA,aACA,gBACA,sBAA2C,CAAA,GAAE;AAnxB/C;AAqxBE,QAAM,EAAC,iBAAiB,CAAA,GAAI,KAAI,IAAI;AACpC,QAAM,EAAC,QAAQ,mBAAkB,IAAI;AACrC,QAAM,sBAAsB,mBAAmB,aAAa,IAAI;AAChE,QAAM,SAAQ,+BAAoB,YAApB,mBAA6B,WAA7B,mBAAqC;AACnD,MAAI,CAAC,OAAO;AACV,oBAAI,KAAK,wCAAwC,OAAO,WAAW,GAAG,EAAC;AACvE;EACF;AAEA,QAAM,cAAc;IAClB,OAAO;;IACP,OAAO;;IACP,WAAW;;IACX,WAAW;;IACX,IAAG,gEAAqB,YAArB,mBAA8B;;AAGnC,QAAM,cAAc;IAClB,IAAI,oBAAoB,eAAe,oBAAoB;IAC3D,SAAS,eAAe,WAAW;;AAGrC,MAAI;AAEJ,MAAI,MAAM,YAAY;AACpB,cAAU,wBAAwB,QAAQ,OAAO,WAAW;EAC9D,OAAO;AACL,UAAM,EAAC,OAAO,OAAM,IAAI,OAAO,qBAAqB,KAAK;AACzD,cAAU,OAAO,cAAc;MAC7B,GAAG;MACH;MACA;MACA,MAAM;KACP;EACH;AAEA,iBAAe,SAAS,WAAW,IAAI;AACvC,MAAI;AAAQ,mBAAe,QAAQ,MAAM,IAAI;AAC7C,MAAI,oBAAoB;AACtB,mBAAe,SAAS,kBAAkB,IAAI;EAChD;AACA,iBAAe,kBAAkB,KAAK,OAAO;AAC/C;AAEA,SAAS,mBAAmB,aAA0B,MAAwB;AAC5E,MAAI,YAAY,WAAW,YAAY,UAAU,UAAa,EAAC,6BAAM,WAAU;AAC7E,WAAO;EACT;AAEA,QAAM,uBAAuB,KAAK,SAAS,YAAY,KAAK;AAI5D,MAAI,CAAC,sBAAsB;AACzB,WAAO;EACT;AAEA,MAAI,aAAa,wBAAwB,qBAAqB,SAAS;AACrE,WAAO;MACL,GAAG;MACH,GAAG;MACH,SAAS,qBAAqB;;EAElC;AAEA,MAAI,EAAE,YAAY,uBAAuB;AACvC,WAAO;EACT;AAEA,SAAO;IACL,GAAG;IACH,SAAS;;AAEb;AAuCA,SAAS,gCACP,QACA,aAAgD;AAEhD,SAAO,OAAO,cAAc;IAC1B,GAAG;IACH,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,WAAW;GACZ;AACH;AAEA,SAAS,+BAA+B,OAAyB;AAC/D,SAAO,MAAM;AACf;AAQA,SAAS,0BACP,WACA,YACA,QAAqB;AAErB,QAAM,EAAC,aAAa,GAAG,cAAc,EAAC,IAAI,iCAAqB,QAAQ,MAAM;AAC7E,MAAI,QAAQ;AACZ,WAAS,IAAI,KAAK,KAAK;AACrB,UAAM,IAAI,KAAK,IAAI,GAAG,aAAa,CAAC;AACpC,UAAM,IAAI,KAAK,IAAI,GAAG,cAAc,CAAC;AACrC,QAAI,IAAI,cAAc,IAAI;AAAa;AACvC;EACF;AACA,SAAO;AACT;AASM,SAAU,wBACd,QACA,OACA,aAAgD;AAt7BlD;AAy7BE,MAAI;AAEJ,MAAI,MAAM,QAAS,MAAc,IAAI,OAAM,WAAc,KAAK,CAAC,MAApB,mBAAuB,OAAM;AAEtE,aAAU,MAAmC;EAC/C,WAAW,aAAa,SAAS,MAAM,QAAS,MAAqC,OAAO,GAAG;AAE7F,aAAU,MAAqC;EACjD,OAAO;AACL,aAAS,CAAA;EACX;AAEA,MAAI,OAAO,WAAW,KAAK,GAAC,YAAO,CAAC,MAAR,mBAAW,OAAM;AAC3C,oBAAI,KACF,sFAAsF,EACvF;AACD,WAAO,gCAAgC,QAAQ,WAAW;EAC5D;AAEA,QAAM,YAAY,OAAO,CAAC;AAC1B,QAAM,YAAY,UAAU,SAAU,MAAc,SAAS;AAC7D,QAAM,aAAa,UAAU,UAAW,MAAc,UAAU;AAEhE,MAAI,aAAa,KAAK,cAAc,GAAG;AACrC,oBAAI,KAAK,+EAA+E,EAAC;AACzF,WAAO,gCAAgC,QAAQ,WAAW;EAC5D;AAEA,QAAM,SAAS,+BAA+B,SAAS;AAEvD,MAAI,CAAC,QAAQ;AACX,oBAAI,KAAK,mFAAmF,EAAC;AAC7F,WAAO,gCAAgC,QAAQ,WAAW;EAC5D;AAWA,QAAM,eAAe,0BAA0B,WAAW,YAAY,MAAM;AAC5E,QAAM,aAAa,KAAK,IAAI,OAAO,QAAQ,YAAY;AAEvD,MAAI,kBAAkB;AACtB,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAM,QAAQ,OAAO,CAAC;AACtB,QAAI,CAAC,MAAM,QAAQ,MAAM,SAAS,KAAK,MAAM,UAAU,GAAG;AACxD,sBAAI,KAAK,sCAAsC,2CAA2C,EAAC;AAC3F;IACF;AACA,UAAM,cAAc,+BAA+B,KAAK;AACxD,QAAI,eAAe,gBAAgB,QAAQ;AACzC,sBAAI,KACF,sCAAsC,aAAa,mCAAmC,qBAAqB,EAC5G;AACD;IACF;AACA,UAAM,YAAY,KAAK,IAAI,GAAG,aAAa,CAAC;AAC5C,UAAM,YAAY,KAAK,IAAI,GAAG,cAAc,CAAC;AAC7C,QAAI,MAAM,UAAU,aAAa,MAAM,WAAW,WAAW;AAC3D,sBAAI,KACF,sCAAsC,gBAAgB,MAAM,SAAS,MAAM,+BACjD,aAAa,uBAAuB,EAC/D;AACD;IACF;AACA;EACF;AAEA,QAAM,UAAU,OAAO,cAAc;IACnC,GAAG;IACH;IACA,OAAO,oBAAQ,UAAU,oBAAQ;IACjC,OAAO;IACP,QAAQ;IACR,WAAW;IACX,MAAM,UAAU;GACjB;AAGD,WAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACxC,YAAQ,UAAU,OAAO,CAAC,EAAE,MAAM;MAChC,OAAO,OAAO,CAAC,EAAE;MACjB,QAAQ,OAAO,CAAC,EAAE;MAClB,UAAU;KACX;EACH;AAEA,SAAO;AACT;;;AGthCA,IAAAC,eAAsB;AAItB,IAAM,oBAAoB;AAGpB,SAAU,gBAAgB,MAAuB;AAPvD;AAQE,QAAM;;IAEH,KAA8C,YAC/C,gBAAK,eAAL,mBAAkB,2BAAlB,mBAA2C;;AAC7C,MAAI,CAAC,aAAa,CAAC,MAAM,QAAQ,SAAS,KAAK,UAAU,WAAW,GAAG;AACrE,WAAO,CAAA;EACT;AAEA,QAAM,SAAkB,CAAA;AACxB,QAAM,iBAAiB,oBAAoB,KAAK,SAAS,CAAA,CAAE;AAC3D,QAAM,sBAAsB,oBAAI,IAAG;AAEnC,aAAW,QAAQ,KAAK,SAAS,CAAA,GAAI;AACnC,UAAM,aACH,KAAkD,WACnD,gBAAK,eAAL,mBAAiB,wBAAjB,mBAAsC;AACxC,QAAI,OAAO,eAAe,UAAU;AAElC;IACF;AACA,UAAM,YAAY,UAAU,UAAU;AACtC,QAAI,CAAC,WAAW;AAEd;IACF;AAEA,UAAM,QAAQ,wBACX,UAAU,SAAS,CAAC,GAAG,GAAG,CAAC,CAA8B;AAE5D,UAAM,YAAY,UAAU,aAAa;AACzC,UAAM,QAAQ,UAAU;AACxB,UAAM,cAAc,mBAAmB,MAAM,gBAAgB,mBAAmB;AAEhF,YAAQ,UAAU,MAAM;MACtB,KAAK;AACH,eAAO,KAAK,sBAAsB,aAAa,OAAO,SAAS,CAAC;AAChE;MACF,KAAK;AACH,eAAO,KAAK,gBAAgB,aAAa,OAAO,WAAW,KAAK,CAAC;AACjE;MACF,KAAK;AACH,eAAO,KAAK,eAAe,aAAa,OAAO,WAAW,OAAO,UAAU,IAAI,CAAC;AAChF;MACF;AAEE;IACJ;EACF;AAEA,SAAO;AACT;AAKA,SAAS,wBAAwB,OAA+B;AAC9D,SAAO,MAAM,IAAI,eAAa,YAAY,iBAAiB;AAC7D;AAKA,SAAS,gBACP,aACA,OACA,WACA,OAAc;AAEd,QAAM,WAAW,iBAAiB,WAAW;AAE7C,MAAI,cAAkD,CAAC,GAAG,GAAG,CAAC;AAC9D,MAAI,UAAU,UAAa,QAAQ,GAAG;AACpC,kBAAc,CAAC,GAAG,GAAG,KAAK,QAAQ,MAAM;EAC1C;AAEA,SAAO;IACL,MAAM;IACN;IACA;IACA;IACA;;AAEJ;AAKA,SAAS,sBACP,aACA,OACA,WAAiB;AAEjB,QAAM,YAAY,kBAAkB,WAAW;AAE/C,SAAO;IACL,MAAM;IACN;IACA;IACA;;AAEJ;AAKA,SAAS,eACP,aACA,OACA,WACA,OACA,OAA2D,CAAA,GAAE;AAE7D,QAAM,WAAW,iBAAiB,WAAW;AAC7C,QAAM,YAAY,kBAAkB,WAAW;AAE/C,MAAI,cAAkD,CAAC,GAAG,GAAG,CAAC;AAC9D,MAAI,UAAU,UAAa,QAAQ,GAAG;AACpC,kBAAc,CAAC,GAAG,GAAG,KAAK,QAAQ,MAAM;EAC1C;AAEA,SAAO;IACL,MAAM;IACN;IACA;IACA;IACA;IACA;IACA,gBAAgB,KAAK,kBAAkB;IACvC,gBAAgB,KAAK,kBAAkB,KAAK,KAAK;;AAErD;AAKA,SAAS,oBAAoB,OAA8B;AACzD,QAAM,iBAAiB,oBAAI,IAAG;AAE9B,aAAW,QAAQ,OAAO;AACxB,eAAW,aAAa,KAAK,YAAY,CAAA,GAAI;AAC3C,qBAAe,IAAI,UAAU,IAAI,IAAI;IACvC;EACF;AAEA,SAAO;AACT;AAKA,SAAS,mBACP,MACA,gBACA,qBAAyC;AAEzC,QAAM,oBAAoB,oBAAoB,IAAI,KAAK,EAAE;AACzD,MAAI,mBAAmB;AACrB,WAAO;EACT;AAEA,QAAM,cAAc,mBAAmB,IAAI;AAC3C,QAAM,aAAa,eAAe,IAAI,KAAK,EAAE;AAC7C,QAAM,cAAc,aAChB,IAAI,qBACF,mBAAmB,YAAY,gBAAgB,mBAAmB,CAAC,EACnE,cAAc,WAAW,IAC3B;AAEJ,sBAAoB,IAAI,KAAK,IAAI,WAAW;AAC5C,SAAO;AACT;AAKA,SAAS,mBAAmB,MAA2B;AACrD,MAAI,KAAK,QAAQ;AACf,WAAO,IAAI,qBAAQ,KAAK,MAAM;EAChC;AAEA,QAAM,SAAS,IAAI,qBAAO;AAE1B,MAAI,KAAK,aAAa;AACpB,WAAO,UAAU,KAAK,WAAW;EACnC;AAEA,MAAI,KAAK,UAAU;AACjB,WAAO,cAAc,IAAI,qBAAO,EAAG,eAAe,KAAK,QAAQ,CAAC;EAClE;AAEA,MAAI,KAAK,OAAO;AACd,WAAO,MAAM,KAAK,KAAK;EACzB;AAEA,SAAO;AACT;AAKA,SAAS,iBAAiB,aAAoB;AAC5C,SAAO,YAAY,iBAAiB,CAAC,GAAG,GAAG,CAAC,CAAC;AAC/C;AAKA,SAAS,kBAAkB,aAAoB;AAC7C,SAAO,YAAY,mBAAmB,CAAC,GAAG,GAAG,EAAE,CAAC;AAClD;;;ACpNA,IAAAC,iBAQO;AAOP,IAAAC,sBAA0B;;;ACZpB,SAAU,4BACd,UAOuB;AAGvB,UAAQ,UAAU;IAChB,KAAK,OAAO;AAAQ,aAAO;IAC3B,KAAK,OAAO;AAAO,aAAO;IAC1B,KAAK,OAAO;AAAY,aAAO;IAC/B,KAAK,OAAO;AAAW,aAAO;IAC9B,KAAK,OAAO;AAAgB,aAAO;IACnC;AAAS,YAAM,IAAI,MAAM,OAAO,QAAQ,CAAC;EAC3C;AACF;;;ACvBA,IAAAC,eASO;AACP,IAAAC,iBAA6B;AAC7B,yBAAgC;AAChC,IAAAA,iBAOO;AAGP,IAAM;;EAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuF1B,IAAM;;EAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDtB,IAAM;;EAAgB;;;;;;;;;AAgChB,SAAU,mBAAmB,QAAgB,SAAkC;AACnF,QAAM,kBACJ,QAAQ,mBAAmB,IAAI,+BAAgB,QAAQ,EAAC,SAAS,CAAC,8BAAW,EAAC,CAAC;AAEjF,QAAM,mBAAmB,EAAC,GAAG,QAAQ,mBAAmB,SAAQ;AAChE,SAAO,iBAAiB;AACxB,QAAM,mBAAmB,OAAO,YAC9B,OAAO,QAAQ;IACb,GAAG;IACH,GAAG,QAAQ,mBAAmB;GAC/B,EAAE,OACD,CAAC,CAAC,MAAM,KAAK,MAAM,gBAAgB,YAAY,IAAI,KAAK,0BAA0B,KAAK,CAAC,CACzF;AAGH,QAAM,WAAW,gBAAgB,eAAe;IAC9C,IAAI,QAAQ;IACZ,UAAU;GACX;AACD,WAAS,SAAS,EAAC,aAAa,iBAAgB,CAAC;AAEjD,SAAO;AACT;AAGM,SAAU,gBAAgB,QAAgB,SAA+B;AAC7E,QAAM,EAAC,IAAI,UAAU,oBAAoB,aAAa,eAAe,CAAA,EAAE,IAAI;AAE3E,mBAAI,KAAK,GAAG,6BAA6B,mBAAmB,OAAO,EAAC;AAKpE,QAAM,mBAA0B,CAAA;AAIhC,QAAM,aAAuC;IAC3C,mBAAmB;IACnB,cAAc;IACd,aAAa;IACb,UAAU;;AAGZ,QAAM,aAAyB;IAC7B;IACA,QAAQ;IACR;IACA;IACA;IACA,UAAU,SAAS;IACnB;IACA,SAAS,CAAC,gCAAa,uBAAI;IAC3B,GAAG;IAEH,SAAS,EAAC,GAAG,mBAAmB,SAAS,GAAG,aAAa,QAAO;IAChE,YAAY,EAAC,GAAG,YAAY,GAAG,mBAAmB,YAAY,GAAG,aAAa,WAAU;;AAG1F,QAAM,WACJ,QAAQ,YACR,mBAAmB,QAAQ;IACzB,IAAI,KAAK,GAAG,gBAAgB;IAC5B;GACD;AACH,aAAW,WAAW;AAEtB,QAAM,QAAQ,IAAI,qBAAM,QAAQ,UAAU;AAE1C,QAAM,yBAAyB;IAC7B,GAAG,mBAAmB;IACtB,GAAG,aAAa;IAChB,GAAG,mBAAmB;IACtB,GAAG,aAAa;;AAElB,QAAM,wBAAwB,yBAC5B,MAAM,aAAa,WAAU,GAC7B,UACA,sBAAsB;AAExB,QAAM,aAAa,SAAS,qBAAqB;AACjD,SAAO,IAAI,yBAAU,EAAC,kBAAkB,MAAK,CAAC;AAChD;AAEA,SAAS,0BAA0B,OAAc;AAC/C,SACE,iBAAiB,uBACjB,iBAAiB,iCACjB,iBAAiB,wBACjB,iBAAiB,wBACjB,iBAAiB;AAErB;AAEA,SAAS,yBACP,SAKA,UACA,mBAA0C;AAE1C,QAAM,0BAA0B,oBAAI,IAAG;AACvC,aAAWC,WAAU,SAAS;AAC5B,eAAW,eAAe,OAAO,KAAKA,QAAO,gBAAgB,CAAA,CAAE,GAAG;AAChE,8BAAwB,IAAI,aAAaA,QAAO,IAAI;IACtD;AACA,eAAW,WAAWA,QAAO,iBAAiB,CAAA,GAAI;AAChD,8BAAwB,IAAI,QAAQ,MAAMA,QAAO,IAAI;IACvD;EACF;AAEA,QAAM,wBAAiE,CAAA;AACvE,aAAW,CAAC,cAAc,KAAK,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AACrE,QAAI,UAAU,QAAW;AACvB;IACF;AAEA,UAAM,aAAa,wBAAwB,IAAI,YAAY;AAC3D,QAAI,CAAC,cAAc,SAAS,WAAW,UAAU,GAAG;AAClD;IACF;AAEA,0BAAsB,UAAU,MAAM,CAAA;AACtC,0BAAsB,UAAU,EAAE,YAAY,IAAI;EACpD;AAEA,SAAO;AACT;;;AFhSA,IAAM,iBAA6C;EACjD,cAAc,CAAA;EACd,UAAU;EACV,+BAA+B;EAC/B,QAAQ;EACR,aAAa;;AAOT,SAAU,UACd,QACA,MACA,UAA4B,CAAA,GAAE;AAa9B,QAAM,kBAAkB,EAAC,GAAG,gBAAgB,GAAG,QAAO;AACtD,QAAM,kBAAkB,IAAI,+BAAgB,QAAQ,EAAC,SAAS,CAAC,+BAAW,EAAC,CAAC;AAC5E,QAAM,aAAa,KAAK,aAAa,CAAA,GAAI,IAAI,CAAC,cAAc,kBAC1D,mBAAmB,QAAQ;IACzB,IAAI,kBAAkB,cAAc,aAAa;IACjD,oBAAoB,iBAClB,QACA,cACA,CAAA,GACA;MACE,GAAG;MACH;MACA,oBAAoB;KACrB;IAEH;GACD,CAAC;AAEJ,QAAM,8BAA8B,oBAAI,IAAG;AAC3C,GAAC,KAAK,aAAa,CAAA,GAAI,QAAQ,CAAC,cAAc,kBAAiB;AAC7D,gCAA4B,IAAI,aAAa,IAAI,UAAU,aAAa,CAAC;EAC3E,CAAC;AAED,QAAM,sBAAsB,oBAAI,IAAG;AACnC,OAAK,OAAO,QAAQ,CAAC,UAAU,QAAO;AACpC,UAAM,UAAU,sBACd,QACA,UACA,MACA,6BACA,eAAe;AAEjB,wBAAoB,IAAI,SAAS,IAAI,OAAO;EAC9C,CAAC;AAED,QAAM,yBAAyB,oBAAI,IAAG;AACtC,QAAM,sBAAsB,oBAAI,IAAG;AAEnC,OAAK,MAAM,QAAQ,CAAC,UAAU,QAAO;AACnC,UAAM,UAAU,sBAAsB,QAAQ,UAAU,eAAe;AACvE,2BAAuB,IAAI,KAAK,OAAO;AACvC,wBAAoB,IAAI,SAAS,IAAI,OAAO;EAC9C,CAAC;AAID,OAAK,MAAM,QAAQ,CAAC,UAAU,QAAO;AACnC,2BAAuB,IAAI,GAAG,EAAG,KAC9B,SAAS,YAAY,CAAA,GAAI,IAAI,CAAC,EAAC,GAAE,MAAK;AACrC,YAAM,QAAQ,oBAAoB,IAAI,EAAE;AACxC,UAAI,CAAC;AAAO,cAAM,IAAI,MAAM,qBAAqB,cAAc,KAAK;AACpE,aAAO;IACT,CAAC,CAAC;AAIJ,QAAI,SAAS,MAAM;AACjB,YAAM,OAAO,oBAAoB,IAAI,SAAS,KAAK,EAAE;AACrD,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,0BAA0B,SAAS,KAAK,cAAc,KAAK;MAC7E;AACA,6BAAuB,IAAI,GAAG,EAAG,IAAI,IAAI;IAC3C;EACF,CAAC;AAED,QAAM,SAAS,KAAK,OAAO,IAAI,eAAY;AACzC,UAAM,YAAY,UAAU,SAAS,CAAA,GAAI,IAAI,CAAC,EAAC,GAAE,MAAK;AACpD,YAAM,QAAQ,oBAAoB,IAAI,EAAE;AACxC,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,qBAAqB,eAAe,UAAU,QAAQ,UAAU,IAAI;AACtF,aAAO;IACT,CAAC;AACD,WAAO,IAAI,yBAAU;MACnB,IAAI,UAAU,QAAQ,UAAU;MAChC;KACD;EACH,CAAC;AAED,SAAO,EAAC,QAAQ,WAAW,qBAAqB,qBAAqB,uBAAsB;AAC7F;AAGA,SAAS,sBACP,QACA,UACA,SAAmC;AAEnC,SAAO,IAAI,yBAAU;IACnB,IAAI,SAAS,QAAQ,SAAS;IAC9B,UAAU,CAAA;IACV,QAAQ,SAAS;IACjB,UAAU,SAAS;IACnB,UAAU,SAAS;IACnB,OAAO,SAAS;GACjB;AACH;AAGA,SAAS,sBACP,QACA,UACA,MACA,6BACA,SAAmC;AAEnC,QAAM,iBAAiB,SAAS,cAAc,CAAA;AAC9C,QAAM,aAAa,eAAe,IAAI,CAAC,eAAe,MACpD,2BAA2B;IACzB;IACA;IACA,gBAAgB;IAChB;IACA;IACA;IACA;GACD,CAAC;AAEJ,QAAM,OAAO,IAAI,yBAAU;IACzB,IAAI,SAAS,QAAQ,SAAS;IAC9B,UAAU;GACX;AAED,SAAO;AACT;AAcA,SAAS,2BAA2B,EAClC,QACA,eACA,gBACA,UACA,MACA,6BACA,QAAO,GAC2B;AAClC,QAAM,KAAK,cAAc,QAAQ,GAAG,SAAS,QAAQ,SAAS,gBAAgB;AAC9E,QAAM,WAAW,4BAA4B,cAAc,QAAQ,CAAC;AACpE,QAAM,cAAc,cAAc,UAC9B,cAAc,QAAQ,QACtB,eAAe,cAAc,UAAU;AAE3C,QAAM,WAAW,eAAe,IAAI,eAAe,QAAQ;AAE3D,QAAM,qBAAqB,iBAAiB,QAAQ,cAAc,UAAU,SAAS,YAAY;IAC/F,GAAG;IACH;GACD;AAED,QAAM,YAAY,gBAAgB,QAAQ;IACxC;IACA,UAAU,eAAe,IAAI,eAAe,QAAQ;IACpD,UAAU,cAAc,WACpB,4BAA4B,IAAI,cAAc,SAAS,EAAE,KAAK,OAC9D;IACJ;IACA,cAAc,QAAQ;IACtB;GACD;AAED,YAAU,SAAS,CAAC,cAAc,WAAW,SAAS,KAAK,cAAc,WAAW,SAAS,GAAG;AAIhG,SAAO;AACT;AAGA,SAAS,eAAe,YAAe;AACrC,QAAM,IAAI,MAAM,gCAAgC;AAClD;AAGA,SAAS,eAAe,IAAY,eAAoB,UAA2B;AACjF,QAAM,aAAgD,CAAA;AACtD,aAAW,CAAC,eAAe,SAAS,KAAK,OAAO,QAAQ,cAAc,UAAU,GAAG;AACjF,UAAM,EAAC,YAAY,MAAM,MAAK,IAAI;AAElC,eAAW,aAAa,IAAI,EAAC,MAAM,QAAQ,YAAY,MAAK;EAC9D;AAEA,SAAO,IAAI,wBAAS;IAClB;IACA;IACA,SAAS,cAAc,QAAQ;IAC/B;GACD;AACH;AAEA,SAAS,kBAAkB,cAAyC,eAAqB;AACvF,SAAO,aAAa,QAAQ,aAAa,MAAM,YAAY;AAC7D;;;AG3QA,IAAAC,eAAkB;;;ACJlB,IAAAC,eAAkB;AAClB,IAAAA,eAAyB;AAKzB,SAAS,iBACP,QACA,MACA,UAAkB;AAElB,UAAQ,MAAM;IACZ,KAAK;AACH,aAAO,OAAO,YAAY,QAAQ,EAAE,aAAY;IAElD,KAAK;AACH,aAAO,OAAO,YAAY,QAAQ,EAAE,aAAY;IAElD,KAAK;AACH,aAAO,OAAO,SAAS,QAAQ,EAAE,aAAY;IAE/C;AACE,uBAAI,KAAK,sBAAsB,MAAM,EAAC;AACtC,aAAO;EACX;AACF;AAGM,SAAU,YACd,MACA,EAAC,OAAO,eAAe,OAAM,GAC7B,QACA,MAAuB;AAEvB,QAAM,UAAU,MAAM,MAAM,SAAS,CAAC;AACtC,QAAM,gBAAgB,OAAO;AAE7B,QAAM,YAAY,MAAM,UAAU,OAAK,KAAK,aAAa;AACzD,QAAM,gBAAgB,KAAK,IAAI,GAAG,YAAY,CAAC;AAE/C,QAAM,eAAe,MAAM,aAAa;AACxC,QAAM,WAAW,MAAM,SAAS;AAEhC,UAAQ,eAAe;IACrB,KAAK;AACH,sBAAgB,QAAQ,MAAM,OAAO,aAAa,CAAC;AACnD;IAEF,KAAK;AACH,UAAI,WAAW,cAAc;AAC3B,cAAM,SAAS,gBAAgB,iBAAiB,WAAW;AAC3D,0BAAkB,QAAQ,MAAM,OAAO,aAAa,GAAG,OAAO,SAAS,GAAG,KAAK;MACjF;AACA;IAEF,KAAK;AACH,UAAI,WAAW,cAAc;AAC3B,cAAM,SAAS,gBAAgB,iBAAiB,WAAW;AAC3D,cAAM,QAAQ,WAAW;AAEzB,cAAM,KAAK,OAAO,IAAI,gBAAgB,CAAC;AACvC,cAAM,cAAc,OAAO,IAAI,gBAAgB,CAAC;AAChD,cAAM,aAAa,OAAO,IAAI,YAAY,CAAC;AAC3C,cAAM,KAAK,OAAO,IAAI,YAAY,CAAC;AAEnC,+BAAuB,QAAQ,MAAM,EAAC,IAAI,aAAa,YAAY,IAAI,OAAO,MAAK,CAAC;MACtF;AACA;IAEF;AACE,uBAAI,KAAK,iBAAiB,6BAA6B,EAAC;AACxD;EACJ;AACF;AAGA,SAAS,kBACP,QACA,MACA,OACA,MACA,OAAa;AAEb,MAAI,SAAS,YAAY;AAEvB,qBAAiB,QAAQ,MAAM,IAAI,wBAAU,EAAG,MAAM,EAAC,OAAO,QAAQ,MAAM,MAAK,CAAC,CAAC;EACrF,OAAO;AAEL,UAAM,SAAS,CAAA;AACf,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,aAAO,CAAC,IAAI,QAAQ,KAAK,CAAC,KAAK,IAAI,SAAS,MAAM,CAAC;IACrD;AACA,qBAAiB,QAAQ,MAAM,MAAM;EACvC;AACF;AAGA,SAAS,uBACP,QACA,MACA,EACE,IACA,aACA,YACA,IACA,OACA,OAAO,EAAC,GAQT;AAGD,QAAM,SAAS,CAAA;AACf,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAClC,UAAM,KAAK,YAAY,CAAC,IAAI;AAC5B,UAAM,KAAK,WAAW,CAAC,IAAI;AAC3B,WAAO,CAAC,KACL,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KACnD,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,MAC3C,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,KAChD,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,KAAK;EACxC;AACA,mBAAiB,QAAQ,MAAM,MAAM;AACvC;AAGA,SAAS,gBAAgB,QAAmB,MAAyB,OAAe;AAClF,mBAAiB,QAAQ,MAAM,KAAK;AACtC;;;AD7GA,IAAM,qBAAN,MAAwB;;EAEtB;;EAEA;;EAEA,YAAoB;;EAEpB,UAAmB;;EAEnB,QAAgB;;EAGhB,YAAY,OAA8B;AACxC,SAAK,YAAY,MAAM;AACvB,SAAK,sBAAsB,MAAM;AACjC,SAAK,UAAU,SAAS;AACxB,WAAO,OAAO,MAAM,KAAK;EAC3B;;EAGA,QAAQ,QAAc;AACpB,QAAI,CAAC,KAAK,SAAS;AACjB;IACF;AAEA,UAAM,UAAU,SAAS;AACzB,UAAM,QAAQ,UAAU,KAAK,aAAa,KAAK;AAE/C,SAAK,UAAU,SAAS,QAAQ,CAAC,EAAC,SAAS,cAAc,KAAI,MAAK;AAChE,YAAM,aAAa,KAAK,oBAAoB,IAAI,YAAY;AAC5D,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,qCAAqC,cAAc;MACrE;AAEA,kBAAY,MAAM,SAAS,YAAY,IAAI;IAC7C,CAAC;EACH;;AAYI,IAAO,eAAP,MAAmB;;EAEvB;;EAGA,YAAY,OAAwB;AAClC,SAAK,aAAa,MAAM,WAAW,IAAI,CAAC,WAAW,UAAS;AAC1D,YAAM,OAAO,UAAU,QAAQ,aAAa;AAC5C,aAAO,IAAI,mBAAmB;QAC5B,qBAAqB,MAAM;QAC3B,WAAW,EAAC,MAAM,UAAU,UAAU,SAAQ;OAC/C;IACH,CAAC;EACH;;EAGA,QAAQ,MAAY;AAClB,qBAAI,KAAK,sEAAsE,EAAC;AAChF,SAAK,QAAQ,IAAI;EACnB;;EAGA,QAAQ,MAAY;AAClB,SAAK,WAAW,QAAQ,eAAa,UAAU,QAAQ,IAAI,CAAC;EAC9D;;EAGA,gBAAa;AACX,WAAO,KAAK;EACd;;;;AElGF,IAAAC,eAAkB;;;ACIX,IAAM,+BAAuD;EAClE,QAAQ;EACR,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;;AAID,IAAM,oCAAyD;EACpE,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;;AAkBF,SAAU,qBAAqB,UAAsB;AA3C3D;AAiDE,QAAM,YAAY,kCAAkC,SAAS,aAAa;AAC1E,QAAM,aAAa,6BAA6B,SAAS,IAAI;AAC7D,QAAM,SAAS,aAAa,SAAS;AACrC,QAAM,EAAC,QAAQ,aAAa,EAAC,MAAI,cAAS,eAAT,mBAAqB,SAAQ,CAAA;AAE9D,QAAM,aAAa,IAAI,UAAU,QAAQ,cAAc,SAAS,cAAc,IAAI,MAAM;AAExF,SAAO,EAAC,YAAY,WAAU;AAChC;;;ADzCM,SAAU,oBAAoB,MAAuB;AACzD,QAAM,iBAAiB,KAAK,cAAc,CAAA;AAC1C,QAAM,kBAAkB,oBAAI,IAAG;AAC/B,QAAM,kBAAkB,oBAAI,IAAG;AAE/B,SAAO,eAAe,QAAQ,CAAC,WAAW,UAAS;AACjD,UAAM,OAAO,UAAU,QAAQ,aAAa;AAC5C,UAAM,eAAe,oBAAI,IAAG;AAC5B,UAAM,WAAmC,UAAU,SAAS,QAAQ,CAAC,EAAC,SAAS,OAAM,MAAK;AACxF,YAAM,OAAO,0BAA0B,OAAO,IAAI;AAClD,UAAI,CAAC,MAAM;AACT,eAAO,CAAA;MACT;AAEA,YAAM,aAAa,KAAK,MAAM,OAAO,QAAQ,CAAC;AAC9C,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,gCAAgC,OAAO,MAAM;MAC/D;AAEA,UAAI,gBAAgB,aAAa,IAAI,OAAO;AAC5C,UAAI,CAAC,eAAe;AAClB,cAAM,cAAc,UAAU,SAAS,OAAO;AAC9C,YAAI,CAAC,aAAa;AAChB,gBAAM,IAAI,MAAM,iCAAiC,SAAS;QAC5D;AACA,cAAM,EAAC,OAAO,gBAAgB,UAAU,OAAM,IAAI;AAClD,wBAAgB;UACd,OAAO,oBAAoB,KAAK,UAAU,KAAK,GAAG,eAAe;UACjE;UACA,QAAQ,oBAAoB,KAAK,UAAU,MAAM,GAAG,eAAe;;AAErE,qBAAa,IAAI,SAAS,aAAa;MACzC;AAEA,aAAO;QACL,SAAS;QACT,cAAc,WAAW;QACzB;;IAEJ,CAAC;AAED,WAAO,SAAS,SAAS,CAAC,EAAC,MAAM,SAAQ,CAAC,IAAI,CAAA;EAChD,CAAC;AACH;AAEA,SAAS,0BAA0B,MAAY;AAC7C,MAAI,SAAS,WAAW;AACtB,qBAAI,KAAK,sEAAsE,EAAC;AAChF,WAAO;EACT;AAEA,SAAO;AACT;AAGA,SAAS,oBACP,UACA,eAAuD;AAEvD,MAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B,WAAO,cAAc,IAAI,QAAQ;EACnC;AAEA,QAAM,EAAC,YAAY,OAAO,WAAU,IAAI,qBAAqB,QAAQ;AACrE,SAAO,eAAe,GAAG,mDAAmD;AAC5E,QAAM,SAAS,MAAM,KAAK,KAAK;AAE/B,gBAAc,IAAI,UAAU,MAAM;AAClC,SAAO;AACT;AAGA,SAAS,oBACP,UACA,eAAyD;AAEzD,MAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B,WAAO,cAAc,IAAI,QAAQ;EACnC;AAEA,QAAM,EAAC,YAAY,OAAO,WAAU,IAAI,qBAAqB,QAAQ;AACrE,SAAO,cAAc,GAAG,oDAAoD;AAE5E,QAAM,SAAS,CAAA;AAGf,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,YAAY;AACjD,WAAO,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC;EACxD;AAEA,gBAAc,IAAI,UAAU,MAAM;AAClC,SAAO;AACT;AAGA,SAAS,OAAO,WAAoB,SAAgB;AAClD,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,OAAO;EACzB;AACF;;;AE7FA,IAAM,4BAA4D;EAChE,cAAc;EACd,SAAS;;AAGX,IAAM,kCAAkF;EACtF,4BAA4B;IAC1B,cAAc;IACd,SAAS;;EAEX,yBAAyB;IACvB,cAAc;IACd,SAAS;;EAEX,uBAAuB;IACrB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,iCAAiC;IAC/B,cAAc;IACd,SAAS;;EAEX,oBAAoB;IAClB,cAAc;IACd,SAAS;;EAEX,uBAAuB;IACrB,cAAc;IACd,SAAS;;EAEX,kBAAkB;IAChB,cAAc;IACd,SACE;;EAEJ,kBAAkB;IAChB,cAAc;IACd,SACE;;EAEJ,wBAAwB;IACtB,cAAc;IACd,SAAS;;EAEX,mBAAmB;IACjB,cAAc;IACd,SAAS;;EAEX,4BAA4B;IAC1B,cAAc;IACd,SACE;;EAEJ,sBAAsB;IACpB,cAAc;IACd,SAAS;;EAEX,yBAAyB;IACvB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,2BAA2B;IACzB,cAAc;IACd,SACE;;EAEJ,0BAA0B;IACxB,cAAc;IACd,SACE;;EAEJ,qCAAqC;IACnC,cAAc;IACd,SACE;;EAEJ,wBAAwB;IACtB,cAAc;IACd,SAAS;;EAEX,yBAAyB;IACvB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,uBAAuB;IACrB,cAAc;IACd,SAAS;;EAEX,oCAAoC;IAClC,cAAc;IACd,SAAS;;EAEX,0BAA0B;IACxB,cAAc;IACd,SAAS;;EAEX,8BAA8B;IAC5B,cAAc;IACd,SAAS;;EAEX,SAAS;IACP,cAAc;IACd,SAAS;;EAEX,iBAAiB;IACf,cAAc;IACd,SAAS;;EAEX,wBAAwB;IACtB,cAAc;IACd,SAAS;;EAEX,mBAAmB;IACjB,cAAc;IACd,SAAS;;EAEX,UAAU;IACR,cAAc;IACd,SAAS;;;AAIP,SAAU,wBACd,MAAuB;AAEvB,QAAM,iBAAiB,MAAM,KAAK,0BAA0B,IAAI,CAAC,EAAE,KAAI;AACvE,QAAM,0BAA4D,eAAe,IAC/E,mBAAgB;AACd,UAAM,6BACJ,gCAAgC,aAAa,KAAK;AAEpD,WAAO;MACL;MACA;QACE;QACA,WAAW,2BAA2B,iBAAiB;QACvD,cAAc,2BAA2B;QACzC,SAAS,2BAA2B;;;EAG1C,CAAC;AAGH,SAAO,IAAI,IAAI,uBAAuB;AACxC;AAEA,SAAS,0BAA0B,MAAuB;AAxL1D;AAyLE,QAAM,4BAA4B;AAClC,QAAM,iBAAiB,oBAAI,IAAG;AAE9B,oBAAkB,gBAAgB,KAAK,cAAc;AACrD,oBAAkB,gBAAgB,KAAK,kBAAkB;AACzD,oBAAkB,gBAAgB,0BAA0B,iBAAiB;AAC7E,oBAAkB,gBAAgB,OAAO,KAAK,KAAK,cAAc,CAAA,CAAE,CAAC;AAEpE,QAAI,+BAA0B,WAA1B,mBAAkC,WAAU,KAAK,MAAM,KAAK,UAAQ,WAAW,IAAI,GAAG;AACxF,mBAAe,IAAI,qBAAqB;EAC1C;AAEA,MACE,KAAK,UAAU,KAAK,cAAW;AAtMnC,QAAAC;AAuMM,UAAM,eAAe;AACrB,WAAO,aAAa,WAASA,MAAA,aAAa,eAAb,gBAAAA,IAAyB;EACxD,CAAC,GACD;AACA,mBAAe,IAAI,qBAAqB;EAC1C;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,gBAA6B,oBAA8B,CAAA,GAAE;AACtF,aAAW,iBAAiB,mBAAmB;AAC7C,mBAAe,IAAI,aAAa;EAClC;AACF;;;AC7JM,SAAU,0BACd,QACA,MACA,SAA0B;AAE1B,QAAM,EAAC,QAAQ,WAAW,qBAAqB,qBAAqB,uBAAsB,IACxF,UAAU,QAAQ,MAAM,OAAO;AAEjC,QAAM,aAAa,oBAAoB,IAAI;AAC3C,QAAM,WAAW,IAAI,aAAa,EAAC,YAAY,oBAAmB,CAAC;AACnE,QAAM,SAAS,gBAAgB,IAAI;AACnC,QAAM,mBAAmB,wBAAwB,IAAI;AACrD,QAAM,cAAc,OAAO,IAAI,WAAS,oBAAoB,MAAM,UAAS,CAAE,CAAC;AAC9E,QAAM,cAAc,4BAA4B,WAAW;AAE3D,SAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;AAEJ;AAEA,SAAS,oBAAoB,QAAmC;AAC9D,MAAI,CAAC,QAAQ;AACX,WAAO;MACL,QAAQ;MACR,QAAQ,CAAC,GAAG,GAAG,CAAC;MAChB,MAAM,CAAC,GAAG,GAAG,CAAC;MACd,QAAQ;MACR,0BAA0B;;EAE9B;AAEA,QAAM,mBAAyE;IAC7E,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;;AAE3C,QAAM,OAAiC;IACrC,iBAAiB,CAAC,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC;IAC9C,iBAAiB,CAAC,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC;IAC9C,iBAAiB,CAAC,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC;;AAEhD,QAAM,SAAmC;IACvC,iBAAiB,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI;IACnC,iBAAiB,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI;IACnC,iBAAiB,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI;;AAErC,QAAM,gBAAgB,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI;AAC5D,QAAM,SAAS,KAAK,IAAI,MAAM,KAAK,MAAM,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAK;AAE1E,SAAO;IACL,QAAQ;IACR;IACA;IACA;IACA,0BAA0B,KAAK,IAC5B,KAAK,IAAI,eAAe,IAAK,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC,IAAK,MAC3D,SAAS,GAAG;;AAGlB;AAEA,SAAS,4BAA4B,aAAmC;AACtE,MAAI,iBAA8E;AAElF,aAAW,kBAAkB,aAAa;AACxC,QAAI,CAAC,eAAe,QAAQ;AAC1B;IACF;AAEA,QAAI,CAAC,gBAAgB;AACnB,uBAAiB;QACf,CAAC,GAAG,eAAe,OAAO,CAAC,CAAC;QAC5B,CAAC,GAAG,eAAe,OAAO,CAAC,CAAC;;AAE9B;IACF;AAEA,aAAS,OAAO,GAAG,OAAO,GAAG,QAAQ;AACnC,qBAAe,CAAC,EAAE,IAAI,IAAI,KAAK,IAAI,eAAe,CAAC,EAAE,IAAI,GAAG,eAAe,OAAO,CAAC,EAAE,IAAI,CAAC;AAC1F,qBAAe,CAAC,EAAE,IAAI,IAAI,KAAK,IAAI,eAAe,CAAC,EAAE,IAAI,GAAG,eAAe,OAAO,CAAC,EAAE,IAAI,CAAC;IAC5F;EACF;AAEA,SAAO,oBAAoB,cAAc;AAC3C;",
|
|
6
|
-
"names": ["GLEnum", "import_core", "import_engine", "import_shadertools", "import_core", "import_engine", "module", "import_core", "import_core", "import_core", "_a"]
|
|
3
|
+
"sources": ["../src/index.ts", "../src/pbr/pbr-environment.ts", "../src/parsers/parse-pbr-material.ts", "../src/webgl-to-webgpu/gltf-webgl-constants.ts", "../src/webgl-to-webgpu/convert-webgl-sampler.ts", "../src/pbr/texture-transform.ts", "../src/parsers/parse-gltf-lights.ts", "../src/parsers/parse-gltf.ts", "../src/webgl-to-webgpu/convert-webgl-topology.ts", "../src/gltf/create-gltf-model.ts", "../src/gltf/gltf-animator.ts", "../src/gltf/animations/interpolate.ts", "../src/parsers/parse-gltf-animations.ts", "../src/gltf/gltf-extension-support.ts", "../src/webgl-to-webgpu/convert-webgl-attribute.ts", "../src/gltf/create-scenegraph-from-gltf.ts"],
|
|
4
|
+
"sourcesContent": ["// luma.gl, MIT license\n\nexport {loadPBREnvironment, type PBREnvironment} from './pbr/pbr-environment';\nexport {type ParsedPBRMaterial} from './pbr/pbr-material';\nexport {parsePBRMaterial, type ParsePBRMaterialOptions} from './parsers/parse-pbr-material';\nexport {parseGLTFLights, type ParseGLTFLightsOptions} from './parsers/parse-gltf-lights';\n\n// glTF Scenegraph Instantiator\nexport {\n createScenegraphsFromGLTF,\n type GLTFScenegraphBounds,\n type GLTFScenegraphs\n} from './gltf/create-scenegraph-from-gltf';\nexport {\n getGLTFExtensionSupport,\n type GLTFExtensionSupport,\n type GLTFExtensionSupportLevel\n} from './gltf/gltf-extension-support';\nexport {GLTFAnimator} from './gltf/gltf-animator';\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, SamplerProps} from '@luma.gl/core';\nimport {\n DynamicTexture,\n type Texture2DData,\n type TextureCubeData,\n type TextureCubeFace\n} from '@luma.gl/engine';\nimport {loadImageTexture} from '@loaders.gl/textures';\n\n/** Environment textures for PBR module */\nexport type PBREnvironment = {\n /** Bi-directional Reflectance Distribution Function (BRDF) lookup table */\n brdfLutTexture: DynamicTexture;\n /** Diffuse irradiance cubemap. */\n diffuseEnvSampler: DynamicTexture;\n /** Specular reflection cubemap with mip chain. */\n specularEnvSampler: DynamicTexture;\n};\n\n/** Configuration used to load an image-based lighting environment. */\nexport type PBREnvironmentProps = {\n /** URL of the BRDF lookup texture. */\n brdfLutUrl: string;\n /** Callback that returns the URL for a diffuse or specular cubemap face and mip level. */\n getTexUrl: (name: string, dir: number, level: number) => string;\n /** Number of mip levels in the specular environment map. */\n specularMipLevels?: number;\n};\n\n/** Loads textures for PBR environment */\nexport function loadPBREnvironment(device: Device, props: PBREnvironmentProps): PBREnvironment {\n const specularMipLevels = props.specularMipLevels ?? 1;\n\n const brdfLutTexture = new DynamicTexture(device, {\n id: 'brdfLUT',\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps,\n // Texture accepts a promise that returns an image as data (Async Textures)\n data: loadImageTexture(resolveTextureUrl(props.brdfLutUrl))\n });\n\n const diffuseEnvSampler = makeCube(device, {\n id: 'DiffuseEnvSampler',\n getTextureForFace: face =>\n loadImageTexture(\n resolveTextureUrl(props.getTexUrl('diffuse', FACES.indexOf(face), 0))\n ) as Promise<Texture2DData>,\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear',\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n const specularEnvSampler = makeCube(device, {\n id: 'SpecularEnvSampler',\n getTextureForFace: (face: TextureCubeFace) => {\n const imageArray: Array<Promise<unknown>> = [];\n const direction = FACES.indexOf(face);\n for (let lod = 0; lod < specularMipLevels; lod++) {\n imageArray.push(\n loadImageTexture(resolveTextureUrl(props.getTexUrl('specular', direction, lod)))\n );\n }\n return Promise.all(imageArray) as Promise<Texture2DData>;\n },\n sampler: {\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n minFilter: 'linear', // [GL.TEXTURE_MIN_FILTER]: GL.LINEAR_MIPMAP_LINEAR,\n magFilter: 'linear'\n } as const satisfies SamplerProps\n });\n\n return {\n brdfLutTexture,\n diffuseEnvSampler,\n specularEnvSampler\n };\n}\n\n// TODO put somewhere common\nconst FACES: TextureCubeFace[] = ['+X', '-X', '+Y', '-Y', '+Z', '-Z'];\n\nfunction resolveTextureUrl(url: string): string {\n const baseUrl = globalThis.document?.baseURI ?? globalThis.location?.href;\n return baseUrl ? new URL(url, baseUrl).toString() : url;\n}\n\n/** Construction props for an asynchronously loaded cubemap. */\nfunction makeCube(\n device: Device,\n {\n id,\n getTextureForFace,\n sampler\n }: {\n /** Debug id assigned to the created texture. */\n id: string;\n /** Returns the image or mip-array promise for one cubemap face. */\n getTextureForFace: (face: TextureCubeFace) => Promise<Texture2DData>;\n /** Sampler configuration shared across faces. */\n sampler: SamplerProps;\n }\n): DynamicTexture {\n const data: Promise<TextureCubeData> = Promise.all(\n FACES.map(face => getTextureForFace(face))\n ).then(faceDataArray => {\n const cubeData = {} as TextureCubeData;\n FACES.forEach((face, index) => {\n cubeData[face] = faceDataArray[index];\n });\n return cubeData;\n });\n return new DynamicTexture(device, {\n id,\n dimension: 'cube',\n mipmaps: false,\n sampler,\n data\n });\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {Device, SamplerProps, TextureFormat, TypedArray} from '@luma.gl/core';\nimport {Texture, log, textureFormatDecoder} from '@luma.gl/core';\nimport type {GLTFPostprocessed, GLTFSampler} from '@loaders.gl/gltf';\n\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {type PBRMaterialBindings} from '@luma.gl/shadertools';\nimport {GLEnum} from '../webgl-to-webgpu/gltf-webgl-constants';\nimport {convertSampler} from '../webgl-to-webgpu/convert-webgl-sampler';\nimport {\n getTextureTransformSlotDefinition,\n getTextureTransformSlotDefinitions,\n getTextureTransformMatrix,\n resolveTextureCoordinateSet,\n resolveTextureTransform,\n type PBRTextureTransformSlot\n} from '../pbr/texture-transform';\n\n// TODO - synchronize the GLTF... types with loaders.gl\n// TODO - remove the glParameters, use only parameters\n\n/* eslint-disable camelcase */\n\ntype GLTFTexture = {\n id: string;\n index?: number;\n texture: {source: {image: any}; sampler: {parameters: any}};\n uniformName?: string;\n // is this on all textures?\n scale?: number;\n // is this on all textures?\n strength?: number;\n};\n\ntype GLTFPBRMetallicRoughness = {\n baseColorTexture?: GLTFTexture;\n baseColorFactor?: [number, number, number, number];\n metallicRoughnessTexture?: GLTFTexture;\n metallicFactor?: number;\n roughnessFactor?: number;\n};\n\ntype GLTFPBRMaterial = {\n extensions?: GLTFMaterialExtensions;\n unlit?: boolean;\n pbrMetallicRoughness?: GLTFPBRMetallicRoughness;\n normalTexture?: GLTFTexture;\n occlusionTexture?: GLTFTexture;\n emissiveTexture?: GLTFTexture;\n emissiveFactor?: [number, number, number];\n alphaMode?: 'OPAQUE' | 'MASK' | 'BLEND';\n doubleSided?: boolean;\n alphaCutoff?: number;\n};\n\ntype GLTFMaterialSpecularExtension = {\n specularFactor?: number;\n specularTexture?: GLTFTexture;\n specularColorFactor?: [number, number, number];\n specularColorTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialIorExtension = {\n ior?: number;\n};\n\ntype GLTFMaterialTransmissionExtension = {\n transmissionFactor?: number;\n transmissionTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialVolumeExtension = {\n thicknessFactor?: number;\n thicknessTexture?: GLTFTexture;\n attenuationDistance?: number;\n attenuationColor?: [number, number, number];\n};\n\ntype GLTFMaterialClearcoatExtension = {\n clearcoatFactor?: number;\n clearcoatTexture?: GLTFTexture;\n clearcoatRoughnessFactor?: number;\n clearcoatRoughnessTexture?: GLTFTexture;\n clearcoatNormalTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialSheenExtension = {\n sheenColorFactor?: [number, number, number];\n sheenColorTexture?: GLTFTexture;\n sheenRoughnessFactor?: number;\n sheenRoughnessTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialIridescenceExtension = {\n iridescenceFactor?: number;\n iridescenceTexture?: GLTFTexture;\n iridescenceIor?: number;\n iridescenceThicknessMinimum?: number;\n iridescenceThicknessMaximum?: number;\n iridescenceThicknessTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialAnisotropyExtension = {\n anisotropyStrength?: number;\n anisotropyRotation?: number;\n anisotropyTexture?: GLTFTexture;\n};\n\ntype GLTFMaterialEmissiveStrengthExtension = {\n emissiveStrength?: number;\n};\n\ntype GLTFMaterialExtensions = {\n KHR_materials_unlit?: Record<string, never>;\n KHR_materials_specular?: GLTFMaterialSpecularExtension;\n KHR_materials_ior?: GLTFMaterialIorExtension;\n KHR_materials_transmission?: GLTFMaterialTransmissionExtension;\n KHR_materials_volume?: GLTFMaterialVolumeExtension;\n KHR_materials_clearcoat?: GLTFMaterialClearcoatExtension;\n KHR_materials_sheen?: GLTFMaterialSheenExtension;\n KHR_materials_iridescence?: GLTFMaterialIridescenceExtension;\n KHR_materials_anisotropy?: GLTFMaterialAnisotropyExtension;\n KHR_materials_emissive_strength?: GLTFMaterialEmissiveStrengthExtension;\n};\n\ntype TextureEnabledUniformName =\n | 'baseColorMapEnabled'\n | 'normalMapEnabled'\n | 'emissiveMapEnabled'\n | 'metallicRoughnessMapEnabled'\n | 'occlusionMapEnabled'\n | 'specularColorMapEnabled'\n | 'specularIntensityMapEnabled'\n | 'transmissionMapEnabled'\n | 'clearcoatMapEnabled'\n | 'clearcoatRoughnessMapEnabled'\n | 'sheenColorMapEnabled'\n | 'sheenRoughnessMapEnabled'\n | 'iridescenceMapEnabled'\n | 'anisotropyMapEnabled';\n\ntype TextureFeatureOptions = {\n define?: string;\n enabledUniformName?: TextureEnabledUniformName;\n};\n\ntype TextureParseOptions = {\n featureOptions?: TextureFeatureOptions;\n gltf?: GLTFPostprocessed;\n attributes?: Record<string, any>;\n textureTransformSlot?: PBRTextureTransformSlot;\n};\n\nexport type ParsePBRMaterialOptions = {\n /** Debug PBR shader */\n pbrDebug?: boolean;\n /** Enable lights */\n lights?: any;\n /** Use tangents */\n useTangents?: boolean;\n /** provide an image based (texture cube) lighting environment */\n imageBasedLightingEnvironment?: PBREnvironment;\n /** parent post-processed glTF, used to resolve extension texture infos */\n gltf?: GLTFPostprocessed;\n /** run primitive-attribute diagnostics such as missing TEXCOORD_0 / NORMAL */\n validateAttributes?: boolean;\n};\n\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n */\nexport function parsePBRMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n attributes: Record<string, any>,\n options: ParsePBRMaterialOptions\n): ParsedPBRMaterial {\n const parsedMaterial: ParsedPBRMaterial = {\n defines: {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n },\n bindings: {},\n uniforms: {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n },\n parameters: {},\n glParameters: {},\n generatedTextures: []\n };\n\n // TODO - always available\n parsedMaterial.defines['USE_TEX_LOD'] = true;\n\n const {imageBasedLightingEnvironment} = options;\n if (imageBasedLightingEnvironment) {\n parsedMaterial.bindings.pbr_diffuseEnvSampler =\n imageBasedLightingEnvironment.diffuseEnvSampler.texture;\n parsedMaterial.bindings.pbr_specularEnvSampler =\n imageBasedLightingEnvironment.specularEnvSampler.texture;\n parsedMaterial.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.brdfLutTexture.texture;\n parsedMaterial.uniforms.IBLenabled = true;\n parsedMaterial.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (options?.pbrDebug) {\n parsedMaterial.defines['PBR_DEBUG'] = true;\n // Override final color for reference app visualization of various parameters in the lighting equation.\n parsedMaterial.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n parsedMaterial.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n if (attributes['NORMAL']) parsedMaterial.defines['HAS_NORMALS'] = true;\n if (attributes['TANGENT'] && options?.useTangents) parsedMaterial.defines['HAS_TANGENTS'] = true;\n if (attributes['TEXCOORD_0']) parsedMaterial.defines['HAS_UV'] = true;\n if (attributes['TEXCOORD_1']) parsedMaterial.defines['HAS_UV_1'] = true;\n if (attributes['JOINTS_0'] && attributes['WEIGHTS_0']) parsedMaterial.defines['HAS_SKIN'] = true;\n if (attributes['COLOR_0']) parsedMaterial.defines['HAS_COLORS'] = true;\n\n if (options?.imageBasedLightingEnvironment) parsedMaterial.defines['USE_IBL'] = true;\n if (options?.lights) parsedMaterial.defines['USE_LIGHTS'] = true;\n\n if (material) {\n if (options.validateAttributes !== false) {\n warnOnMissingExpectedAttributes(material, attributes);\n }\n parseMaterial(device, material, parsedMaterial, attributes, options.gltf);\n }\n\n return parsedMaterial;\n}\n\nfunction warnOnMissingExpectedAttributes(\n material: GLTFPBRMaterial,\n attributes: Record<string, any>\n): void {\n const uvDependentTextureSlots = getUvDependentTextureSlots(material, 0);\n if (uvDependentTextureSlots.length > 0 && !attributes['TEXCOORD_0']) {\n log.warn(\n `glTF material uses ${uvDependentTextureSlots.join(', ')} but primitive is missing TEXCOORD_0; textured shading will sample the default UV coordinates`\n )();\n }\n const uv1DependentTextureSlots = getUvDependentTextureSlots(material, 1);\n if (uv1DependentTextureSlots.length > 0 && !attributes['TEXCOORD_1']) {\n log.warn(\n `glTF material uses ${uv1DependentTextureSlots.join(', ')} with TEXCOORD_1 but primitive is missing TEXCOORD_1; those textures will be skipped`\n )();\n }\n\n const isUnlitMaterial = Boolean(material.unlit || material.extensions?.KHR_materials_unlit);\n if (isUnlitMaterial || attributes['NORMAL']) {\n return;\n }\n\n const missingNormalReason = material.normalTexture\n ? 'lit PBR shading with normalTexture'\n : 'lit PBR shading';\n log.warn(\n `glTF primitive is missing NORMAL while using ${missingNormalReason}; shading will fall back to geometric normals`\n )();\n}\n\nfunction getUvDependentTextureSlots(\n material: GLTFPBRMaterial,\n textureCoordinateSet: number\n): string[] {\n const uvDependentTextureSlots: string[] = [];\n\n for (const slotDefinition of getTextureTransformSlotDefinitions()) {\n const textureInfo = getNestedTextureInfo(material, slotDefinition.pathSegments);\n if (!textureInfo) {\n continue;\n }\n\n if (resolveTextureCoordinateSet(textureInfo) === textureCoordinateSet) {\n uvDependentTextureSlots.push(slotDefinition.displayName);\n }\n }\n\n return uvDependentTextureSlots;\n}\n\nfunction getNestedTextureInfo(\n material: GLTFPBRMaterial,\n pathSegments: string[]\n): Record<string, any> | null {\n let value: any = material;\n for (const pathSegment of pathSegments) {\n value = value?.[pathSegment];\n if (!value) {\n return null;\n }\n }\n\n return value;\n}\n\n/** Parse GLTF material record */\nfunction parseMaterial(\n device: Device,\n material: GLTFPBRMaterial,\n parsedMaterial: ParsedPBRMaterial,\n attributes: Record<string, any>,\n gltf?: GLTFPostprocessed\n): void {\n parsedMaterial.uniforms.unlit = Boolean(\n material.unlit || material.extensions?.KHR_materials_unlit\n );\n\n if (material.pbrMetallicRoughness) {\n parsePbrMetallicRoughness(\n device,\n material.pbrMetallicRoughness,\n parsedMaterial,\n attributes,\n gltf\n );\n }\n if (material.normalTexture) {\n addTexture(device, material.normalTexture, 'pbr_normalSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_NORMALMAP',\n enabledUniformName: 'normalMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'normal'\n });\n\n const {scale = 1} = material.normalTexture;\n parsedMaterial.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n addTexture(device, material.occlusionTexture, 'pbr_occlusionSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_OCCLUSIONMAP',\n enabledUniformName: 'occlusionMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'occlusion'\n });\n\n const {strength = 1} = material.occlusionTexture;\n parsedMaterial.uniforms.occlusionStrength = strength;\n }\n parsedMaterial.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n if (material.emissiveTexture) {\n addTexture(device, material.emissiveTexture, 'pbr_emissiveSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_EMISSIVEMAP',\n enabledUniformName: 'emissiveMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'emissive'\n });\n }\n\n parseMaterialExtensions(device, material.extensions, parsedMaterial, gltf, attributes);\n\n switch (material.alphaMode || 'OPAQUE') {\n case 'OPAQUE':\n break;\n case 'MASK': {\n const {alphaCutoff = 0.5} = material;\n parsedMaterial.defines['ALPHA_CUTOFF'] = true;\n parsedMaterial.uniforms.alphaCutoffEnabled = true;\n parsedMaterial.uniforms.alphaCutoff = alphaCutoff;\n break;\n }\n case 'BLEND':\n log.warn('glTF BLEND alphaMode might not work well because it requires mesh sorting')();\n applyAlphaBlendParameters(parsedMaterial);\n\n break;\n }\n}\n\nfunction applyAlphaBlendParameters(parsedMaterial: ParsedPBRMaterial): void {\n parsedMaterial.parameters.blend = true;\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'src-alpha';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GLEnum.SRC_ALPHA,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ];\n}\n\nfunction applyTransmissionBlendApproximation(parsedMaterial: ParsedPBRMaterial): void {\n parsedMaterial.parameters.blend = true;\n parsedMaterial.parameters.depthWriteEnabled = false;\n parsedMaterial.parameters.blendColorOperation = 'add';\n parsedMaterial.parameters.blendColorSrcFactor = 'one';\n parsedMaterial.parameters.blendColorDstFactor = 'one-minus-src-alpha';\n parsedMaterial.parameters.blendAlphaOperation = 'add';\n parsedMaterial.parameters.blendAlphaSrcFactor = 'one';\n parsedMaterial.parameters.blendAlphaDstFactor = 'one-minus-src-alpha';\n\n parsedMaterial.glParameters['blend'] = true;\n parsedMaterial.glParameters['depthMask'] = false;\n parsedMaterial.glParameters['blendEquation'] = GLEnum.FUNC_ADD;\n parsedMaterial.glParameters['blendFunc'] = [\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ];\n}\n\n/** Parse GLTF material sub record */\nfunction parsePbrMetallicRoughness(\n device: Device,\n pbrMetallicRoughness: GLTFPBRMetallicRoughness,\n parsedMaterial: ParsedPBRMaterial,\n attributes: Record<string, any>,\n gltf?: GLTFPostprocessed\n): void {\n if (pbrMetallicRoughness.baseColorTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_BASECOLORMAP',\n enabledUniformName: 'baseColorMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'baseColor'\n }\n );\n }\n parsedMaterial.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n addTexture(\n device,\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_METALROUGHNESSMAP',\n enabledUniformName: 'metallicRoughnessMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'metallicRoughness'\n }\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n parsedMaterial.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n}\n\nfunction parseMaterialExtensions(\n device: Device,\n extensions: GLTFMaterialExtensions | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extensions) {\n return;\n }\n\n if (hasMaterialExtensionShading(extensions)) {\n parsedMaterial.defines['USE_MATERIAL_EXTENSIONS'] = true;\n }\n\n parseSpecularExtension(\n device,\n extensions.KHR_materials_specular,\n parsedMaterial,\n gltf,\n attributes\n );\n parseIorExtension(extensions.KHR_materials_ior, parsedMaterial);\n parseTransmissionExtension(\n device,\n extensions.KHR_materials_transmission,\n parsedMaterial,\n gltf,\n attributes\n );\n parseVolumeExtension(device, extensions.KHR_materials_volume, parsedMaterial, gltf, attributes);\n parseClearcoatExtension(\n device,\n extensions.KHR_materials_clearcoat,\n parsedMaterial,\n gltf,\n attributes\n );\n parseSheenExtension(device, extensions.KHR_materials_sheen, parsedMaterial, gltf, attributes);\n parseIridescenceExtension(\n device,\n extensions.KHR_materials_iridescence,\n parsedMaterial,\n gltf,\n attributes\n );\n parseAnisotropyExtension(\n device,\n extensions.KHR_materials_anisotropy,\n parsedMaterial,\n gltf,\n attributes\n );\n parseEmissiveStrengthExtension(extensions.KHR_materials_emissive_strength, parsedMaterial);\n}\n\nfunction hasMaterialExtensionShading(extensions: GLTFMaterialExtensions): boolean {\n return Boolean(\n extensions.KHR_materials_specular ||\n extensions.KHR_materials_ior ||\n extensions.KHR_materials_transmission ||\n extensions.KHR_materials_volume ||\n extensions.KHR_materials_clearcoat ||\n extensions.KHR_materials_sheen ||\n extensions.KHR_materials_iridescence ||\n extensions.KHR_materials_anisotropy\n );\n}\n\nfunction parseSpecularExtension(\n device: Device,\n extension: GLTFMaterialSpecularExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.specularColorFactor) {\n parsedMaterial.uniforms.specularColorFactor = extension.specularColorFactor;\n }\n if (extension.specularFactor !== undefined) {\n parsedMaterial.uniforms.specularIntensityFactor = extension.specularFactor;\n }\n if (extension.specularColorTexture) {\n addTexture(device, extension.specularColorTexture, 'pbr_specularColorSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SPECULARCOLORMAP',\n enabledUniformName: 'specularColorMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'specularColor'\n });\n }\n if (extension.specularTexture) {\n addTexture(device, extension.specularTexture, 'pbr_specularIntensitySampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SPECULARINTENSITYMAP',\n enabledUniformName: 'specularIntensityMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'specularIntensity'\n });\n }\n}\n\nfunction parseIorExtension(\n extension: GLTFMaterialIorExtension | undefined,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (extension?.ior !== undefined) {\n parsedMaterial.uniforms.ior = extension.ior;\n }\n}\n\nfunction parseTransmissionExtension(\n device: Device,\n extension: GLTFMaterialTransmissionExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.transmissionFactor !== undefined) {\n parsedMaterial.uniforms.transmissionFactor = extension.transmissionFactor;\n }\n if (extension.transmissionTexture) {\n addTexture(device, extension.transmissionTexture, 'pbr_transmissionSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_TRANSMISSIONMAP',\n enabledUniformName: 'transmissionMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'transmission'\n });\n }\n\n if ((extension.transmissionFactor ?? 0) > 0 || extension.transmissionTexture) {\n log.warn(\n 'KHR_materials_transmission uses a premultiplied-alpha blending approximation and may require mesh sorting'\n )();\n applyTransmissionBlendApproximation(parsedMaterial);\n }\n}\n\nfunction parseVolumeExtension(\n device: Device,\n extension: GLTFMaterialVolumeExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.thicknessFactor !== undefined) {\n parsedMaterial.uniforms.thicknessFactor = extension.thicknessFactor;\n }\n if (extension.thicknessTexture) {\n addTexture(device, extension.thicknessTexture, 'pbr_thicknessSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_THICKNESSMAP'\n },\n gltf,\n attributes,\n textureTransformSlot: 'thickness'\n });\n }\n if (extension.attenuationDistance !== undefined) {\n parsedMaterial.uniforms.attenuationDistance = extension.attenuationDistance;\n }\n if (extension.attenuationColor) {\n parsedMaterial.uniforms.attenuationColor = extension.attenuationColor;\n }\n}\n\nfunction parseClearcoatExtension(\n device: Device,\n extension: GLTFMaterialClearcoatExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.clearcoatFactor !== undefined) {\n parsedMaterial.uniforms.clearcoatFactor = extension.clearcoatFactor;\n }\n if (extension.clearcoatRoughnessFactor !== undefined) {\n parsedMaterial.uniforms.clearcoatRoughnessFactor = extension.clearcoatRoughnessFactor;\n }\n if (extension.clearcoatTexture) {\n addTexture(device, extension.clearcoatTexture, 'pbr_clearcoatSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_CLEARCOATMAP',\n enabledUniformName: 'clearcoatMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'clearcoat'\n });\n }\n if (extension.clearcoatRoughnessTexture) {\n addTexture(\n device,\n extension.clearcoatRoughnessTexture,\n 'pbr_clearcoatRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_CLEARCOATROUGHNESSMAP',\n enabledUniformName: 'clearcoatRoughnessMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'clearcoatRoughness'\n }\n );\n }\n if (extension.clearcoatNormalTexture) {\n addTexture(\n device,\n extension.clearcoatNormalTexture,\n 'pbr_clearcoatNormalSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_CLEARCOATNORMALMAP'\n },\n gltf,\n attributes,\n textureTransformSlot: 'clearcoatNormal'\n }\n );\n }\n}\n\nfunction parseSheenExtension(\n device: Device,\n extension: GLTFMaterialSheenExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.sheenColorFactor) {\n parsedMaterial.uniforms.sheenColorFactor = extension.sheenColorFactor;\n }\n if (extension.sheenRoughnessFactor !== undefined) {\n parsedMaterial.uniforms.sheenRoughnessFactor = extension.sheenRoughnessFactor;\n }\n if (extension.sheenColorTexture) {\n addTexture(device, extension.sheenColorTexture, 'pbr_sheenColorSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_SHEENCOLORMAP',\n enabledUniformName: 'sheenColorMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'sheenColor'\n });\n }\n if (extension.sheenRoughnessTexture) {\n addTexture(\n device,\n extension.sheenRoughnessTexture,\n 'pbr_sheenRoughnessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_SHEENROUGHNESSMAP',\n enabledUniformName: 'sheenRoughnessMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'sheenRoughness'\n }\n );\n }\n}\n\nfunction parseIridescenceExtension(\n device: Device,\n extension: GLTFMaterialIridescenceExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.iridescenceFactor !== undefined) {\n parsedMaterial.uniforms.iridescenceFactor = extension.iridescenceFactor;\n }\n if (extension.iridescenceIor !== undefined) {\n parsedMaterial.uniforms.iridescenceIor = extension.iridescenceIor;\n }\n if (\n extension.iridescenceThicknessMinimum !== undefined ||\n extension.iridescenceThicknessMaximum !== undefined\n ) {\n parsedMaterial.uniforms.iridescenceThicknessRange = [\n extension.iridescenceThicknessMinimum ?? 100,\n extension.iridescenceThicknessMaximum ?? 400\n ];\n }\n if (extension.iridescenceTexture) {\n addTexture(device, extension.iridescenceTexture, 'pbr_iridescenceSampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_IRIDESCENCEMAP',\n enabledUniformName: 'iridescenceMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'iridescence'\n });\n }\n if (extension.iridescenceThicknessTexture) {\n addTexture(\n device,\n extension.iridescenceThicknessTexture,\n 'pbr_iridescenceThicknessSampler',\n parsedMaterial,\n {\n featureOptions: {\n define: 'HAS_IRIDESCENCETHICKNESSMAP'\n },\n gltf,\n attributes,\n textureTransformSlot: 'iridescenceThickness'\n }\n );\n }\n}\n\nfunction parseAnisotropyExtension(\n device: Device,\n extension: GLTFMaterialAnisotropyExtension | undefined,\n parsedMaterial: ParsedPBRMaterial,\n gltf?: GLTFPostprocessed,\n attributes: Record<string, any> = {}\n): void {\n if (!extension) {\n return;\n }\n\n if (extension.anisotropyStrength !== undefined) {\n parsedMaterial.uniforms.anisotropyStrength = extension.anisotropyStrength;\n }\n if (extension.anisotropyRotation !== undefined) {\n parsedMaterial.uniforms.anisotropyRotation = extension.anisotropyRotation;\n }\n if (extension.anisotropyTexture) {\n addTexture(device, extension.anisotropyTexture, 'pbr_anisotropySampler', parsedMaterial, {\n featureOptions: {\n define: 'HAS_ANISOTROPYMAP',\n enabledUniformName: 'anisotropyMapEnabled'\n },\n gltf,\n attributes,\n textureTransformSlot: 'anisotropy'\n });\n }\n}\n\nfunction parseEmissiveStrengthExtension(\n extension: GLTFMaterialEmissiveStrengthExtension | undefined,\n parsedMaterial: ParsedPBRMaterial\n): void {\n if (extension?.emissiveStrength !== undefined) {\n parsedMaterial.uniforms.emissiveStrength = extension.emissiveStrength;\n }\n}\n\n/** Create a texture from a glTF texture/sampler/image combo and add it to bindings */\nfunction addTexture(\n device: Device,\n gltfTexture: GLTFTexture,\n uniformName: keyof PBRMaterialBindings,\n parsedMaterial: ParsedPBRMaterial,\n textureParseOptions: TextureParseOptions = {}\n): void {\n const {featureOptions = {}, gltf, attributes = {}, textureTransformSlot} = textureParseOptions;\n const {define, enabledUniformName} = featureOptions;\n const textureCoordinateSet = resolveTextureCoordinateSet(gltfTexture as Record<string, any>);\n if (textureCoordinateSet > 1) {\n log.warn(\n `Skipping ${String(uniformName)} because ${textureCoordinateSet} is not supported; only TEXCOORD_0 and TEXCOORD_1 are currently available`\n )();\n return;\n }\n if (textureCoordinateSet === 1 && !attributes['TEXCOORD_1']) {\n log.warn(\n `Skipping ${String(uniformName)} because it requires TEXCOORD_1 but the primitive does not provide TEXCOORD_1`\n )();\n return;\n }\n\n const resolvedTextureInfo = resolveTextureInfo(gltfTexture, gltf);\n const image = resolvedTextureInfo.texture?.source?.image;\n if (!image) {\n log.warn(`Skipping unresolved glTF texture for ${String(uniformName)}`)();\n return;\n }\n\n const gltfSampler = {\n wrapS: 10497, // default REPEAT S (U) wrapping mode.\n wrapT: 10497, // default REPEAT T (V) wrapping mode.\n minFilter: 9729, // default LINEAR filtering\n magFilter: 9729, // default LINEAR filtering\n ...resolvedTextureInfo?.texture?.sampler\n } as GLTFSampler;\n\n const baseOptions = {\n id: resolvedTextureInfo.uniformName || resolvedTextureInfo.id,\n sampler: convertSampler(gltfSampler)\n };\n\n let texture: Texture;\n\n if (image.compressed) {\n texture = createCompressedTexture(device, image, baseOptions);\n } else {\n const {width, height} = device.getExternalImageSize(image);\n texture = device.createTexture({\n ...baseOptions,\n width,\n height,\n data: image\n });\n }\n\n parsedMaterial.bindings[uniformName] = texture;\n if (define) parsedMaterial.defines[define] = true;\n if (enabledUniformName) {\n parsedMaterial.uniforms[enabledUniformName] = true;\n }\n if (textureTransformSlot) {\n const textureTransformSlotDefinition = getTextureTransformSlotDefinition(textureTransformSlot);\n (parsedMaterial.uniforms as Record<string, any>)[textureTransformSlotDefinition.uvSetUniform] =\n textureCoordinateSet;\n (parsedMaterial.uniforms as Record<string, any>)[\n textureTransformSlotDefinition.uvTransformUniform\n ] = getTextureTransformMatrix(resolveTextureTransform(gltfTexture as Record<string, any>));\n }\n parsedMaterial.generatedTextures.push(texture);\n}\n\nfunction resolveTextureInfo(gltfTexture: GLTFTexture, gltf?: GLTFPostprocessed): GLTFTexture {\n if (gltfTexture.texture || gltfTexture.index === undefined || !gltf?.textures) {\n return gltfTexture;\n }\n\n const resolvedTextureEntry = gltf.textures[gltfTexture.index] as\n | Partial<GLTFTexture>\n | GLTFTexture['texture']\n | undefined;\n if (!resolvedTextureEntry) {\n return gltfTexture;\n }\n\n if ('texture' in resolvedTextureEntry && resolvedTextureEntry.texture) {\n return {\n ...resolvedTextureEntry,\n ...gltfTexture,\n texture: resolvedTextureEntry.texture\n } as GLTFTexture;\n }\n\n if (!('source' in resolvedTextureEntry)) {\n return gltfTexture;\n }\n\n return {\n ...gltfTexture,\n texture: resolvedTextureEntry\n };\n}\n\n/** One mip level as produced by loaders.gl compressed texture parsers */\nexport type CompressedMipLevel = {\n data: TypedArray;\n width: number;\n height: number;\n textureFormat?: TextureFormat;\n};\n\n/**\n * Compressed image from current loaders.gl releases.\n * - `mipmaps` is a boolean (true), NOT an array\n * - `data` is an Array of TextureLevel-like objects\n * - Per-level `textureFormat` is already a luma.gl TextureFormat\n * - Top-level `width`/`height` may be undefined\n */\nexport type CompressedImageDataArray = {\n compressed: true;\n mipmaps?: boolean;\n width?: number;\n height?: number;\n data: CompressedMipLevel[];\n};\n\n/**\n * Hypothetical future format where `mipmaps` is an actual array.\n * Kept for forward compatibility.\n */\nexport type CompressedImageMipmapArray = {\n compressed: true;\n width?: number;\n height?: number;\n mipmaps: CompressedMipLevel[];\n};\n\n/** Union of all known loaders.gl compressed image shapes */\nexport type CompressedImage = CompressedImageDataArray | CompressedImageMipmapArray;\n\nfunction createCompressedTextureFallback(\n device: Device,\n baseOptions: {id: string; sampler: SamplerProps}\n): Texture {\n return device.createTexture({\n ...baseOptions,\n format: 'rgba8unorm',\n width: 1,\n height: 1,\n mipLevels: 1\n });\n}\n\nfunction resolveCompressedTextureFormat(level: CompressedMipLevel): TextureFormat | undefined {\n return level.textureFormat;\n}\n\n/**\n * Maximum mip levels that can be filled for a compressed texture.\n * texStorage2D allocates level i at (baseW >> i) \u00D7 (baseH >> i).\n * Compressed formats can't upload data for levels smaller than one block,\n * so we stop before either dimension drops below the block size.\n */\nfunction getMaxCompressedMipLevels(\n baseWidth: number,\n baseHeight: number,\n format: TextureFormat\n): number {\n const {blockWidth = 1, blockHeight = 1} = textureFormatDecoder.getInfo(format);\n let count = 1;\n for (let i = 1; ; i++) {\n const w = Math.max(1, baseWidth >> i);\n const h = Math.max(1, baseHeight >> i);\n if (w < blockWidth || h < blockHeight) break;\n count++;\n }\n return count;\n}\n\n/**\n * Create a texture from compressed image data produced by loaders.gl.\n * Handles current loaders.gl compressed image layouts:\n *\n * current: {compressed, mipmaps: true, data: [{data, width, height, textureFormat}, ...]}\n * forward: {compressed, mipmaps: [{data, width, height, textureFormat}, ...]}\n */\nexport function createCompressedTexture(\n device: Device,\n image: CompressedImage,\n baseOptions: {id: string; sampler: SamplerProps}\n): Texture {\n // Normalize mip levels from all known loaders.gl formats\n let levels: CompressedMipLevel[];\n\n if (Array.isArray((image as any).data) && (image as any).data[0]?.data) {\n // loaders.gl current format: image.data is Array of mip-level objects\n levels = (image as CompressedImageDataArray).data;\n } else if ('mipmaps' in image && Array.isArray((image as CompressedImageMipmapArray).mipmaps)) {\n // Hypothetical future format: image.mipmaps is an Array\n levels = (image as CompressedImageMipmapArray).mipmaps;\n } else {\n levels = [];\n }\n\n if (levels.length === 0 || !levels[0]?.data) {\n log.warn(\n 'createCompressedTexture: compressed image has no valid mip levels, creating fallback'\n )();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n const baseLevel = levels[0];\n const baseWidth = baseLevel.width ?? (image as any).width ?? 0;\n const baseHeight = baseLevel.height ?? (image as any).height ?? 0;\n\n if (baseWidth <= 0 || baseHeight <= 0) {\n log.warn('createCompressedTexture: base level has invalid dimensions, creating fallback')();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n const format = resolveCompressedTextureFormat(baseLevel);\n\n if (!format) {\n log.warn('createCompressedTexture: compressed image has no textureFormat, creating fallback')();\n return createCompressedTextureFallback(device, baseOptions);\n }\n\n // Validate mip levels: truncate chain at first invalid level.\n // Levels must be contiguous, so we stop at the first level that has\n // a format mismatch, missing data, non-positive dimensions, or\n // dimensions that don't match what texStorage2D will allocate.\n //\n // For block-compressed formats (ASTC, BC, ETC2), texStorage2D allocates\n // mip levels down to 1\u00D71 texels, but compressed data can't be smaller\n // than one block (e.g. 4\u00D74 for ASTC-4x4). Cap the chain so we never\n // try to upload data whose block-aligned size exceeds the allocated level.\n const maxMipLevels = getMaxCompressedMipLevels(baseWidth, baseHeight, format);\n const levelLimit = Math.min(levels.length, maxMipLevels);\n\n let validLevelCount = 1;\n for (let i = 1; i < levelLimit; i++) {\n const level = levels[i];\n if (!level.data || level.width <= 0 || level.height <= 0) {\n log.warn(`createCompressedTexture: mip level ${i} has invalid data/dimensions, truncating`)();\n break;\n }\n const levelFormat = resolveCompressedTextureFormat(level);\n if (levelFormat && levelFormat !== format) {\n log.warn(\n `createCompressedTexture: mip level ${i} format '${levelFormat}' differs from base '${format}', truncating`\n )();\n break;\n }\n const expectedW = Math.max(1, baseWidth >> i);\n const expectedH = Math.max(1, baseHeight >> i);\n if (level.width !== expectedW || level.height !== expectedH) {\n log.warn(\n `createCompressedTexture: mip level ${i} dimensions ${level.width}x${level.height} ` +\n `don't match expected ${expectedW}x${expectedH}, truncating`\n )();\n break;\n }\n validLevelCount++;\n }\n\n const texture = device.createTexture({\n ...baseOptions,\n format,\n usage: Texture.TEXTURE | Texture.COPY_DST,\n width: baseWidth,\n height: baseHeight,\n mipLevels: validLevelCount,\n data: baseLevel.data\n });\n\n // Upload additional validated mip levels\n for (let i = 1; i < validLevelCount; i++) {\n texture.writeData(levels[i].data, {\n width: levels[i].width,\n height: levels[i].height,\n mipLevel: i\n });\n }\n\n return texture;\n}\n\n/*\n/**\n * Parses a GLTF material definition into uniforms and parameters for the PBR shader module\n *\nexport class PBRMaterialParser {\n readonly device: Device;\n\n readonly defines: Record<string, boolean>;\n readonly bindings: Record<string, Binding>;\n readonly uniforms: Record<string, any>;\n readonly parameters: Record<string, any>;\n\n /** Hold on to generated textures, we destroy them in the destroy method *\n readonly generatedTextures: Texture[];\n\n constructor(device: Device, props: PBRMaterialParserProps) {\n const {attributes, material, pbrDebug, imageBasedLightingEnvironment, lights, useTangents} =\n props;\n this.device = device;\n\n this.defines = {\n // TODO: Use EXT_sRGB if available (Standard in WebGL 2.0)\n MANUAL_SRGB: true,\n SRGB_FAST_APPROXIMATION: true\n };\n\n if (this.device.features.has('glsl-texture-lod')) {\n this.defines.USE_TEX_LOD = true;\n }\n\n this.uniforms = {\n // TODO: find better values?\n camera: [0, 0, 0], // Model should override\n\n metallicRoughnessValues: [1, 1] // Default is 1 and 1\n };\n\n this.bindings = {};\n\n this.parameters = {};\n this.generatedTextures = [];\n\n if (imageBasedLightingEnvironment) {\n this.bindings.pbr_diffuseEnvSampler = imageBasedLightingEnvironment.getDiffuseEnvSampler();\n this.bindings.pbr_specularEnvSampler = imageBasedLightingEnvironment.getSpecularEnvSampler();\n this.bindings.pbr_brdfLUT = imageBasedLightingEnvironment.getBrdfTexture();\n this.uniforms.scaleIBLAmbient = [1, 1];\n }\n\n if (pbrDebug) {\n // Override final color for reference app visualization\n // of various parameters in the lighting equation.\n this.uniforms.scaleDiffBaseMR = [0, 0, 0, 0];\n this.uniforms.scaleFGDSpec = [0, 0, 0, 0];\n }\n\n this.defineIfPresent(attributes.NORMAL, 'HAS_NORMALS');\n this.defineIfPresent(attributes.TANGENT && useTangents, 'HAS_TANGENTS');\n this.defineIfPresent(attributes.TEXCOORD_0, 'HAS_UV');\n this.defineIfPresent(attributes.COLOR_0, 'HAS_COLORS');\n\n this.defineIfPresent(imageBasedLightingEnvironment, 'USE_IBL');\n this.defineIfPresent(lights, 'USE_LIGHTS');\n this.defineIfPresent(pbrDebug, 'PBR_DEBUG');\n\n if (material) {\n this.parseMaterial(material);\n }\n }\n\n /**\n * Destroy all generated resources to release memory.\n *\n destroy(): void {\n this.generatedTextures.forEach(texture => texture.destroy());\n }\n\n /** Add a define if the the value is non-nullish *\n defineIfPresent(value: unknown, name: string): void {\n if (value) {\n this.defines[name] = 1;\n }\n }\n\n /** Parse GLTF material record *\n parseMaterial(material) {\n this.uniforms.unlit = Boolean(material.unlit);\n\n if (material.pbrMetallicRoughness) {\n this.parsePbrMetallicRoughness(material.pbrMetallicRoughness);\n }\n if (material.normalTexture) {\n this.addTexture(material.normalTexture, 'pbr_normalSampler', 'HAS_NORMALMAP');\n\n const {scale = 1} = material.normalTexture;\n this.uniforms.normalScale = scale;\n }\n if (material.occlusionTexture) {\n this.addTexture(material.occlusionTexture, 'pbr_occlusionSampler', 'HAS_OCCLUSIONMAP');\n\n const {strength = 1} = material.occlusionTexture;\n this.uniforms.occlusionStrength = strength;\n }\n if (material.emissiveTexture) {\n this.addTexture(material.emissiveTexture, 'pbr_emissiveSampler', 'HAS_EMISSIVEMAP');\n this.uniforms.emissiveFactor = material.emissiveFactor || [0, 0, 0];\n }\n if (material.alphaMode === 'MASK') {\n const {alphaCutoff = 0.5} = material;\n this.defines.ALPHA_CUTOFF = true;\n this.uniforms.u_AlphaCutoff = alphaCutoff;\n } else if (material.alphaMode === 'BLEND') {\n log.warn('BLEND alphaMode might not work well because it requires mesh sorting')();\n Object.assign(this.parameters, {\n blend: true,\n blendEquation: GLEnum.FUNC_ADD,\n blendFunc: [\n GLEnum.SRC_ALPHA,\n GLEnum.ONE_MINUS_SRC_ALPHA,\n GLEnum.ONE,\n GLEnum.ONE_MINUS_SRC_ALPHA\n ]\n });\n }\n }\n\n /** Parse GLTF material sub record *\n parsePbrMetallicRoughness(pbrMetallicRoughness) {\n if (pbrMetallicRoughness.baseColorTexture) {\n this.addTexture(\n pbrMetallicRoughness.baseColorTexture,\n 'pbr_baseColorSampler',\n 'HAS_BASECOLORMAP'\n );\n }\n this.uniforms.baseColorFactor = pbrMetallicRoughness.baseColorFactor || [1, 1, 1, 1];\n\n if (pbrMetallicRoughness.metallicRoughnessTexture) {\n this.addTexture(\n pbrMetallicRoughness.metallicRoughnessTexture,\n 'pbr_metallicRoughnessSampler',\n 'HAS_METALROUGHNESSMAP'\n );\n }\n const {metallicFactor = 1, roughnessFactor = 1} = pbrMetallicRoughness;\n this.uniforms.metallicRoughnessValues = [metallicFactor, roughnessFactor];\n }\n\n /** Create a texture from a glTF texture/sampler/image combo and add it to bindings *\n addTexture(gltfTexture, name, define = null) {\n const parameters = gltfTexture?.texture?.sampler?.parameters || {};\n\n const image = gltfTexture.texture.source.image;\n let textureOptions;\n let specialTextureParameters = {};\n if (image.compressed) {\n textureOptions = image;\n specialTextureParameters = {\n [GLEnum.TEXTURE_MIN_FILTER]:\n image.data.length > 1 ? GLEnum.LINEAR_MIPMAP_NEAREST : GLEnum.LINEAR\n };\n } else {\n // Texture2D accepts a promise that returns an image as data (Async Textures)\n textureOptions = {data: image};\n }\n\n const texture: Texture = this.device.createTexture({\n id: gltfTexture.name || gltfTexture.id,\n parameters: {\n ...parameters,\n ...specialTextureParameters\n },\n pixelStore: {\n [GLEnum.UNPACK_FLIP_Y_WEBGL]: false\n },\n ...textureOptions\n });\n this.bindings[name] = texture;\n this.defineIfPresent(define, define);\n this.generatedTextures.push(texture);\n }\n}\n*/\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// NOTE: `@luma.gl/gltf` intentionally keeps this as a local enum subset so it\n// does not need to depend on `@luma.gl/webgl` for a handful of stable WebGL values.\n// eslint-disable-next-line no-shadow\nexport enum GLEnum {\n POINTS = 0x0,\n LINES = 0x1,\n LINE_LOOP = 0x2,\n LINE_STRIP = 0x3,\n TRIANGLES = 0x4,\n TRIANGLE_STRIP = 0x5,\n TRIANGLE_FAN = 0x6,\n\n ONE = 1,\n SRC_ALPHA = 0x0302,\n ONE_MINUS_SRC_ALPHA = 0x0303,\n FUNC_ADD = 0x8006,\n\n LINEAR = 0x2601,\n NEAREST = 0x2600,\n NEAREST_MIPMAP_NEAREST = 0x2700,\n LINEAR_MIPMAP_NEAREST = 0x2701,\n NEAREST_MIPMAP_LINEAR = 0x2702,\n LINEAR_MIPMAP_LINEAR = 0x2703,\n TEXTURE_MIN_FILTER = 0x2801,\n TEXTURE_WRAP_S = 0x2802,\n TEXTURE_WRAP_T = 0x2803,\n REPEAT = 0x2901,\n CLAMP_TO_EDGE = 0x812f,\n MIRRORED_REPEAT = 0x8370,\n UNPACK_FLIP_Y_WEBGL = 0x9240\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\n\nimport type {SamplerProps} from '@luma.gl/core';\nimport {GLEnum} from './gltf-webgl-constants';\n\n/** Minimal glTF sampler representation used during conversion. */\ntype GLTFSampler = {\n /** Horizontal wrap mode. */\n wrapS?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;\n /** Vertical wrap mode. */\n wrapT?: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT;\n /** Magnification filter. */\n magFilter?: GLEnum.NEAREST | GLEnum.LINEAR;\n /** Minification and mip filter combination. */\n minFilter?:\n | GLEnum.NEAREST\n | GLEnum.LINEAR\n | GLEnum.NEAREST_MIPMAP_NEAREST\n | GLEnum.LINEAR_MIPMAP_NEAREST\n | GLEnum.NEAREST_MIPMAP_LINEAR\n | GLEnum.LINEAR_MIPMAP_LINEAR;\n};\n\n/** Converts a glTF sampler into luma.gl sampler props. */\nexport function convertSampler(gltfSampler: GLTFSampler): SamplerProps {\n return {\n addressModeU: convertSamplerWrapMode(gltfSampler.wrapS),\n addressModeV: convertSamplerWrapMode(gltfSampler.wrapT),\n magFilter: convertSamplerMagFilter(gltfSampler.magFilter),\n ...convertSamplerMinFilter(gltfSampler.minFilter)\n };\n}\n\n/** Converts a glTF wrap enum into a luma.gl address mode. */\nfunction convertSamplerWrapMode(\n mode: GLEnum.CLAMP_TO_EDGE | GLEnum.REPEAT | GLEnum.MIRRORED_REPEAT | undefined\n): 'clamp-to-edge' | 'repeat' | 'mirror-repeat' | undefined {\n switch (mode) {\n case GLEnum.CLAMP_TO_EDGE:\n return 'clamp-to-edge';\n case GLEnum.REPEAT:\n return 'repeat';\n case GLEnum.MIRRORED_REPEAT:\n return 'mirror-repeat';\n default:\n return undefined;\n }\n}\n\n/** Converts a glTF mag filter enum into a luma.gl mag filter. */\nfunction convertSamplerMagFilter(\n mode: GLEnum.NEAREST | GLEnum.LINEAR | undefined\n): 'nearest' | 'linear' | undefined {\n switch (mode) {\n case GLEnum.NEAREST:\n return 'nearest';\n case GLEnum.LINEAR:\n return 'linear';\n default:\n return undefined;\n }\n}\n\n/** Converts a glTF min filter enum into luma.gl minification and mipmap filters. */\nfunction convertSamplerMinFilter(\n mode:\n | GLEnum.NEAREST\n | GLEnum.LINEAR\n | GLEnum.NEAREST_MIPMAP_NEAREST\n | GLEnum.LINEAR_MIPMAP_NEAREST\n | GLEnum.NEAREST_MIPMAP_LINEAR\n | GLEnum.LINEAR_MIPMAP_LINEAR\n | undefined\n): {minFilter?: 'nearest' | 'linear'; mipmapFilter?: 'nearest' | 'linear'} {\n switch (mode) {\n case GLEnum.NEAREST:\n return {minFilter: 'nearest'};\n case GLEnum.LINEAR:\n return {minFilter: 'linear'};\n case GLEnum.NEAREST_MIPMAP_NEAREST:\n return {minFilter: 'nearest', mipmapFilter: 'nearest'};\n case GLEnum.LINEAR_MIPMAP_NEAREST:\n return {minFilter: 'linear', mipmapFilter: 'nearest'};\n case GLEnum.NEAREST_MIPMAP_LINEAR:\n return {minFilter: 'nearest', mipmapFilter: 'linear'};\n case GLEnum.LINEAR_MIPMAP_LINEAR:\n return {minFilter: 'linear', mipmapFilter: 'linear'};\n default:\n return {};\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Matrix3} from '@math.gl/core';\n\nexport type PBRTextureTransformSlot =\n | 'baseColor'\n | 'metallicRoughness'\n | 'normal'\n | 'occlusion'\n | 'emissive'\n | 'specularColor'\n | 'specularIntensity'\n | 'transmission'\n | 'thickness'\n | 'clearcoat'\n | 'clearcoatRoughness'\n | 'clearcoatNormal'\n | 'sheenColor'\n | 'sheenRoughness'\n | 'iridescence'\n | 'iridescenceThickness'\n | 'anisotropy';\n\nexport type PBRTextureTransformPath = 'offset' | 'rotation' | 'scale';\n\nexport type PBRTextureTransform = {\n offset: [number, number];\n rotation: number;\n scale: [number, number];\n};\n\nexport type PBRTextureTransformSlotDefinition = {\n slot: PBRTextureTransformSlot;\n binding: string;\n displayName: string;\n pathSegments: string[];\n uvSetUniform: string;\n uvTransformUniform: string;\n};\n\nconst IDENTITY_TEXTURE_TRANSFORM: PBRTextureTransform = {\n offset: [0, 0],\n rotation: 0,\n scale: [1, 1]\n};\n\nconst TEXTURE_TRANSFORM_SLOT_DEFINITIONS: PBRTextureTransformSlotDefinition[] = [\n createTextureTransformSlotDefinition('baseColor', 'pbr_baseColorSampler', 'baseColorTexture', [\n 'pbrMetallicRoughness',\n 'baseColorTexture'\n ]),\n createTextureTransformSlotDefinition(\n 'metallicRoughness',\n 'pbr_metallicRoughnessSampler',\n 'metallicRoughnessTexture',\n ['pbrMetallicRoughness', 'metallicRoughnessTexture']\n ),\n createTextureTransformSlotDefinition('normal', 'pbr_normalSampler', 'normalTexture', [\n 'normalTexture'\n ]),\n createTextureTransformSlotDefinition('occlusion', 'pbr_occlusionSampler', 'occlusionTexture', [\n 'occlusionTexture'\n ]),\n createTextureTransformSlotDefinition('emissive', 'pbr_emissiveSampler', 'emissiveTexture', [\n 'emissiveTexture'\n ]),\n createTextureTransformSlotDefinition(\n 'specularColor',\n 'pbr_specularColorSampler',\n 'KHR_materials_specular.specularColorTexture',\n ['extensions', 'KHR_materials_specular', 'specularColorTexture']\n ),\n createTextureTransformSlotDefinition(\n 'specularIntensity',\n 'pbr_specularIntensitySampler',\n 'KHR_materials_specular.specularTexture',\n ['extensions', 'KHR_materials_specular', 'specularTexture']\n ),\n createTextureTransformSlotDefinition(\n 'transmission',\n 'pbr_transmissionSampler',\n 'KHR_materials_transmission.transmissionTexture',\n ['extensions', 'KHR_materials_transmission', 'transmissionTexture']\n ),\n createTextureTransformSlotDefinition(\n 'thickness',\n 'pbr_thicknessSampler',\n 'KHR_materials_volume.thicknessTexture',\n ['extensions', 'KHR_materials_volume', 'thicknessTexture']\n ),\n createTextureTransformSlotDefinition(\n 'clearcoat',\n 'pbr_clearcoatSampler',\n 'KHR_materials_clearcoat.clearcoatTexture',\n ['extensions', 'KHR_materials_clearcoat', 'clearcoatTexture']\n ),\n createTextureTransformSlotDefinition(\n 'clearcoatRoughness',\n 'pbr_clearcoatRoughnessSampler',\n 'KHR_materials_clearcoat.clearcoatRoughnessTexture',\n ['extensions', 'KHR_materials_clearcoat', 'clearcoatRoughnessTexture']\n ),\n createTextureTransformSlotDefinition(\n 'clearcoatNormal',\n 'pbr_clearcoatNormalSampler',\n 'KHR_materials_clearcoat.clearcoatNormalTexture',\n ['extensions', 'KHR_materials_clearcoat', 'clearcoatNormalTexture']\n ),\n createTextureTransformSlotDefinition(\n 'sheenColor',\n 'pbr_sheenColorSampler',\n 'KHR_materials_sheen.sheenColorTexture',\n ['extensions', 'KHR_materials_sheen', 'sheenColorTexture']\n ),\n createTextureTransformSlotDefinition(\n 'sheenRoughness',\n 'pbr_sheenRoughnessSampler',\n 'KHR_materials_sheen.sheenRoughnessTexture',\n ['extensions', 'KHR_materials_sheen', 'sheenRoughnessTexture']\n ),\n createTextureTransformSlotDefinition(\n 'iridescence',\n 'pbr_iridescenceSampler',\n 'KHR_materials_iridescence.iridescenceTexture',\n ['extensions', 'KHR_materials_iridescence', 'iridescenceTexture']\n ),\n createTextureTransformSlotDefinition(\n 'iridescenceThickness',\n 'pbr_iridescenceThicknessSampler',\n 'KHR_materials_iridescence.iridescenceThicknessTexture',\n ['extensions', 'KHR_materials_iridescence', 'iridescenceThicknessTexture']\n ),\n createTextureTransformSlotDefinition(\n 'anisotropy',\n 'pbr_anisotropySampler',\n 'KHR_materials_anisotropy.anisotropyTexture',\n ['extensions', 'KHR_materials_anisotropy', 'anisotropyTexture']\n )\n];\n\nconst TEXTURE_TRANSFORM_SLOT_DEFINITION_MAP = new Map(\n TEXTURE_TRANSFORM_SLOT_DEFINITIONS.map(definition => [definition.slot, definition])\n);\n\nfunction createTextureTransformSlotDefinition(\n slot: PBRTextureTransformSlot,\n binding: string,\n displayName: string,\n pathSegments: string[]\n): PBRTextureTransformSlotDefinition {\n return {\n slot,\n binding,\n displayName,\n pathSegments,\n uvSetUniform: `${slot}UVSet`,\n uvTransformUniform: `${slot}UVTransform`\n };\n}\n\nexport function getTextureTransformSlotDefinitions(): PBRTextureTransformSlotDefinition[] {\n return TEXTURE_TRANSFORM_SLOT_DEFINITIONS;\n}\n\nexport function getTextureTransformSlotDefinition(\n slot: PBRTextureTransformSlot\n): PBRTextureTransformSlotDefinition {\n const definition = TEXTURE_TRANSFORM_SLOT_DEFINITION_MAP.get(slot);\n if (!definition) {\n throw new Error(`Unknown PBR texture transform slot ${slot}`);\n }\n return definition;\n}\n\nexport function getDefaultTextureTransform(): PBRTextureTransform {\n return {\n offset: [...IDENTITY_TEXTURE_TRANSFORM.offset] as [number, number],\n rotation: IDENTITY_TEXTURE_TRANSFORM.rotation,\n scale: [...IDENTITY_TEXTURE_TRANSFORM.scale] as [number, number]\n };\n}\n\nexport function resolveTextureTransform(\n textureInfo: Record<string, any> | undefined\n): PBRTextureTransform {\n const extensionTextureTransform = textureInfo?.['extensions']?.['KHR_texture_transform'];\n return {\n offset: extensionTextureTransform?.offset\n ? [extensionTextureTransform.offset[0], extensionTextureTransform.offset[1]]\n : [0, 0],\n rotation: extensionTextureTransform?.rotation ?? 0,\n scale: extensionTextureTransform?.scale\n ? [extensionTextureTransform.scale[0], extensionTextureTransform.scale[1]]\n : [1, 1]\n };\n}\n\nexport function resolveTextureCoordinateSet(textureInfo: Record<string, any> | undefined): number {\n const extensionTextureTransform = textureInfo?.['extensions']?.['KHR_texture_transform'];\n return extensionTextureTransform?.['texCoord'] ?? textureInfo?.['texCoord'] ?? 0;\n}\n\nexport function resolveTextureTransformSlot(\n pointerSegments: string[]\n): PBRTextureTransformSlotDefinition | null {\n return (\n TEXTURE_TRANSFORM_SLOT_DEFINITIONS.find(\n definition =>\n definition.pathSegments.length === pointerSegments.length &&\n definition.pathSegments.every((segment, index) => pointerSegments[index] === segment)\n ) || null\n );\n}\n\nexport function getTextureTransformMatrix(transform: PBRTextureTransform): number[] {\n const translationMatrix = new Matrix3().set(\n 1,\n 0,\n 0,\n 0,\n 1,\n 0,\n transform.offset[0],\n transform.offset[1],\n 1\n );\n const rotationMatrix = new Matrix3().set(\n Math.cos(transform.rotation),\n Math.sin(transform.rotation),\n 0,\n -Math.sin(transform.rotation),\n Math.cos(transform.rotation),\n 0,\n 0,\n 0,\n 1\n );\n const scaleMatrix = new Matrix3().set(\n transform.scale[0],\n 0,\n 0,\n 0,\n transform.scale[1],\n 0,\n 0,\n 0,\n 1\n );\n\n return Array.from(translationMatrix.multiplyRight(rotationMatrix).multiplyRight(scaleMatrix));\n}\n\nexport function getTextureTransformDeltaMatrix(\n baseTransform: PBRTextureTransform,\n currentTransform: PBRTextureTransform\n): number[] {\n const baseMatrix = new Matrix3(getTextureTransformMatrix(baseTransform));\n const currentMatrix = new Matrix3(getTextureTransformMatrix(currentTransform));\n const inverseBaseMatrix = new Matrix3(baseMatrix).invert();\n return Array.from(currentMatrix.multiplyRight(inverseBaseMatrix));\n}\n", "import {Matrix4} from '@math.gl/core';\nimport type {GLTFNodePostprocessed, GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {\n normalizeByteColor3,\n type DirectionalLight,\n type Light,\n type PointLight,\n type SpotLight\n} from '@luma.gl/shadertools';\n\nexport type ParseGLTFLightsOptions = {\n /** When true, parsed light colors are converted into luma.gl's legacy byte-style range. */\n useByteColors?: boolean;\n};\n\n/** Parse KHR_lights_punctual extension into luma.gl light definitions */\nexport function parseGLTFLights(\n gltf: GLTFPostprocessed,\n options: ParseGLTFLightsOptions = {}\n): Light[] {\n const lightDefs =\n // `postProcessGLTF()` moves KHR_lights_punctual into `gltf.lights`.\n (gltf as GLTFPostprocessed & {lights?: any[]}).lights ||\n gltf.extensions?.['KHR_lights_punctual']?.['lights'];\n if (!lightDefs || !Array.isArray(lightDefs) || lightDefs.length === 0) {\n return [];\n }\n\n const lights: Light[] = [];\n const parentNodeById = createParentNodeMap(gltf.nodes || []);\n const worldMatrixByNodeId = new Map<string, Matrix4>();\n\n for (const node of gltf.nodes || []) {\n const lightIndex =\n (node as GLTFNodePostprocessed & {light?: number}).light ??\n node.extensions?.KHR_lights_punctual?.light;\n if (typeof lightIndex !== 'number') {\n // eslint-disable-next-line no-continue\n continue;\n }\n const gltfLight = lightDefs[lightIndex];\n if (!gltfLight) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n const color = normalizeGLTFLightColor(\n (gltfLight.color || [1, 1, 1]) as [number, number, number],\n options.useByteColors ?? true\n );\n const intensity = gltfLight.intensity ?? 1;\n const range = gltfLight.range;\n const worldMatrix = getNodeWorldMatrix(node, parentNodeById, worldMatrixByNodeId);\n\n switch (gltfLight.type) {\n case 'directional':\n lights.push(parseDirectionalLight(worldMatrix, color, intensity));\n break;\n case 'point':\n lights.push(parsePointLight(worldMatrix, color, intensity, range));\n break;\n case 'spot':\n lights.push(parseSpotLight(worldMatrix, color, intensity, range, gltfLight.spot));\n break;\n default:\n // Unsupported light type\n break;\n }\n }\n\n return lights;\n}\n\n/**\n * Converts glTF colors from the 0-1 spec range to the configured luma light convention.\n */\nfunction normalizeGLTFLightColor(\n color: [number, number, number],\n useByteColors: boolean\n): [number, number, number] {\n if (useByteColors) {\n return color.map(component => component * 255) as [number, number, number];\n }\n return normalizeByteColor3(color, false) as [number, number, number];\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a point light.\n */\nfunction parsePointLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number,\n range?: number\n): PointLight {\n const position = getLightPosition(worldMatrix);\n\n let attenuation: Readonly<[number, number, number]> = [1, 0, 0];\n if (range !== undefined && range > 0) {\n attenuation = [1, 0, 1 / (range * range)] as [number, number, number];\n }\n\n return {\n type: 'point',\n position,\n color,\n intensity,\n attenuation\n };\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a directional light.\n */\nfunction parseDirectionalLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number\n): DirectionalLight {\n const direction = getLightDirection(worldMatrix);\n\n return {\n type: 'directional',\n direction,\n color,\n intensity\n };\n}\n\n/**\n * Converts a glTF punctual light attached to a node into a spot light.\n */\nfunction parseSpotLight(\n worldMatrix: Matrix4,\n color: [number, number, number],\n intensity: number,\n range?: number,\n spot: {innerConeAngle?: number; outerConeAngle?: number} = {}\n): SpotLight {\n const position = getLightPosition(worldMatrix);\n const direction = getLightDirection(worldMatrix);\n\n let attenuation: Readonly<[number, number, number]> = [1, 0, 0];\n if (range !== undefined && range > 0) {\n attenuation = [1, 0, 1 / (range * range)] as [number, number, number];\n }\n\n return {\n type: 'spot',\n position,\n direction,\n color,\n intensity,\n attenuation,\n innerConeAngle: spot.innerConeAngle ?? 0,\n outerConeAngle: spot.outerConeAngle ?? Math.PI / 4\n };\n}\n\n/**\n * Builds a parent lookup so punctual lights can be resolved in world space.\n */\nfunction createParentNodeMap(nodes: GLTFNodePostprocessed[]): Map<string, GLTFNodePostprocessed> {\n const parentNodeById = new Map<string, GLTFNodePostprocessed>();\n\n for (const node of nodes) {\n for (const childNode of node.children || []) {\n parentNodeById.set(childNode.id, node);\n }\n }\n\n return parentNodeById;\n}\n\n/**\n * Resolves a glTF node's world matrix from its local transform and parent chain.\n */\nfunction getNodeWorldMatrix(\n node: GLTFNodePostprocessed,\n parentNodeById: Map<string, GLTFNodePostprocessed>,\n worldMatrixByNodeId: Map<string, Matrix4>\n): Matrix4 {\n const cachedWorldMatrix = worldMatrixByNodeId.get(node.id);\n if (cachedWorldMatrix) {\n return cachedWorldMatrix;\n }\n\n const localMatrix = getNodeLocalMatrix(node);\n const parentNode = parentNodeById.get(node.id);\n const worldMatrix = parentNode\n ? new Matrix4(\n getNodeWorldMatrix(parentNode, parentNodeById, worldMatrixByNodeId)\n ).multiplyRight(localMatrix)\n : localMatrix;\n\n worldMatrixByNodeId.set(node.id, worldMatrix);\n return worldMatrix;\n}\n\n/**\n * Resolves a glTF node's local matrix from its matrix or TRS components.\n */\nfunction getNodeLocalMatrix(node: GLTFNodePostprocessed): Matrix4 {\n if (node.matrix) {\n return new Matrix4(node.matrix);\n }\n\n const matrix = new Matrix4();\n\n if (node.translation) {\n matrix.translate(node.translation);\n }\n\n if (node.rotation) {\n matrix.multiplyRight(new Matrix4().fromQuaternion(node.rotation));\n }\n\n if (node.scale) {\n matrix.scale(node.scale);\n }\n\n return matrix;\n}\n\n/**\n * Resolves the world-space position of a glTF light node.\n */\nfunction getLightPosition(worldMatrix: Matrix4): [number, number, number] {\n return worldMatrix.transformAsPoint([0, 0, 0]) as [number, number, number];\n}\n\n/**\n * Resolves the world-space forward direction of a glTF light node.\n */\nfunction getLightDirection(worldMatrix: Matrix4): [number, number, number] {\n return worldMatrix.transformDirection([0, 0, -1]) as [number, number, number];\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device, type PrimitiveTopology} from '@luma.gl/core';\nimport {\n Geometry,\n GeometryAttribute,\n GroupNode,\n Material,\n MaterialFactory,\n ModelNode,\n type ModelProps\n} from '@luma.gl/engine';\nimport {\n type GLTFMaterialPostprocessed,\n type GLTFMeshPostprocessed,\n type GLTFNodePostprocessed,\n type GLTFPostprocessed\n} from '@loaders.gl/gltf';\nimport {pbrMaterial} from '@luma.gl/shadertools';\n\nimport {type PBREnvironment} from '../pbr/pbr-environment';\nimport {convertGLDrawModeToTopology} from '../webgl-to-webgpu/convert-webgl-topology';\nimport {createGLTFMaterial, createGLTFModel} from '../gltf/create-gltf-model';\n\nimport {parsePBRMaterial} from './parse-pbr-material';\n\n/** Options that influence how a post-processed glTF is turned into a luma.gl scenegraph. */\nexport type ParseGLTFOptions = {\n /** Additional model props applied to each generated primitive model. */\n modelOptions?: Partial<ModelProps>;\n /** Enables shader-level PBR debug output. */\n pbrDebug?: boolean;\n /** Optional image-based lighting environment. */\n imageBasedLightingEnvironment?: PBREnvironment;\n /** Enables punctual light extraction. */\n lights?: boolean;\n /** Enables tangent usage when available. */\n useTangents?: boolean;\n /** When true, parsed semantic light colors are converted into luma.gl's legacy byte-style range. */\n useByteColors?: boolean;\n};\n\nconst defaultOptions: Required<ParseGLTFOptions> = {\n modelOptions: {},\n pbrDebug: false,\n imageBasedLightingEnvironment: undefined!,\n lights: true,\n useTangents: false,\n useByteColors: true\n};\n\n/**\n * GLTF instantiator for luma.gl\n * Walks the parsed and resolved glTF structure and builds a luma.gl scenegraph\n */\nexport function parseGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options: ParseGLTFOptions = {}\n): {\n /** Scene roots generated from `gltf.scenes`. */\n scenes: GroupNode[];\n /** Materials aligned with the source `gltf.materials` array. */\n materials: Material[];\n /** Map from glTF mesh ids to generated mesh group nodes. */\n gltfMeshIdToNodeMap: Map<string, GroupNode>;\n /** Map from glTF node indices to generated scenegraph nodes. */\n gltfNodeIndexToNodeMap: Map<number, GroupNode>;\n /** Map from glTF node ids to generated scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n} {\n const combinedOptions = {...defaultOptions, ...options};\n const materialFactory = new MaterialFactory(device, {modules: [pbrMaterial]});\n const materials = (gltf.materials || []).map((gltfMaterial, materialIndex) =>\n createGLTFMaterial(device, {\n id: getGLTFMaterialId(gltfMaterial, materialIndex),\n parsedPPBRMaterial: parsePBRMaterial(\n device,\n gltfMaterial as any,\n {},\n {\n ...combinedOptions,\n gltf,\n validateAttributes: false\n }\n ),\n materialFactory\n })\n );\n const gltfMaterialIdToMaterialMap = new Map<string, Material>();\n (gltf.materials || []).forEach((gltfMaterial, materialIndex) => {\n gltfMaterialIdToMaterialMap.set(gltfMaterial.id, materials[materialIndex]);\n });\n\n const gltfMeshIdToNodeMap = new Map<string, GroupNode>();\n gltf.meshes.forEach((gltfMesh, idx) => {\n const newMesh = createNodeForGLTFMesh(\n device,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n combinedOptions\n );\n gltfMeshIdToNodeMap.set(gltfMesh.id, newMesh);\n });\n\n const gltfNodeIndexToNodeMap = new Map<number, GroupNode>();\n const gltfNodeIdToNodeMap = new Map<string, GroupNode>();\n // Step 1/2: Generate a GroupNode for each gltf node. (1:1 mapping).\n gltf.nodes.forEach((gltfNode, idx) => {\n const newNode = createNodeForGLTFNode(device, gltfNode, combinedOptions);\n gltfNodeIndexToNodeMap.set(idx, newNode);\n gltfNodeIdToNodeMap.set(gltfNode.id, newNode);\n });\n\n // Step 2/2: Go though each gltf node and attach the children.\n // This guarantees that each gltf node will have exactly one luma GroupNode.\n gltf.nodes.forEach((gltfNode, idx) => {\n gltfNodeIndexToNodeMap.get(idx)!.add(\n (gltfNode.children ?? []).map(({id}) => {\n const child = gltfNodeIdToNodeMap.get(id);\n if (!child) throw new Error(`Cannot find child ${id} of node ${idx}`);\n return child;\n })\n );\n\n // Nodes can have children nodes and one optional child mesh at the same time.\n if (gltfNode.mesh) {\n const mesh = gltfMeshIdToNodeMap.get(gltfNode.mesh.id);\n if (!mesh) {\n throw new Error(`Cannot find mesh child ${gltfNode.mesh.id} of node ${idx}`);\n }\n gltfNodeIndexToNodeMap.get(idx)!.add(mesh);\n }\n });\n\n const scenes = gltf.scenes.map(gltfScene => {\n const children = (gltfScene.nodes || []).map(({id}) => {\n const child = gltfNodeIdToNodeMap.get(id);\n if (!child)\n throw new Error(`Cannot find child ${id} of scene ${gltfScene.name || gltfScene.id}`);\n return child;\n });\n return new GroupNode({\n id: gltfScene.name || gltfScene.id,\n children\n });\n });\n\n return {scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap};\n}\n\n/** Creates a `GroupNode` for one glTF node transform. */\nfunction createNodeForGLTFNode(\n device: Device,\n gltfNode: GLTFNodePostprocessed,\n options: Required<ParseGLTFOptions>\n): GroupNode {\n return new GroupNode({\n id: gltfNode.name || gltfNode.id,\n children: [],\n matrix: gltfNode.matrix,\n position: gltfNode.translation,\n rotation: gltfNode.rotation,\n scale: gltfNode.scale\n });\n}\n\n/** Creates a mesh group node containing one model node per glTF primitive. */\nfunction createNodeForGLTFMesh(\n device: Device,\n gltfMesh: GLTFMeshPostprocessed,\n gltf: GLTFPostprocessed,\n gltfMaterialIdToMaterialMap: Map<string, Material>,\n options: Required<ParseGLTFOptions>\n): GroupNode {\n const gltfPrimitives = gltfMesh.primitives || [];\n const primitives = gltfPrimitives.map((gltfPrimitive, i) =>\n createNodeForGLTFPrimitive({\n device,\n gltfPrimitive,\n primitiveIndex: i,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n options\n })\n );\n const mesh = new GroupNode({\n id: gltfMesh.name || gltfMesh.id,\n children: primitives\n });\n\n return mesh;\n}\n\n/** Input options for creating one renderable glTF primitive model node. */\ntype CreateNodeForGLTFPrimitiveOptions = {\n device: Device;\n gltfPrimitive: any;\n primitiveIndex: number;\n gltfMesh: GLTFMeshPostprocessed;\n gltf: GLTFPostprocessed;\n gltfMaterialIdToMaterialMap: Map<string, Material>;\n options: Required<ParseGLTFOptions>;\n};\n\n/** Creates a renderable model node for one glTF primitive. */\nfunction createNodeForGLTFPrimitive({\n device,\n gltfPrimitive,\n primitiveIndex,\n gltfMesh,\n gltf,\n gltfMaterialIdToMaterialMap,\n options\n}: CreateNodeForGLTFPrimitiveOptions): ModelNode {\n const id = gltfPrimitive.name || `${gltfMesh.name || gltfMesh.id}-primitive-${primitiveIndex}`;\n const topology = convertGLDrawModeToTopology(gltfPrimitive.mode ?? 4);\n const vertexCount = gltfPrimitive.indices\n ? gltfPrimitive.indices.count\n : getVertexCount(gltfPrimitive.attributes);\n\n const geometry = createGeometry(id, gltfPrimitive, topology);\n\n const parsedPPBRMaterial = parsePBRMaterial(device, gltfPrimitive.material, geometry.attributes, {\n ...options,\n gltf\n });\n\n const modelNode = createGLTFModel(device, {\n id,\n geometry,\n material: gltfPrimitive.material\n ? gltfMaterialIdToMaterialMap.get(gltfPrimitive.material.id) || null\n : null,\n parsedPPBRMaterial,\n modelOptions: options.modelOptions,\n vertexCount\n });\n\n modelNode.bounds = [gltfPrimitive.attributes.POSITION.min, gltfPrimitive.attributes.POSITION.max];\n // TODO this holds on to all the CPU side texture and attribute data\n // modelNode.material = gltfPrimitive.material;\n\n return modelNode;\n}\n\n/** Computes the vertex count for a primitive without indices. */\nfunction getVertexCount(attributes: any) {\n let vertexCount = Infinity;\n for (const attribute of Object.values(attributes)) {\n if (attribute) {\n const {value, size, components} = attribute as any;\n const attributeSize = size ?? components;\n if (value?.length !== undefined && attributeSize >= 1) {\n vertexCount = Math.min(vertexCount, value.length / attributeSize);\n }\n }\n }\n if (!Number.isFinite(vertexCount)) {\n throw new Error('Could not determine vertex count from attributes');\n }\n return vertexCount;\n}\n\n/** Converts glTF primitive attributes and indices into a luma.gl `Geometry`. */\nfunction createGeometry(id: string, gltfPrimitive: any, topology: PrimitiveTopology): Geometry {\n const attributes: Record<string, GeometryAttribute> = {};\n for (const [attributeName, attribute] of Object.entries(gltfPrimitive.attributes)) {\n const {components, size, value, normalized} = attribute as GeometryAttribute;\n\n attributes[attributeName] = {size: size ?? components, value, normalized};\n }\n\n return new Geometry({\n id,\n topology,\n indices: gltfPrimitive.indices?.value,\n attributes\n });\n}\n\nfunction getGLTFMaterialId(gltfMaterial: GLTFMaterialPostprocessed, materialIndex: number): string {\n return gltfMaterial.name || gltfMaterial.id || `material-${materialIndex}`;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {PrimitiveTopology} from '@luma.gl/core';\nimport {GLEnum} from './gltf-webgl-constants';\n\n/** Converts a WebGL draw mode into a luma.gl primitive topology string. */\nexport function convertGLDrawModeToTopology(\n drawMode:\n | GLEnum.POINTS\n | GLEnum.LINES\n | GLEnum.LINE_STRIP\n | GLEnum.LINE_LOOP\n | GLEnum.TRIANGLES\n | GLEnum.TRIANGLE_STRIP\n | GLEnum.TRIANGLE_FAN\n): PrimitiveTopology {\n // biome-ignore format: preserve layout\n switch (drawMode) {\n case GLEnum.POINTS: return 'point-list';\n case GLEnum.LINES: return 'line-list';\n case GLEnum.LINE_STRIP: return 'line-strip';\n case GLEnum.TRIANGLES: return 'triangle-list';\n case GLEnum.TRIANGLE_STRIP: return 'triangle-strip';\n default: throw new Error(String(drawMode));\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {\n Buffer,\n Device,\n Sampler,\n Texture,\n TextureView,\n type Binding,\n type RenderPipelineParameters,\n log\n} from '@luma.gl/core';\nimport {DynamicTexture} from '@luma.gl/engine';\nimport {pbrMaterial, skin} from '@luma.gl/shadertools';\nimport {\n Geometry,\n Material,\n MaterialFactory,\n Model,\n ModelNode,\n type ModelProps\n} from '@luma.gl/engine';\nimport {type ParsedPBRMaterial} from '../pbr/pbr-material';\n\nconst SHADER = /* WGSL */ `\nstruct VertexInputs {\n @location(0) positions: vec3f,\n#ifdef HAS_NORMALS\n @location(1) normals: vec3f,\n#endif\n#ifdef HAS_TANGENTS\n @location(2) TANGENT: vec4f,\n#endif\n#ifdef HAS_UV\n @location(3) texCoords: vec2f,\n#endif\n#ifdef HAS_UV_1\n @location(4) texCoords1: vec2f,\n#endif\n#ifdef HAS_SKIN\n @location(5) JOINTS_0: vec4u,\n @location(6) WEIGHTS_0: vec4f,\n#endif\n};\n\nstruct FragmentInputs {\n @builtin(position) position: vec4f,\n @location(0) pbrPosition: vec3f,\n @location(1) pbrUV0: vec2f,\n @location(2) pbrUV1: vec2f,\n @location(3) pbrNormal: vec3f,\n#ifdef HAS_TANGENTS\n @location(4) pbrTangent: vec4f,\n#endif\n};\n\n@vertex\nfn vertexMain(inputs: VertexInputs) -> FragmentInputs {\n var outputs: FragmentInputs;\n var position = vec4f(inputs.positions, 1.0);\n var normal = vec3f(0.0, 0.0, 1.0);\n var tangent = vec4f(1.0, 0.0, 0.0, 1.0);\n var uv0 = vec2f(0.0, 0.0);\n var uv1 = vec2f(0.0, 0.0);\n\n#ifdef HAS_NORMALS\n normal = inputs.normals;\n#endif\n#ifdef HAS_UV\n uv0 = inputs.texCoords;\n#endif\n#ifdef HAS_UV_1\n uv1 = inputs.texCoords1;\n#endif\n#ifdef HAS_TANGENTS\n tangent = inputs.TANGENT;\n#endif\n#ifdef HAS_SKIN\n let skinMatrix = getSkinMatrix(inputs.WEIGHTS_0, inputs.JOINTS_0);\n position = skinMatrix * position;\n normal = normalize((skinMatrix * vec4f(normal, 0.0)).xyz);\n#ifdef HAS_TANGENTS\n tangent = vec4f(normalize((skinMatrix * vec4f(tangent.xyz, 0.0)).xyz), tangent.w);\n#endif\n#endif\n\n let worldPosition = pbrProjection.modelMatrix * position;\n\n#ifdef HAS_NORMALS\n normal = normalize((pbrProjection.normalMatrix * vec4f(normal, 0.0)).xyz);\n#endif\n#ifdef HAS_TANGENTS\n let worldTangent = normalize((pbrProjection.modelMatrix * vec4f(tangent.xyz, 0.0)).xyz);\n outputs.pbrTangent = vec4f(worldTangent, tangent.w);\n#endif\n\n outputs.position = pbrProjection.modelViewProjectionMatrix * position;\n outputs.pbrPosition = worldPosition.xyz / worldPosition.w;\n outputs.pbrUV0 = uv0;\n outputs.pbrUV1 = uv1;\n outputs.pbrNormal = normal;\n return outputs;\n}\n\n@fragment\nfn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4f {\n fragmentInputs.pbr_vPosition = inputs.pbrPosition;\n fragmentInputs.pbr_vUV0 = inputs.pbrUV0;\n fragmentInputs.pbr_vUV1 = inputs.pbrUV1;\n fragmentInputs.pbr_vNormal = inputs.pbrNormal;\n#ifdef HAS_TANGENTS\n let tangent = normalize(inputs.pbrTangent.xyz);\n let bitangent = normalize(cross(inputs.pbrNormal, tangent)) * inputs.pbrTangent.w;\n fragmentInputs.pbr_vTBN = mat3x3f(tangent, bitangent, inputs.pbrNormal);\n#endif\n return pbr_filterColor(vec4f(1.0));\n}\n`;\n\n// TODO rename attributes to POSITION/NORMAL etc\n// See gpu-geometry.ts: getAttributeBuffersFromGeometry()\nconst vs = /* glsl */ `\\\n#version 300 es\n\n // in vec4 POSITION;\n in vec4 positions;\n\n #ifdef HAS_NORMALS\n // in vec4 NORMAL;\n in vec4 normals;\n #endif\n\n #ifdef HAS_TANGENTS\n in vec4 TANGENT;\n #endif\n\n #ifdef HAS_UV\n // in vec2 TEXCOORD_0;\n in vec2 texCoords;\n #endif\n\n #ifdef HAS_UV_1\n in vec2 texCoords1;\n #endif\n\n #ifdef HAS_SKIN\n in uvec4 JOINTS_0;\n in vec4 WEIGHTS_0;\n #endif\n\n void main(void) {\n vec4 _NORMAL = vec4(0.);\n vec4 _TANGENT = vec4(0.);\n vec2 _TEXCOORD_0 = vec2(0.);\n vec2 _TEXCOORD_1 = vec2(0.);\n\n #ifdef HAS_NORMALS\n _NORMAL = normals;\n #endif\n\n #ifdef HAS_TANGENTS\n _TANGENT = TANGENT;\n #endif\n\n #ifdef HAS_UV\n _TEXCOORD_0 = texCoords;\n #endif\n\n #ifdef HAS_UV_1\n _TEXCOORD_1 = texCoords1;\n #endif\n\n vec4 pos = positions;\n\n #ifdef HAS_SKIN\n mat4 skinMat = getSkinMatrix(WEIGHTS_0, JOINTS_0);\n pos = skinMat * pos;\n _NORMAL = skinMat * _NORMAL;\n _TANGENT = vec4((skinMat * vec4(_TANGENT.xyz, 0.)).xyz, _TANGENT.w);\n #endif\n\n pbr_setPositionNormalTangentUV(pos, _NORMAL, _TANGENT, _TEXCOORD_0, _TEXCOORD_1);\n gl_Position = pbrProjection.modelViewProjectionMatrix * pos;\n }\n`;\n\nconst fs = /* glsl */ `\\\n#version 300 es\n out vec4 fragmentColor;\n\n void main(void) {\n vec3 pos = pbr_vPosition;\n fragmentColor = pbr_filterColor(vec4(1.0));\n }\n`;\n\n/** Options used to instantiate a `ModelNode` for one glTF primitive. */\nexport type CreateGLTFModelOptions = {\n /** Optional id assigned to the generated model. */\n id?: string;\n /** Vertex count override for non-indexed primitives. */\n vertexCount?: number;\n /** Geometry converted from the glTF primitive. */\n geometry: Geometry;\n /** Parsed PBR material state for the primitive. */\n parsedPPBRMaterial: ParsedPBRMaterial;\n /** Pre-created material aligned with the source glTF material entry, when available. */\n material?: Material | null;\n /** Additional model props merged into the generated model. */\n modelOptions?: Partial<ModelProps>;\n};\n\nexport type CreateGLTFMaterialOptions = {\n id?: string;\n parsedPPBRMaterial: ParsedPBRMaterial;\n materialFactory?: MaterialFactory;\n};\n\nexport function createGLTFMaterial(device: Device, options: CreateGLTFMaterialOptions): Material {\n const materialFactory =\n options.materialFactory || new MaterialFactory(device, {modules: [pbrMaterial]});\n\n const pbrMaterialProps = {...options.parsedPPBRMaterial.uniforms};\n delete pbrMaterialProps.camera;\n const materialBindings = Object.fromEntries(\n Object.entries({\n ...pbrMaterialProps,\n ...options.parsedPPBRMaterial.bindings\n }).filter(\n ([name, value]) => materialFactory.ownsBinding(name) && isMaterialBindingResource(value)\n )\n ) as Record<string, Binding | DynamicTexture>;\n\n const material = materialFactory.createMaterial({\n id: options.id,\n bindings: materialBindings\n });\n material.setProps({pbrMaterial: pbrMaterialProps});\n\n return material;\n}\n\n/** Creates a luma.gl Model from GLTF data*/\nexport function createGLTFModel(device: Device, options: CreateGLTFModelOptions): ModelNode {\n const {id, geometry, parsedPPBRMaterial, vertexCount, modelOptions = {}} = options;\n\n log.info(4, 'createGLTFModel defines: ', parsedPPBRMaterial.defines)();\n\n // Calculate managedResources\n // TODO: Implement resource management logic that will\n // not deallocate resources/textures/buffers that are shared\n const managedResources: any[] = [];\n // managedResources.push(...parsedMaterial.generatedTextures);\n // managedResources.push(...Object.values(attributes).map((attribute) => attribute.buffer));\n\n const parameters: RenderPipelineParameters = {\n depthWriteEnabled: true,\n depthCompare: 'less',\n depthFormat: 'depth24plus',\n cullMode: 'back'\n };\n\n const modelProps: ModelProps = {\n id,\n source: SHADER,\n vs,\n fs,\n geometry,\n topology: geometry.topology,\n vertexCount,\n modules: [pbrMaterial, skin],\n ...modelOptions,\n\n defines: {...parsedPPBRMaterial.defines, ...modelOptions.defines},\n parameters: {...parameters, ...parsedPPBRMaterial.parameters, ...modelOptions.parameters}\n };\n\n const material =\n options.material ||\n createGLTFMaterial(device, {\n id: id ? `${id}-material` : undefined,\n parsedPPBRMaterial\n });\n modelProps.material = material;\n\n const model = new Model(device, modelProps);\n\n const sceneShaderInputValues = {\n ...parsedPPBRMaterial.uniforms,\n ...modelOptions.uniforms,\n ...parsedPPBRMaterial.bindings,\n ...modelOptions.bindings\n };\n const sceneShaderInputProps = getSceneShaderInputProps(\n model.shaderInputs.getModules(),\n material,\n sceneShaderInputValues\n );\n model.shaderInputs.setProps(sceneShaderInputProps);\n return new ModelNode({managedResources, model});\n}\n\nfunction isMaterialBindingResource(value: unknown): boolean {\n return (\n value instanceof Buffer ||\n value instanceof DynamicTexture ||\n value instanceof Sampler ||\n value instanceof Texture ||\n value instanceof TextureView\n );\n}\n\nfunction getSceneShaderInputProps(\n modules: Array<{\n name: string;\n uniformTypes?: Readonly<Record<string, unknown>>;\n bindingLayout?: ReadonlyArray<{name: string}>;\n }>,\n material: Material,\n shaderInputValues: Record<string, unknown>\n): Record<string, Record<string, unknown>> {\n const propertyToModuleNameMap = new Map<string, string>();\n for (const module of modules) {\n for (const uniformName of Object.keys(module.uniformTypes || {})) {\n propertyToModuleNameMap.set(uniformName, module.name);\n }\n for (const binding of module.bindingLayout || []) {\n propertyToModuleNameMap.set(binding.name, module.name);\n }\n }\n\n const sceneShaderInputProps: Record<string, Record<string, unknown>> = {};\n for (const [propertyName, value] of Object.entries(shaderInputValues)) {\n if (value === undefined) {\n continue;\n }\n\n const moduleName = propertyToModuleNameMap.get(propertyName);\n if (!moduleName || material.ownsModule(moduleName)) {\n continue;\n }\n\n sceneShaderInputProps[moduleName] ||= {};\n sceneShaderInputProps[moduleName][propertyName] = value;\n }\n\n return sceneShaderInputProps;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {GroupNode, Material} from '@luma.gl/engine';\nimport {\n GLTFAnimation,\n GLTFMaterialAnimationChannel,\n GLTFMaterialAnimationProperty,\n GLTFTextureTransformAnimationChannel\n} from './animations/animations';\nimport {evaluateSampler, interpolate} from './animations/interpolate';\nimport {\n getTextureTransformDeltaMatrix,\n getTextureTransformSlotDefinition,\n type PBRTextureTransform,\n type PBRTextureTransformSlot\n} from '../pbr/texture-transform';\n\n/** Construction props for a single glTF animation controller. */\ntype GLTFSingleAnimatorProps = {\n /** Animation data to evaluate. */\n animation: GLTFAnimation;\n /** Mapping from glTF node ids to scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n /** Materials aligned with the source glTF materials array. */\n materials?: Material[];\n /** Start time in seconds. */\n startTime?: number;\n /** Whether playback is active. */\n playing?: boolean;\n /** Playback speed multiplier. */\n speed?: number;\n};\n\n/** Evaluates one glTF animation against the generated scenegraph. */\nclass GLTFSingleAnimator {\n /** Animation definition being played. */\n animation: GLTFAnimation;\n /** Target scenegraph lookup table. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n /** Materials aligned with the source glTF materials array. */\n materials: Material[];\n /** Playback start time in seconds. */\n startTime: number = 0;\n /** Whether playback is currently enabled. */\n playing: boolean = true;\n /** Playback speed multiplier. */\n speed: number = 1;\n /** Mutable runtime texture-transform state for animated material slots. */\n materialTextureTransformState = new Map<\n Material,\n Partial<Record<PBRTextureTransformSlot, PBRTextureTransform>>\n >();\n\n /** Creates a single-animation controller. */\n constructor(props: GLTFSingleAnimatorProps) {\n this.animation = props.animation;\n this.gltfNodeIdToNodeMap = props.gltfNodeIdToNodeMap;\n this.materials = props.materials || [];\n this.animation.name ||= 'unnamed';\n Object.assign(this, props);\n\n if (\n this.animation.channels.some(channel => channel.type !== 'node') &&\n !this.materials.length\n ) {\n throw new Error(\n `Animation ${this.animation.name} targets materials, but GLTFAnimator was created without a materials array`\n );\n }\n }\n\n /** Advances the animation to the supplied wall-clock time in milliseconds. */\n setTime(timeMs: number) {\n if (!this.playing) {\n return;\n }\n\n const absTime = timeMs / 1000;\n const time = (absTime - this.startTime) * this.speed;\n\n this.animation.channels.forEach(channel => {\n if (channel.type === 'node') {\n const {sampler, targetNodeId, path} = channel;\n const targetNode = this.gltfNodeIdToNodeMap.get(targetNodeId);\n if (!targetNode) {\n throw new Error(`Cannot find animation target node ${targetNodeId}`);\n }\n\n interpolate(time, sampler, targetNode, path);\n return;\n }\n\n const material = this.materials[channel.targetMaterialIndex];\n if (!material) {\n throw new Error(\n `Cannot find animation target material ${channel.targetMaterialIndex} for ${channel.pointer}`\n );\n }\n\n const value = evaluateSampler(time, channel.sampler);\n if (value) {\n if (channel.type === 'material') {\n applyMaterialAnimationValue(material, channel, value);\n } else {\n applyTextureTransformAnimationValue(\n material,\n channel,\n value,\n this.materialTextureTransformState\n );\n }\n }\n });\n }\n}\n\n/** Construction props for {@link GLTFAnimator}. */\nexport type GLTFAnimatorProps = {\n /** Parsed animations from the source glTF. */\n animations: GLTFAnimation[];\n /** Mapping from glTF node ids to scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n /** Materials aligned with the source glTF materials array. */\n materials?: Material[];\n};\n\n/** Coordinates playback of every animation found in a glTF scene. */\nexport class GLTFAnimator {\n /** Individual animation controllers. */\n animations: GLTFSingleAnimator[];\n\n /** Creates an animator for the supplied glTF scenegraph. */\n constructor(props: GLTFAnimatorProps) {\n this.animations = props.animations.map((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n return new GLTFSingleAnimator({\n gltfNodeIdToNodeMap: props.gltfNodeIdToNodeMap,\n materials: props.materials,\n animation: {name, channels: animation.channels}\n });\n });\n }\n\n /** @deprecated Use .setTime(). Will be removed (deck.gl is using this) */\n animate(time: number): void {\n log.warn('GLTFAnimator#animate is deprecated. Use GLTFAnimator#setTime instead')();\n this.setTime(time);\n }\n\n /** Advances every animation to the supplied wall-clock time in milliseconds. */\n setTime(time: number): void {\n this.animations.forEach(animation => animation.setTime(time));\n }\n\n /** Returns the per-animation controllers managed by this animator. */\n getAnimations() {\n return this.animations;\n }\n}\n\nfunction applyMaterialAnimationValue(\n material: Material,\n channel: GLTFMaterialAnimationChannel,\n value: number[]\n): void {\n const pbrMaterial =\n channel.component !== undefined\n ? {\n [channel.property]: updateMaterialArrayComponent(\n getCurrentMaterialValue(material, channel.property),\n channel.component,\n value[0]\n )\n }\n : {\n [channel.property]: value.length === 1 ? value[0] : value\n };\n\n material.setProps({pbrMaterial});\n}\n\nfunction getCurrentMaterialValue(\n material: Material,\n property: GLTFMaterialAnimationProperty\n): number[] {\n const uniformValues = material.shaderInputs.getUniformValues() as Record<string, any>;\n const currentValue = uniformValues['pbrMaterial']?.[property];\n return Array.isArray(currentValue) ? [...currentValue] : [];\n}\n\nfunction updateMaterialArrayComponent(\n currentValue: number[],\n component: number,\n nextValue: number\n): number[] {\n const updatedValue = [...currentValue];\n updatedValue[component] = nextValue;\n return updatedValue;\n}\n\nfunction applyTextureTransformAnimationValue(\n material: Material,\n channel: GLTFTextureTransformAnimationChannel,\n value: number[],\n materialTextureTransformState: Map<\n Material,\n Partial<Record<PBRTextureTransformSlot, PBRTextureTransform>>\n >\n): void {\n const slotDefinition = getTextureTransformSlotDefinition(channel.textureSlot);\n const currentTransform = getCurrentTextureTransform(\n materialTextureTransformState,\n material,\n channel\n );\n\n switch (channel.path) {\n case 'offset':\n if (channel.component !== undefined) {\n currentTransform.offset[channel.component] = value[0];\n } else {\n currentTransform.offset = [value[0], value[1]];\n }\n break;\n\n case 'rotation':\n currentTransform.rotation = value[0];\n break;\n\n case 'scale':\n if (channel.component !== undefined) {\n currentTransform.scale[channel.component] = value[0];\n } else {\n currentTransform.scale = [value[0], value[1]];\n }\n break;\n }\n\n material.setProps({\n pbrMaterial: {\n [slotDefinition.uvTransformUniform]: getTextureTransformDeltaMatrix(\n channel.baseTransform,\n currentTransform\n )\n }\n });\n}\n\nfunction getCurrentTextureTransform(\n materialTextureTransformState: Map<\n Material,\n Partial<Record<PBRTextureTransformSlot, PBRTextureTransform>>\n >,\n material: Material,\n channel: GLTFTextureTransformAnimationChannel\n): PBRTextureTransform {\n const materialState = materialTextureTransformState.get(material) || {};\n let textureTransformState = materialState[channel.textureSlot];\n if (!textureTransformState) {\n textureTransformState = {\n offset: [...channel.baseTransform.offset] as [number, number],\n rotation: channel.baseTransform.rotation,\n scale: [...channel.baseTransform.scale] as [number, number]\n };\n materialState[channel.textureSlot] = textureTransformState;\n materialTextureTransformState.set(material, materialState);\n }\n\n return textureTransformState;\n}\n", "import {log} from '@luma.gl/core';\nimport {Quaternion} from '@math.gl/core';\nimport {GLTFAnimationPath, GLTFAnimationSampler} from './animations';\nimport {GroupNode} from '@luma.gl/engine';\n\n/** Applies an evaluated animation value to a scenegraph node. */\nfunction updateTargetPath(\n target: GroupNode,\n path: GLTFAnimationPath,\n newValue: number[]\n): GroupNode | null {\n switch (path) {\n case 'translation':\n return target.setPosition(newValue).updateMatrix();\n\n case 'rotation':\n return target.setRotation(newValue).updateMatrix();\n\n case 'scale':\n return target.setScale(newValue).updateMatrix();\n\n default:\n log.warn(`Bad animation path ${path}`)();\n return null;\n }\n}\n\n/** Evaluates a glTF animation sampler at the supplied time and applies the result to a node. */\nexport function interpolate(\n time: number,\n {input, interpolation, output}: GLTFAnimationSampler,\n target: GroupNode,\n path: GLTFAnimationPath\n) {\n const value = evaluateSampler(time, {input, interpolation, output}, path);\n if (value) {\n updateTargetPath(target, path, value);\n }\n}\n\n/** Evaluates a glTF animation sampler at the supplied time. */\nexport function evaluateSampler(\n time: number,\n {input, interpolation, output}: GLTFAnimationSampler,\n path?: GLTFAnimationPath\n): number[] | null {\n const maxTime = input[input.length - 1];\n if (!Number.isFinite(maxTime) || maxTime <= 0) {\n return output[0] || null;\n }\n\n const animationTime = time % maxTime;\n\n const nextIndex = input.findIndex(t => t >= animationTime);\n if (nextIndex < 0) {\n return output[output.length - 1] || null;\n }\n const previousIndex = Math.max(0, nextIndex - 1);\n\n const previousTime = input[previousIndex];\n const nextTime = input[nextIndex];\n\n switch (interpolation) {\n case 'STEP':\n return output[previousIndex];\n\n case 'LINEAR':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n return linearInterpolate(path, output[previousIndex], output[nextIndex], ratio);\n }\n return output[previousIndex] || null;\n\n case 'CUBICSPLINE':\n if (nextTime > previousTime) {\n const ratio = (animationTime - previousTime) / (nextTime - previousTime);\n const tDiff = nextTime - previousTime;\n\n const p0 = output[3 * previousIndex + 1];\n const outTangent0 = output[3 * previousIndex + 2];\n const inTangent1 = output[3 * nextIndex + 0];\n const p1 = output[3 * nextIndex + 1];\n\n return cubicsplineInterpolate({p0, outTangent0, inTangent1, p1, tDiff, ratio});\n }\n return output[3 * previousIndex + 1] || null;\n\n default:\n log.warn(`Interpolation ${interpolation} not supported`)();\n return null;\n }\n}\n\n/** Applies linear interpolation between two keyframes. */\nfunction linearInterpolate(\n path: GLTFAnimationPath | undefined,\n start: number[],\n stop: number[],\n ratio: number\n): number[] {\n if (path === 'rotation') {\n // SLERP when path is rotation\n return new Quaternion().slerp({start, target: stop, ratio}) as unknown as number[];\n }\n\n const newVal = [];\n for (let i = 0; i < start.length; i++) {\n newVal[i] = ratio * stop[i] + (1 - ratio) * start[i];\n }\n return newVal;\n}\n\n/** Applies glTF cubic spline interpolation between two keyframes. */\nfunction cubicsplineInterpolate({\n p0,\n outTangent0,\n inTangent1,\n p1,\n tDiff,\n ratio: t\n}: {\n p0: number[];\n outTangent0: number[];\n inTangent1: number[];\n p1: number[];\n tDiff: number;\n ratio: number;\n}): number[] {\n // TODO: Quaternion might need normalization\n const newVal = [];\n for (let i = 0; i < p0.length; i++) {\n const m0 = outTangent0[i] * tDiff;\n const m1 = inTangent1[i] * tDiff;\n newVal[i] =\n (2 * Math.pow(t, 3) - 3 * Math.pow(t, 2) + 1) * p0[i] +\n (Math.pow(t, 3) - 2 * Math.pow(t, 2) + t) * m0 +\n (-2 * Math.pow(t, 3) + 3 * Math.pow(t, 2)) * p1[i] +\n (Math.pow(t, 3) - Math.pow(t, 2)) * m1;\n }\n return newVal;\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {log} from '@luma.gl/core';\nimport {type GLTFAccessorPostprocessed, type GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {\n GLTFAnimationPath,\n type GLTFAnimation,\n type GLTFAnimationChannel,\n type GLTFMaterialAnimationChannel,\n type GLTFMaterialAnimationProperty,\n type GLTFNodeAnimationChannel,\n type GLTFAnimationSampler,\n type GLTFTextureTransformAnimationChannel\n} from '../gltf/animations/animations';\nimport {\n resolveTextureTransform,\n resolveTextureTransformSlot,\n type PBRTextureTransformPath\n} from '../pbr/texture-transform';\nimport {getRegisteredGLTFExtensionSupport} from '../gltf/gltf-extension-support';\n\nimport {accessorToTypedArray} from '../webgl-to-webgpu/convert-webgl-attribute';\n\ntype UnsupportedAnimationPointerResolution = {\n reason: string;\n};\n\n/** Parses glTF animation records into the runtime animation model used by `GLTFAnimator`. */\nexport function parseGLTFAnimations(gltf: GLTFPostprocessed): GLTFAnimation[] {\n const gltfAnimations = gltf.animations || [];\n const accessorCache1D = new Map<GLTFAccessorPostprocessed, number[]>();\n const accessorCache2D = new Map<GLTFAccessorPostprocessed, number[][]>();\n\n return gltfAnimations.flatMap((animation, index) => {\n const name = animation.name || `Animation-${index}`;\n const samplerCache = new Map<number, GLTFAnimationSampler>();\n const channels: GLTFAnimationChannel[] = animation.channels.flatMap(({sampler, target}) => {\n let parsedSampler = samplerCache.get(sampler);\n if (!parsedSampler) {\n const gltfSampler = animation.samplers[sampler];\n if (!gltfSampler) {\n throw new Error(`Cannot find animation sampler ${sampler}`);\n }\n const {input, interpolation = 'LINEAR', output} = gltfSampler;\n parsedSampler = {\n input: accessorToJsArray1D(gltf.accessors[input], accessorCache1D),\n interpolation,\n output: accessorToJsArray2D(gltf.accessors[output], accessorCache2D)\n };\n samplerCache.set(sampler, parsedSampler);\n }\n\n const parsedChannel = parseAnimationChannel(gltf, target, parsedSampler);\n return parsedChannel ? [parsedChannel] : [];\n });\n\n return channels.length ? [{name, channels}] : [];\n });\n}\n\nfunction parseAnimationChannel(\n gltf: GLTFPostprocessed,\n target: {node?: number; path: string; extensions?: Record<string, any>},\n sampler: GLTFAnimationSampler\n): GLTFAnimationChannel | null {\n if (target.path === 'pointer') {\n return parseAnimationPointerChannel(gltf, target, sampler);\n }\n\n const path = getNodeAnimationPath(target.path);\n if (!path) {\n return null;\n }\n\n const targetNode = gltf.nodes[target.node ?? 0];\n if (!targetNode) {\n throw new Error(`Cannot find animation target ${target.node}`);\n }\n\n return {\n type: 'node',\n sampler,\n targetNodeId: targetNode.id,\n path\n };\n}\n\nfunction parseAnimationPointerChannel(\n gltf: GLTFPostprocessed,\n target: {extensions?: Record<string, any>},\n sampler: GLTFAnimationSampler\n): GLTFAnimationChannel | null {\n const pointer = target.extensions?.['KHR_animation_pointer']?.pointer;\n if (typeof pointer !== 'string' || !pointer.startsWith('/')) {\n log.warn('KHR_animation_pointer channel is missing a valid JSON pointer and will be skipped')();\n return null;\n }\n\n const pointerSegments = splitJsonPointer(pointer);\n switch (pointerSegments[0]) {\n case 'nodes':\n return parseNodePointerAnimationChannel(gltf, pointerSegments, sampler, pointer);\n\n case 'materials':\n return parseMaterialPointerAnimationChannel(gltf, pointerSegments, sampler, pointer);\n\n default:\n warnUnsupportedAnimationPointer(\n pointer,\n `top-level target \"${pointerSegments[0]}\" has no runtime animation mapping`\n );\n return null;\n }\n}\n\nfunction parseNodePointerAnimationChannel(\n gltf: GLTFPostprocessed,\n pointerSegments: string[],\n sampler: GLTFAnimationSampler,\n pointer: string\n): GLTFNodeAnimationChannel | null {\n if (pointerSegments.length !== 3) {\n warnUnsupportedAnimationPointer(\n pointer,\n 'node pointers must use /nodes/{index}/{translation|rotation|scale|weights}'\n );\n return null;\n }\n\n const nodeIndex = Number(pointerSegments[1]);\n const targetNode = gltf.nodes[nodeIndex];\n if (!Number.isInteger(nodeIndex) || !targetNode) {\n log.warn(\n `KHR_animation_pointer target ${pointer} references a missing node and will be skipped`\n )();\n return null;\n }\n\n const path = getNodeAnimationPath(pointerSegments[2]);\n if (!path) {\n warnUnsupportedAnimationPointer(\n pointer,\n `node property \"${pointerSegments[2]}\" has no runtime animation mapping`\n );\n return null;\n }\n if (path === 'weights') {\n log.warn(\n `KHR_animation_pointer target ${pointer} will be skipped because morph weights are not implemented in GLTFAnimator`\n )();\n return null;\n }\n\n return {\n type: 'node',\n sampler,\n targetNodeId: targetNode.id,\n path\n };\n}\n\nfunction parseMaterialPointerAnimationChannel(\n gltf: GLTFPostprocessed,\n pointerSegments: string[],\n sampler: GLTFAnimationSampler,\n pointer: string\n): GLTFMaterialAnimationChannel | GLTFTextureTransformAnimationChannel | null {\n if (pointerSegments.length < 3) {\n warnUnsupportedAnimationPointer(\n pointer,\n 'material pointers must include a material index and target property path'\n );\n return null;\n }\n\n const materialIndex = Number(pointerSegments[1]);\n const material = gltf.materials[materialIndex] as Record<string, any> | undefined;\n if (!Number.isInteger(materialIndex) || !material) {\n log.warn(\n `KHR_animation_pointer target ${pointer} references a missing material and will be skipped`\n )();\n return null;\n }\n\n const materialTarget = resolveMaterialAnimationTarget(material, pointerSegments.slice(2));\n if ('reason' in materialTarget) {\n warnUnsupportedAnimationPointer(pointer, materialTarget.reason);\n return null;\n }\n\n return {\n sampler,\n pointer,\n targetMaterialIndex: materialIndex,\n ...materialTarget\n };\n}\n\nfunction getNodeAnimationPath(path: string): GLTFAnimationPath | null {\n switch (path) {\n case 'translation':\n case 'rotation':\n case 'scale':\n case 'weights':\n return path;\n\n default:\n return null;\n }\n}\n\nfunction resolveMaterialAnimationTarget(\n material: Record<string, any>,\n pointerSegments: string[]\n):\n | {type: 'material'; property: GLTFMaterialAnimationProperty; component?: number}\n | {\n type: 'textureTransform';\n textureSlot: import('../pbr/texture-transform').PBRTextureTransformSlot;\n path: PBRTextureTransformPath;\n component?: number;\n baseTransform: import('../pbr/texture-transform').PBRTextureTransform;\n }\n | UnsupportedAnimationPointerResolution {\n const textureTransformTarget = resolveTextureTransformAnimationTarget(material, pointerSegments);\n if (!('reason' in textureTransformTarget)) {\n return textureTransformTarget;\n }\n if (textureTransformTarget.reason !== 'not-a-texture-transform-target') {\n return textureTransformTarget;\n }\n\n const pointerPath = pointerSegments.join('/');\n\n switch (pointerPath) {\n case 'pbrMetallicRoughness/baseColorFactor':\n return material['pbrMetallicRoughness']\n ? {type: 'material', property: 'baseColorFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'pbrMetallicRoughness/metallicFactor':\n return material['pbrMetallicRoughness']\n ? {type: 'material', property: 'metallicRoughnessValues', component: 0}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'pbrMetallicRoughness/roughnessFactor':\n return material['pbrMetallicRoughness']\n ? {type: 'material', property: 'metallicRoughnessValues', component: 1}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'normalTexture/scale':\n return material['normalTexture']\n ? {type: 'material', property: 'normalScale'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'occlusionTexture/strength':\n return material['occlusionTexture']\n ? {type: 'material', property: 'occlusionStrength'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'emissiveFactor':\n return {type: 'material', property: 'emissiveFactor'};\n\n case 'alphaCutoff':\n return {type: 'material', property: 'alphaCutoff'};\n\n case 'extensions/KHR_materials_specular/specularFactor':\n return material['extensions']?.['KHR_materials_specular']\n ? {type: 'material', property: 'specularIntensityFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_specular/specularColorFactor':\n return material['extensions']?.['KHR_materials_specular']\n ? {type: 'material', property: 'specularColorFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_ior/ior':\n return material['extensions']?.['KHR_materials_ior']\n ? {type: 'material', property: 'ior'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_transmission/transmissionFactor':\n return material['extensions']?.['KHR_materials_transmission']\n ? {type: 'material', property: 'transmissionFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_volume/thicknessFactor':\n return material['extensions']?.['KHR_materials_volume']\n ? {type: 'material', property: 'thicknessFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_volume/attenuationDistance':\n return material['extensions']?.['KHR_materials_volume']\n ? {type: 'material', property: 'attenuationDistance'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_volume/attenuationColor':\n return material['extensions']?.['KHR_materials_volume']\n ? {type: 'material', property: 'attenuationColor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_clearcoat/clearcoatFactor':\n return material['extensions']?.['KHR_materials_clearcoat']\n ? {type: 'material', property: 'clearcoatFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_clearcoat/clearcoatRoughnessFactor':\n return material['extensions']?.['KHR_materials_clearcoat']\n ? {type: 'material', property: 'clearcoatRoughnessFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_sheen/sheenColorFactor':\n return material['extensions']?.['KHR_materials_sheen']\n ? {type: 'material', property: 'sheenColorFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_sheen/sheenRoughnessFactor':\n return material['extensions']?.['KHR_materials_sheen']\n ? {type: 'material', property: 'sheenRoughnessFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_iridescence/iridescenceFactor':\n return material['extensions']?.['KHR_materials_iridescence']\n ? {type: 'material', property: 'iridescenceFactor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_iridescence/iridescenceIor':\n return material['extensions']?.['KHR_materials_iridescence']\n ? {type: 'material', property: 'iridescenceIor'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_iridescence/iridescenceThicknessMinimum':\n return material['extensions']?.['KHR_materials_iridescence']\n ? {type: 'material', property: 'iridescenceThicknessRange', component: 0}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_iridescence/iridescenceThicknessMaximum':\n return material['extensions']?.['KHR_materials_iridescence']\n ? {type: 'material', property: 'iridescenceThicknessRange', component: 1}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_anisotropy/anisotropyStrength':\n return material['extensions']?.['KHR_materials_anisotropy']\n ? {type: 'material', property: 'anisotropyStrength'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_anisotropy/anisotropyRotation':\n return material['extensions']?.['KHR_materials_anisotropy']\n ? {type: 'material', property: 'anisotropyRotation'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n case 'extensions/KHR_materials_emissive_strength/emissiveStrength':\n return material['extensions']?.['KHR_materials_emissive_strength']\n ? {type: 'material', property: 'emissiveStrength'}\n : {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n\n default:\n return {reason: getUnsupportedMaterialPointerReason(pointerSegments)};\n }\n}\n\nfunction resolveTextureTransformAnimationTarget(\n material: Record<string, any>,\n pointerSegments: string[]\n):\n | {\n type: 'textureTransform';\n textureSlot: import('../pbr/texture-transform').PBRTextureTransformSlot;\n path: PBRTextureTransformPath;\n component?: number;\n baseTransform: import('../pbr/texture-transform').PBRTextureTransform;\n }\n | UnsupportedAnimationPointerResolution {\n const extensionIndex = pointerSegments.lastIndexOf('extensions');\n if (\n extensionIndex < 0 ||\n pointerSegments[extensionIndex + 1] !== 'KHR_texture_transform' ||\n extensionIndex < 1\n ) {\n return {reason: 'not-a-texture-transform-target'};\n }\n\n const textureSlotDefinition = resolveTextureTransformSlot(\n pointerSegments.slice(0, extensionIndex)\n );\n if (!textureSlotDefinition) {\n return {\n reason: getUnsupportedTextureTransformSlotReason(pointerSegments.slice(0, extensionIndex))\n };\n }\n\n const textureInfo = getNestedMaterialValue(material, textureSlotDefinition.pathSegments);\n if (!textureInfo) {\n return {\n reason: `texture-transform target \"${pointerSegments\n .slice(0, extensionIndex)\n .join('/')}\" does not exist on the referenced material`\n };\n }\n\n const textureTransformPath = pointerSegments[extensionIndex + 2];\n if (textureTransformPath === 'texCoord') {\n return {\n reason:\n 'animated KHR_texture_transform.texCoord is unsupported because texCoord selection is structural, not a runtime float/vector update'\n };\n }\n if (\n textureTransformPath !== 'offset' &&\n textureTransformPath !== 'rotation' &&\n textureTransformPath !== 'scale'\n ) {\n return {\n reason: `KHR_texture_transform property \"${textureTransformPath}\" is not animatable; supported properties are offset, rotation, and scale`\n };\n }\n\n const componentSegment = pointerSegments[extensionIndex + 3];\n if (pointerSegments.length > extensionIndex + 4) {\n return {\n reason: `KHR_texture_transform.${textureTransformPath} does not support nested property paths`\n };\n }\n\n let component: number | undefined;\n if (componentSegment !== undefined) {\n component = Number(componentSegment);\n if (textureTransformPath === 'rotation') {\n return {\n reason: 'KHR_texture_transform.rotation does not support component indices'\n };\n }\n if (!Number.isInteger(component) || component < 0 || component > 1) {\n return {\n reason: `KHR_texture_transform.${textureTransformPath} component index \"${componentSegment}\" is invalid; only 0 and 1 are supported`\n };\n }\n }\n\n return {\n type: 'textureTransform',\n textureSlot: textureSlotDefinition.slot,\n path: textureTransformPath,\n component,\n baseTransform: resolveTextureTransform(textureInfo)\n };\n}\n\nfunction getNestedMaterialValue(\n material: Record<string, any>,\n pathSegments: string[]\n): Record<string, any> | null {\n let value: any = material;\n for (const pathSegment of pathSegments) {\n value = value?.[pathSegment];\n if (!value) {\n return null;\n }\n }\n\n return value;\n}\n\nfunction splitJsonPointer(pointer: string): string[] {\n return pointer\n .slice(1)\n .split('/')\n .map(segment => segment.replace(/~1/g, '/').replace(/~0/g, '~'));\n}\n\nfunction getUnsupportedMaterialPointerReason(pointerSegments: string[]): string {\n const extensionName = getPointerExtensionName(pointerSegments);\n if (extensionName) {\n const extensionSupport = getRegisteredGLTFExtensionSupport(extensionName);\n if (extensionSupport?.supportLevel === 'none') {\n return `${extensionName} is referenced by this pointer, but ${extensionSupport.comment\n .charAt(0)\n .toLowerCase()}${extensionSupport.comment.slice(1)}`;\n }\n }\n\n return `no runtime target exists for material property \"${pointerSegments.join('/')}\"`;\n}\n\nfunction getUnsupportedTextureTransformSlotReason(pointerSegments: string[]): string {\n const extensionName = getPointerExtensionName(pointerSegments);\n if (extensionName) {\n const extensionSupport = getRegisteredGLTFExtensionSupport(extensionName);\n if (extensionSupport?.supportLevel === 'none') {\n return `${extensionName} is referenced by this pointer, but ${extensionSupport.comment\n .charAt(0)\n .toLowerCase()}${extensionSupport.comment.slice(1)}`;\n }\n }\n\n return `texture-transform target \"${pointerSegments.join('/')}\" has no runtime texture-slot mapping`;\n}\n\nfunction getPointerExtensionName(pointerSegments: string[]): string | null {\n const extensionIndex = pointerSegments.indexOf('extensions');\n const extensionName = pointerSegments[extensionIndex + 1];\n return extensionIndex >= 0 && extensionName ? extensionName : null;\n}\n\nfunction warnUnsupportedAnimationPointer(pointer: string, reason: string): void {\n log.warn(`KHR_animation_pointer target ${pointer} will be skipped because ${reason}`)();\n}\n\n/** Converts a scalar accessor into a cached JavaScript number array. */\nfunction accessorToJsArray1D(\n accessor: GLTFAccessorPostprocessed,\n accessorCache: Map<GLTFAccessorPostprocessed, number[]>\n): number[] {\n if (accessorCache.has(accessor)) {\n return accessorCache.get(accessor)!;\n }\n\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n assert(components === 1, 'accessorToJsArray1D must have exactly 1 component');\n const result = Array.from(array);\n\n accessorCache.set(accessor, result);\n return result;\n}\n\n/** Converts a scalar, vector, or matrix accessor into a cached JavaScript array-of-arrays. */\nfunction accessorToJsArray2D(\n accessor: GLTFAccessorPostprocessed,\n accessorCache: Map<GLTFAccessorPostprocessed, number[][]>\n): number[][] {\n if (accessorCache.has(accessor)) {\n return accessorCache.get(accessor)!;\n }\n\n const {typedArray: array, components} = accessorToTypedArray(accessor);\n assert(components >= 1, 'accessorToJsArray2D must have at least 1 component');\n\n const result = [];\n\n // Slice array\n for (let i = 0; i < array.length; i += components) {\n result.push(Array.from(array.slice(i, i + components)));\n }\n\n accessorCache.set(accessor, result);\n return result;\n}\n\n/** Throws when the supplied condition is false. */\nfunction assert(condition: boolean, message?: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type {GLTFPostprocessed} from '@loaders.gl/gltf';\n\nexport type GLTFExtensionSupportLevel = 'built-in' | 'parsed-and-wired' | 'loader-only' | 'none';\n\nexport type GLTFExtensionSupport = {\n extensionName: string;\n supported: boolean;\n supportLevel: GLTFExtensionSupportLevel;\n comment: string;\n};\n\ntype GLTFExtensionSupportDefinition = Omit<GLTFExtensionSupport, 'extensionName' | 'supported'>;\n\ntype GLTFPostprocessedWithRemovedExtensions = GLTFPostprocessed & {\n extensionsRemoved?: string[];\n lights?: unknown[];\n};\n\nconst UNKNOWN_EXTENSION_SUPPORT: GLTFExtensionSupportDefinition = {\n supportLevel: 'none',\n comment: 'Not currently listed in the luma.gl glTF extension support registry.'\n};\n\nconst GLTF_EXTENSION_SUPPORT_REGISTRY: Record<string, GLTFExtensionSupportDefinition> = {\n KHR_draco_mesh_compression: {\n supportLevel: 'built-in',\n comment: 'Decoded by loaders.gl before luma.gl builds the scenegraph.'\n },\n EXT_meshopt_compression: {\n supportLevel: 'built-in',\n comment: 'Meshopt-compressed primitives are decoded during load.'\n },\n KHR_mesh_quantization: {\n supportLevel: 'built-in',\n comment: 'Quantized accessors are unpacked before geometry creation.'\n },\n KHR_lights_punctual: {\n supportLevel: 'built-in',\n comment: 'Parsed into luma.gl Light objects.'\n },\n KHR_materials_unlit: {\n supportLevel: 'built-in',\n comment: 'Unlit materials bypass the default lighting path.'\n },\n KHR_materials_emissive_strength: {\n supportLevel: 'built-in',\n comment: 'Applied by the stock PBR shader.'\n },\n KHR_texture_basisu: {\n supportLevel: 'built-in',\n comment: 'BasisU / KTX2 textures pass through when the device supports them.'\n },\n KHR_texture_transform: {\n supportLevel: 'built-in',\n comment: 'UV transforms are applied during load.'\n },\n EXT_texture_webp: {\n supportLevel: 'loader-only',\n comment:\n 'Texture source is resolved during load; final support depends on browser and device decode support.'\n },\n EXT_texture_avif: {\n supportLevel: 'loader-only',\n comment:\n 'Texture source is resolved during load; final support depends on browser and device decode support.'\n },\n KHR_materials_specular: {\n supportLevel: 'built-in',\n comment: 'The stock shader now applies specular factors and textures to the dielectric F0 term.'\n },\n KHR_materials_ior: {\n supportLevel: 'built-in',\n comment: 'The stock shader now drives dielectric reflectance from the glTF IOR value.'\n },\n KHR_materials_transmission: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now applies transmission to the base layer and exposes transparency through alpha, without a scene-color refraction buffer.'\n },\n KHR_materials_volume: {\n supportLevel: 'built-in',\n comment: 'Thickness and attenuation now tint transmitted light in the stock shader.'\n },\n KHR_materials_clearcoat: {\n supportLevel: 'built-in',\n comment: 'The stock shader now adds a secondary clearcoat specular lobe.'\n },\n KHR_materials_sheen: {\n supportLevel: 'built-in',\n comment: 'The stock shader now adds a sheen lobe for cloth-like materials.'\n },\n KHR_materials_iridescence: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now tints specular response with a view-dependent thin-film iridescence approximation.'\n },\n KHR_materials_anisotropy: {\n supportLevel: 'built-in',\n comment:\n 'The stock shader now shapes highlights and IBL response with an anisotropy-direction approximation.'\n },\n KHR_materials_pbrSpecularGlossiness: {\n supportLevel: 'loader-only',\n comment:\n 'Extension data can be loaded, but it is not translated into the default metallic-roughness material path.'\n },\n KHR_materials_variants: {\n supportLevel: 'loader-only',\n comment: 'Variant metadata can be loaded, but applications must choose and apply variants.'\n },\n EXT_mesh_gpu_instancing: {\n supportLevel: 'none',\n comment: 'GPU instancing data is not yet converted into luma.gl instanced draw setup.'\n },\n KHR_node_visibility: {\n supportLevel: 'none',\n comment: 'Node-visibility animations and toggles are not mapped onto runtime scenegraph state.'\n },\n KHR_animation_pointer: {\n supportLevel: 'parsed-and-wired',\n comment:\n 'Selected node TRS, material factor, and KHR_texture_transform offset/rotation/scale pointers are wired to runtime updates; unsupported targets are skipped.'\n },\n KHR_materials_diffuse_transmission: {\n supportLevel: 'none',\n comment: 'Diffuse-transmission shading is not implemented in the stock PBR shader.'\n },\n KHR_materials_dispersion: {\n supportLevel: 'none',\n comment: 'Chromatic dispersion is not implemented in the stock PBR shader.'\n },\n KHR_materials_volume_scatter: {\n supportLevel: 'none',\n comment: 'Volume scattering is not implemented in the stock PBR shader.'\n },\n KHR_xmp: {\n supportLevel: 'none',\n comment: 'Metadata payloads remain in the loaded glTF, but luma.gl does not interpret them.'\n },\n KHR_xmp_json_ld: {\n supportLevel: 'none',\n comment: 'Metadata is preserved in the glTF, but luma.gl does not interpret it.'\n },\n EXT_lights_image_based: {\n supportLevel: 'none',\n comment: 'Use loadPBREnvironment() or custom environment setup instead.'\n },\n EXT_texture_video: {\n supportLevel: 'none',\n comment: 'Video textures are not created automatically by the stock pipeline.'\n },\n MSFT_lod: {\n supportLevel: 'none',\n comment: 'Level-of-detail switching is not implemented in the stock scenegraph loader.'\n }\n};\n\nexport function getGLTFExtensionSupport(\n gltf: GLTFPostprocessed\n): Map<string, GLTFExtensionSupport> {\n const extensionNames = Array.from(collectGLTFExtensionNames(gltf)).sort();\n const extensionSupportEntries: [string, GLTFExtensionSupport][] = extensionNames.map(\n extensionName => {\n const extensionSupportDefinition =\n GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || UNKNOWN_EXTENSION_SUPPORT;\n\n return [\n extensionName,\n {\n extensionName,\n supported:\n extensionSupportDefinition.supportLevel === 'built-in' ||\n extensionSupportDefinition.supportLevel === 'parsed-and-wired',\n supportLevel: extensionSupportDefinition.supportLevel,\n comment: extensionSupportDefinition.comment\n }\n ];\n }\n );\n\n return new Map(extensionSupportEntries);\n}\n\nexport function getRegisteredGLTFExtensionSupport(\n extensionName: string\n): GLTFExtensionSupportDefinition | null {\n return GLTF_EXTENSION_SUPPORT_REGISTRY[extensionName] || null;\n}\n\nfunction collectGLTFExtensionNames(gltf: GLTFPostprocessed): Set<string> {\n const gltfWithRemovedExtensions = gltf as GLTFPostprocessedWithRemovedExtensions;\n const extensionNames = new Set<string>();\n\n addExtensionNames(extensionNames, gltf.extensionsUsed);\n addExtensionNames(extensionNames, gltf.extensionsRequired);\n addExtensionNames(extensionNames, gltfWithRemovedExtensions.extensionsRemoved);\n addExtensionNames(extensionNames, Object.keys(gltf.extensions || {}));\n\n if (\n gltfWithRemovedExtensions.lights?.length ||\n (gltf.nodes || []).some(node => 'light' in node)\n ) {\n extensionNames.add('KHR_lights_punctual');\n }\n\n if (\n (gltf.materials || []).some(material => {\n const gltfMaterial = material as typeof material & {unlit?: boolean};\n return gltfMaterial.unlit || gltfMaterial.extensions?.KHR_materials_unlit;\n })\n ) {\n extensionNames.add('KHR_materials_unlit');\n }\n\n return extensionNames;\n}\n\nfunction addExtensionNames(extensionNames: Set<string>, newExtensionNames: string[] = []): void {\n for (const extensionName of newExtensionNames) {\n extensionNames.add(extensionName);\n }\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// TODO: convert in loaders.gl?\nimport type {TypedArray} from '@math.gl/types';\n\n/** Maps glTF accessor type strings to their component counts. */\nexport const ATTRIBUTE_TYPE_TO_COMPONENTS: Record<string, number> = {\n SCALAR: 1,\n VEC2: 2,\n VEC3: 3,\n VEC4: 4,\n MAT2: 4,\n MAT3: 9,\n MAT4: 16\n};\n\n/** Maps glTF accessor component-type enums to typed-array constructors. */\nexport const ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY: Record<number, any> = {\n 5120: Int8Array,\n 5121: Uint8Array,\n 5122: Int16Array,\n 5123: Uint16Array,\n 5125: Uint32Array,\n 5126: Float32Array\n};\n\n/** Minimal accessor shape required to materialize a typed array. */\ntype GLTFAccessor = {\n /** Numeric component type enum. */\n componentType: number;\n /** Accessor type string such as `VEC3` or `SCALAR`. */\n type: string;\n /** Number of logical elements in the accessor. */\n count: number;\n /** Buffer view carrying the raw bytes. */\n bufferView?: {data: {buffer: ArrayBufferLike; byteOffset?: number}};\n /** Byte offset into the buffer view. */\n byteOffset?: number;\n};\n\n/** Converts a glTF accessor into a typed array plus its component count. */\nexport function accessorToTypedArray(accessor: GLTFAccessor): {\n /** Typed array view over the accessor data. */\n typedArray: TypedArray;\n /** Number of scalar components per element. */\n components: number;\n} {\n const ArrayType = ATTRIBUTE_COMPONENT_TYPE_TO_ARRAY[accessor.componentType];\n const components = ATTRIBUTE_TYPE_TO_COMPONENTS[accessor.type];\n const length = components * accessor.count;\n const {buffer, byteOffset = 0} = accessor.bufferView?.data ?? {};\n\n const typedArray = new ArrayType(buffer, byteOffset + (accessor.byteOffset || 0), length);\n\n return {typedArray, components};\n}\n", "// luma.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport {Device} from '@luma.gl/core';\nimport {GroupNode, Material} from '@luma.gl/engine';\nimport {GLTFPostprocessed} from '@loaders.gl/gltf';\nimport {Light} from '@luma.gl/shadertools';\nimport {parseGLTF, type ParseGLTFOptions} from '../parsers/parse-gltf';\nimport {parseGLTFLights} from '../parsers/parse-gltf-lights';\nimport {GLTFAnimator} from './gltf-animator';\nimport {parseGLTFAnimations} from '../parsers/parse-gltf-animations';\nimport {getGLTFExtensionSupport, type GLTFExtensionSupport} from './gltf-extension-support';\n\nexport type GLTFScenegraphBounds = {\n /** World-space axis-aligned bounds for the scene or model. */\n bounds: [[number, number, number], [number, number, number]] | null;\n /** World-space center of the bounds. */\n center: [number, number, number];\n /** World-space bounds size on each axis. */\n size: [number, number, number];\n /** Half of the world-space bounds diagonal, clamped to a small practical minimum. */\n radius: number;\n /** Suggested orbit distance for a 60-degree field of view camera. */\n recommendedOrbitDistance: number;\n};\n\n/** Scenegraph bundle returned from a parsed glTF asset. */\nexport type GLTFScenegraphs = {\n /** Scene roots produced from the glTF scenes array. */\n scenes: GroupNode[];\n /** Materials aligned with the source glTF `materials` array. */\n materials: Material[];\n /** Animation controller for glTF animations. */\n animator: GLTFAnimator;\n /** Parsed punctual lights from the asset. */\n lights: Light[];\n /** Extensions reported by the asset and whether luma.gl supports them. */\n extensionSupport: Map<string, GLTFExtensionSupport>;\n /** Camera-friendly bounds for each scene in `scenes`, in matching order. */\n sceneBounds: GLTFScenegraphBounds[];\n /** Combined camera-friendly bounds for the entire loaded asset. */\n modelBounds: GLTFScenegraphBounds;\n\n /** Map from glTF mesh ids to generated mesh group nodes. */\n gltfMeshIdToNodeMap: Map<string, GroupNode>;\n /** Map from glTF node indices to generated scenegraph nodes. */\n gltfNodeIndexToNodeMap: Map<number, GroupNode>;\n /** Map from glTF node ids to generated scenegraph nodes. */\n gltfNodeIdToNodeMap: Map<string, GroupNode>;\n\n /** Original post-processed glTF document. */\n gltf: GLTFPostprocessed;\n};\n\n/** Converts a post-processed glTF asset into luma.gl scenegraph nodes and animation helpers. */\nexport function createScenegraphsFromGLTF(\n device: Device,\n gltf: GLTFPostprocessed,\n options?: ParseGLTFOptions\n): GLTFScenegraphs {\n const {scenes, materials, gltfMeshIdToNodeMap, gltfNodeIdToNodeMap, gltfNodeIndexToNodeMap} =\n parseGLTF(device, gltf, options);\n\n const animations = parseGLTFAnimations(gltf);\n const animator = new GLTFAnimator({animations, gltfNodeIdToNodeMap, materials});\n const lights = parseGLTFLights(gltf, {useByteColors: options?.useByteColors ?? true});\n const extensionSupport = getGLTFExtensionSupport(gltf);\n const sceneBounds = scenes.map(scene => getScenegraphBounds(scene.getBounds()));\n const modelBounds = getCombinedScenegraphBounds(sceneBounds);\n\n return {\n scenes,\n materials,\n animator,\n lights,\n extensionSupport,\n sceneBounds,\n modelBounds,\n gltfMeshIdToNodeMap,\n gltfNodeIdToNodeMap,\n gltfNodeIndexToNodeMap,\n gltf\n };\n}\n\nfunction getScenegraphBounds(bounds: [number[], number[]] | null): GLTFScenegraphBounds {\n if (!bounds) {\n return {\n bounds: null,\n center: [0, 0, 0],\n size: [0, 0, 0],\n radius: 0.5,\n recommendedOrbitDistance: 1\n };\n }\n\n const normalizedBounds: [[number, number, number], [number, number, number]] = [\n [bounds[0][0], bounds[0][1], bounds[0][2]],\n [bounds[1][0], bounds[1][1], bounds[1][2]]\n ];\n const size: [number, number, number] = [\n normalizedBounds[1][0] - normalizedBounds[0][0],\n normalizedBounds[1][1] - normalizedBounds[0][1],\n normalizedBounds[1][2] - normalizedBounds[0][2]\n ];\n const center: [number, number, number] = [\n normalizedBounds[0][0] + size[0] * 0.5,\n normalizedBounds[0][1] + size[1] * 0.5,\n normalizedBounds[0][2] + size[2] * 0.5\n ];\n const maxHalfExtent = Math.max(size[0], size[1], size[2]) * 0.5;\n const radius = Math.max(0.5 * Math.hypot(size[0], size[1], size[2]), 0.001);\n\n return {\n bounds: normalizedBounds,\n center,\n size,\n radius,\n recommendedOrbitDistance: Math.max(\n (Math.max(maxHalfExtent, 0.001) / Math.tan(Math.PI / 6)) * 1.15,\n radius * 1.1\n )\n };\n}\n\nfunction getCombinedScenegraphBounds(sceneBounds: GLTFScenegraphBounds[]): GLTFScenegraphBounds {\n let combinedBounds: [[number, number, number], [number, number, number]] | null = null;\n\n for (const sceneBoundInfo of sceneBounds) {\n if (!sceneBoundInfo.bounds) {\n continue;\n }\n\n if (!combinedBounds) {\n combinedBounds = [\n [...sceneBoundInfo.bounds[0]] as [number, number, number],\n [...sceneBoundInfo.bounds[1]] as [number, number, number]\n ];\n continue;\n }\n\n for (let axis = 0; axis < 3; axis++) {\n combinedBounds[0][axis] = Math.min(combinedBounds[0][axis], sceneBoundInfo.bounds[0][axis]);\n combinedBounds[1][axis] = Math.max(combinedBounds[1][axis], sceneBoundInfo.bounds[1][axis]);\n }\n }\n\n return getScenegraphBounds(combinedBounds);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;ACKA,oBAKO;AACP,sBAA+B;AAuBzB,SAAU,mBAAmB,QAAgB,OAA0B;AAC3E,QAAM,oBAAoB,MAAM,qBAAqB;AAErD,QAAM,iBAAiB,IAAI,6BAAe,QAAQ;IAChD,IAAI;IACJ,SAAS;MACP,cAAc;MACd,cAAc;MACd,WAAW;MACX,WAAW;;;IAGb,UAAM,kCAAiB,kBAAkB,MAAM,UAAU,CAAC;GAC3D;AAED,QAAM,oBAAoB,SAAS,QAAQ;IACzC,IAAI;IACJ,mBAAmB,cACjB,kCACE,kBAAkB,MAAM,UAAU,WAAW,MAAM,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC;IAEzE,SAAS;MACP,cAAc;MACd,cAAc;MACd,WAAW;MACX,WAAW;;GAEd;AAED,QAAM,qBAAqB,SAAS,QAAQ;IAC1C,IAAI;IACJ,mBAAmB,CAAC,SAAyB;AAC3C,YAAM,aAAsC,CAAA;AAC5C,YAAM,YAAY,MAAM,QAAQ,IAAI;AACpC,eAAS,MAAM,GAAG,MAAM,mBAAmB,OAAO;AAChD,mBAAW,SACT,kCAAiB,kBAAkB,MAAM,UAAU,YAAY,WAAW,GAAG,CAAC,CAAC,CAAC;MAEpF;AACA,aAAO,QAAQ,IAAI,UAAU;IAC/B;IACA,SAAS;MACP,cAAc;MACd,cAAc;MACd,WAAW;;MACX,WAAW;;GAEd;AAED,SAAO;IACL;IACA;IACA;;AAEJ;AAGA,IAAM,QAA2B,CAAC,MAAM,MAAM,MAAM,MAAM,MAAM,IAAI;AAEpE,SAAS,kBAAkB,KAAW;AA7FtC;AA8FE,QAAM,YAAU,gBAAW,aAAX,mBAAqB,cAAW,gBAAW,aAAX,mBAAqB;AACrE,SAAO,UAAU,IAAI,IAAI,KAAK,OAAO,EAAE,SAAQ,IAAK;AACtD;AAGA,SAAS,SACP,QACA,EACE,IACA,mBACA,QAAO,GAQR;AAED,QAAM,OAAiC,QAAQ,IAC7C,MAAM,IAAI,UAAQ,kBAAkB,IAAI,CAAC,CAAC,EAC1C,KAAK,mBAAgB;AACrB,UAAM,WAAW,CAAA;AACjB,UAAM,QAAQ,CAAC,MAAM,UAAS;AAC5B,eAAS,IAAI,IAAI,cAAc,KAAK;IACtC,CAAC;AACD,WAAO;EACT,CAAC;AACD,SAAO,IAAI,6BAAe,QAAQ;IAChC;IACA,WAAW;IACX,SAAS;IACT;IACA;GACD;AACH;;;AC7HA,IAAAA,eAAiD;;;ACEjD,IAAY;CAAZ,SAAYC,SAAM;AAChB,EAAAA,QAAAA,QAAA,QAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,OAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,WAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,YAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,WAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,gBAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,cAAA,IAAA,CAAA,IAAA;AAEA,EAAAA,QAAAA,QAAA,KAAA,IAAA,CAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,WAAA,IAAA,GAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,qBAAA,IAAA,GAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,UAAA,IAAA,KAAA,IAAA;AAEA,EAAAA,QAAAA,QAAA,QAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,SAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,wBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,uBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,uBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,sBAAA,IAAA,IAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,oBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,gBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,gBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,QAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,eAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,iBAAA,IAAA,KAAA,IAAA;AACA,EAAAA,QAAAA,QAAA,qBAAA,IAAA,KAAA,IAAA;AACF,GA3BY,WAAA,SAAM,CAAA,EAAA;;;ACqBZ,SAAU,eAAe,aAAwB;AACrD,SAAO;IACL,cAAc,uBAAuB,YAAY,KAAK;IACtD,cAAc,uBAAuB,YAAY,KAAK;IACtD,WAAW,wBAAwB,YAAY,SAAS;IACxD,GAAG,wBAAwB,YAAY,SAAS;;AAEpD;AAGA,SAAS,uBACP,MAA+E;AAE/E,UAAQ,MAAM;IACZ,KAAK,OAAO;AACV,aAAO;IACT,KAAK,OAAO;AACV,aAAO;IACT,KAAK,OAAO;AACV,aAAO;IACT;AACE,aAAO;EACX;AACF;AAGA,SAAS,wBACP,MAAgD;AAEhD,UAAQ,MAAM;IACZ,KAAK,OAAO;AACV,aAAO;IACT,KAAK,OAAO;AACV,aAAO;IACT;AACE,aAAO;EACX;AACF;AAGA,SAAS,wBACP,MAOa;AAEb,UAAQ,MAAM;IACZ,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,UAAS;IAC9B,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,SAAQ;IAC7B,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,WAAW,cAAc,UAAS;IACvD,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,UAAU,cAAc,UAAS;IACtD,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,WAAW,cAAc,SAAQ;IACtD,KAAK,OAAO;AACV,aAAO,EAAC,WAAW,UAAU,cAAc,SAAQ;IACrD;AACE,aAAO,CAAA;EACX;AACF;;;AC1FA,kBAAsB;AA4CtB,IAAM,qCAA0E;EAC9E,qCAAqC,aAAa,wBAAwB,oBAAoB;IAC5F;IACA;GACD;EACD,qCACE,qBACA,gCACA,4BACA,CAAC,wBAAwB,0BAA0B,CAAC;EAEtD,qCAAqC,UAAU,qBAAqB,iBAAiB;IACnF;GACD;EACD,qCAAqC,aAAa,wBAAwB,oBAAoB;IAC5F;GACD;EACD,qCAAqC,YAAY,uBAAuB,mBAAmB;IACzF;GACD;EACD,qCACE,iBACA,4BACA,+CACA,CAAC,cAAc,0BAA0B,sBAAsB,CAAC;EAElE,qCACE,qBACA,gCACA,0CACA,CAAC,cAAc,0BAA0B,iBAAiB,CAAC;EAE7D,qCACE,gBACA,2BACA,kDACA,CAAC,cAAc,8BAA8B,qBAAqB,CAAC;EAErE,qCACE,aACA,wBACA,yCACA,CAAC,cAAc,wBAAwB,kBAAkB,CAAC;EAE5D,qCACE,aACA,wBACA,4CACA,CAAC,cAAc,2BAA2B,kBAAkB,CAAC;EAE/D,qCACE,sBACA,iCACA,qDACA,CAAC,cAAc,2BAA2B,2BAA2B,CAAC;EAExE,qCACE,mBACA,8BACA,kDACA,CAAC,cAAc,2BAA2B,wBAAwB,CAAC;EAErE,qCACE,cACA,yBACA,yCACA,CAAC,cAAc,uBAAuB,mBAAmB,CAAC;EAE5D,qCACE,kBACA,6BACA,6CACA,CAAC,cAAc,uBAAuB,uBAAuB,CAAC;EAEhE,qCACE,eACA,0BACA,gDACA,CAAC,cAAc,6BAA6B,oBAAoB,CAAC;EAEnE,qCACE,wBACA,mCACA,yDACA,CAAC,cAAc,6BAA6B,6BAA6B,CAAC;EAE5E,qCACE,cACA,yBACA,8CACA,CAAC,cAAc,4BAA4B,mBAAmB,CAAC;;AAInE,IAAM,wCAAwC,IAAI,IAChD,mCAAmC,IAAI,gBAAc,CAAC,WAAW,MAAM,UAAU,CAAC,CAAC;AAGrF,SAAS,qCACP,MACA,SACA,aACA,cAAsB;AAEtB,SAAO;IACL;IACA;IACA;IACA;IACA,cAAc,GAAG;IACjB,oBAAoB,GAAG;;AAE3B;AAEM,SAAU,qCAAkC;AAChD,SAAO;AACT;AAEM,SAAU,kCACd,MAA6B;AAE7B,QAAM,aAAa,sCAAsC,IAAI,IAAI;AACjE,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,sCAAsC,MAAM;EAC9D;AACA,SAAO;AACT;AAUM,SAAU,wBACd,aAA4C;AAzL9C;AA2LE,QAAM,6BAA4B,gDAAc,kBAAd,mBAA8B;AAChE,SAAO;IACL,SAAQ,uEAA2B,UAC/B,CAAC,0BAA0B,OAAO,CAAC,GAAG,0BAA0B,OAAO,CAAC,CAAC,IACzE,CAAC,GAAG,CAAC;IACT,WAAU,uEAA2B,aAAY;IACjD,QAAO,uEAA2B,SAC9B,CAAC,0BAA0B,MAAM,CAAC,GAAG,0BAA0B,MAAM,CAAC,CAAC,IACvE,CAAC,GAAG,CAAC;;AAEb;AAEM,SAAU,4BAA4B,aAA4C;AAvMxF;AAwME,QAAM,6BAA4B,gDAAc,kBAAd,mBAA8B;AAChE,UAAO,uEAA4B,iBAAe,2CAAc,gBAAe;AACjF;AAEM,SAAU,4BACd,iBAAyB;AAEzB,SACE,mCAAmC,KACjC,gBACE,WAAW,aAAa,WAAW,gBAAgB,UACnD,WAAW,aAAa,MAAM,CAAC,SAAS,UAAU,gBAAgB,KAAK,MAAM,OAAO,CAAC,KACpF;AAET;AAEM,SAAU,0BAA0B,WAA8B;AACtE,QAAM,oBAAoB,IAAI,oBAAO,EAAG,IACtC,GACA,GACA,GACA,GACA,GACA,GACA,UAAU,OAAO,CAAC,GAClB,UAAU,OAAO,CAAC,GAClB,CAAC;AAEH,QAAM,iBAAiB,IAAI,oBAAO,EAAG,IACnC,KAAK,IAAI,UAAU,QAAQ,GAC3B,KAAK,IAAI,UAAU,QAAQ,GAC3B,GACA,CAAC,KAAK,IAAI,UAAU,QAAQ,GAC5B,KAAK,IAAI,UAAU,QAAQ,GAC3B,GACA,GACA,GACA,CAAC;AAEH,QAAM,cAAc,IAAI,oBAAO,EAAG,IAChC,UAAU,MAAM,CAAC,GACjB,GACA,GACA,GACA,UAAU,MAAM,CAAC,GACjB,GACA,GACA,GACA,CAAC;AAGH,SAAO,MAAM,KAAK,kBAAkB,cAAc,cAAc,EAAE,cAAc,WAAW,CAAC;AAC9F;AAEM,SAAU,+BACd,eACA,kBAAqC;AAErC,QAAM,aAAa,IAAI,oBAAQ,0BAA0B,aAAa,CAAC;AACvE,QAAM,gBAAgB,IAAI,oBAAQ,0BAA0B,gBAAgB,CAAC;AAC7E,QAAM,oBAAoB,IAAI,oBAAQ,UAAU,EAAE,OAAM;AACxD,SAAO,MAAM,KAAK,cAAc,cAAc,iBAAiB,CAAC;AAClE;;;AHvFM,SAAU,iBACd,QACA,UACA,YACA,SAAgC;AAEhC,QAAM,iBAAoC;IACxC,SAAS;;MAEP,aAAa;MACb,yBAAyB;;IAE3B,UAAU,CAAA;IACV,UAAU;;MAER,QAAQ,CAAC,GAAG,GAAG,CAAC;;MAEhB,yBAAyB,CAAC,GAAG,CAAC;;;IAEhC,YAAY,CAAA;IACZ,cAAc,CAAA;IACd,mBAAmB,CAAA;;AAIrB,iBAAe,QAAQ,aAAa,IAAI;AAExC,QAAM,EAAC,8BAA6B,IAAI;AACxC,MAAI,+BAA+B;AACjC,mBAAe,SAAS,wBACtB,8BAA8B,kBAAkB;AAClD,mBAAe,SAAS,yBACtB,8BAA8B,mBAAmB;AACnD,mBAAe,SAAS,cAAc,8BAA8B,eAAe;AACnF,mBAAe,SAAS,aAAa;AACrC,mBAAe,SAAS,kBAAkB,CAAC,GAAG,CAAC;EACjD;AAEA,MAAI,mCAAS,UAAU;AACrB,mBAAe,QAAQ,WAAW,IAAI;AAEtC,mBAAe,SAAS,kBAAkB,CAAC,GAAG,GAAG,GAAG,CAAC;AACrD,mBAAe,SAAS,eAAe,CAAC,GAAG,GAAG,GAAG,CAAC;EACpD;AAEA,MAAI,WAAW,QAAQ;AAAG,mBAAe,QAAQ,aAAa,IAAI;AAClE,MAAI,WAAW,SAAS,MAAK,mCAAS;AAAa,mBAAe,QAAQ,cAAc,IAAI;AAC5F,MAAI,WAAW,YAAY;AAAG,mBAAe,QAAQ,QAAQ,IAAI;AACjE,MAAI,WAAW,YAAY;AAAG,mBAAe,QAAQ,UAAU,IAAI;AACnE,MAAI,WAAW,UAAU,KAAK,WAAW,WAAW;AAAG,mBAAe,QAAQ,UAAU,IAAI;AAC5F,MAAI,WAAW,SAAS;AAAG,mBAAe,QAAQ,YAAY,IAAI;AAElE,MAAI,mCAAS;AAA+B,mBAAe,QAAQ,SAAS,IAAI;AAChF,MAAI,mCAAS;AAAQ,mBAAe,QAAQ,YAAY,IAAI;AAE5D,MAAI,UAAU;AACZ,QAAI,QAAQ,uBAAuB,OAAO;AACxC,sCAAgC,UAAU,UAAU;IACtD;AACA,kBAAc,QAAQ,UAAU,gBAAgB,YAAY,QAAQ,IAAI;EAC1E;AAEA,SAAO;AACT;AAEA,SAAS,gCACP,UACA,YAA+B;AAlPjC;AAoPE,QAAM,0BAA0B,2BAA2B,UAAU,CAAC;AACtE,MAAI,wBAAwB,SAAS,KAAK,CAAC,WAAW,YAAY,GAAG;AACnE,qBAAI,KACF,sBAAsB,wBAAwB,KAAK,IAAI,gGAAgG,EACxJ;EACH;AACA,QAAM,2BAA2B,2BAA2B,UAAU,CAAC;AACvE,MAAI,yBAAyB,SAAS,KAAK,CAAC,WAAW,YAAY,GAAG;AACpE,qBAAI,KACF,sBAAsB,yBAAyB,KAAK,IAAI,uFAAuF,EAChJ;EACH;AAEA,QAAM,kBAAkB,QAAQ,SAAS,WAAS,cAAS,eAAT,mBAAqB,oBAAmB;AAC1F,MAAI,mBAAmB,WAAW,QAAQ,GAAG;AAC3C;EACF;AAEA,QAAM,sBAAsB,SAAS,gBACjC,uCACA;AACJ,mBAAI,KACF,gDAAgD,kEAAkE,EACnH;AACH;AAEA,SAAS,2BACP,UACA,sBAA4B;AAE5B,QAAM,0BAAoC,CAAA;AAE1C,aAAW,kBAAkB,mCAAkC,GAAI;AACjE,UAAM,cAAc,qBAAqB,UAAU,eAAe,YAAY;AAC9E,QAAI,CAAC,aAAa;AAChB;IACF;AAEA,QAAI,4BAA4B,WAAW,MAAM,sBAAsB;AACrE,8BAAwB,KAAK,eAAe,WAAW;IACzD;EACF;AAEA,SAAO;AACT;AAEA,SAAS,qBACP,UACA,cAAsB;AAEtB,MAAI,QAAa;AACjB,aAAW,eAAe,cAAc;AACtC,YAAQ,+BAAQ;AAChB,QAAI,CAAC,OAAO;AACV,aAAO;IACT;EACF;AAEA,SAAO;AACT;AAGA,SAAS,cACP,QACA,UACA,gBACA,YACA,MAAwB;AAvT1B;AAyTE,iBAAe,SAAS,QAAQ,QAC9B,SAAS,WAAS,cAAS,eAAT,mBAAqB,oBAAmB;AAG5D,MAAI,SAAS,sBAAsB;AACjC,8BACE,QACA,SAAS,sBACT,gBACA,YACA,IAAI;EAER;AACA,MAAI,SAAS,eAAe;AAC1B,eAAW,QAAQ,SAAS,eAAe,qBAAqB,gBAAgB;MAC9E,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;AAED,UAAM,EAAC,QAAQ,EAAC,IAAI,SAAS;AAC7B,mBAAe,SAAS,cAAc;EACxC;AACA,MAAI,SAAS,kBAAkB;AAC7B,eAAW,QAAQ,SAAS,kBAAkB,wBAAwB,gBAAgB;MACpF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;AAED,UAAM,EAAC,WAAW,EAAC,IAAI,SAAS;AAChC,mBAAe,SAAS,oBAAoB;EAC9C;AACA,iBAAe,SAAS,iBAAiB,SAAS,kBAAkB,CAAC,GAAG,GAAG,CAAC;AAC5E,MAAI,SAAS,iBAAiB;AAC5B,eAAW,QAAQ,SAAS,iBAAiB,uBAAuB,gBAAgB;MAClF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AAEA,0BAAwB,QAAQ,SAAS,YAAY,gBAAgB,MAAM,UAAU;AAErF,UAAQ,SAAS,aAAa,UAAU;IACtC,KAAK;AACH;IACF,KAAK,QAAQ;AACX,YAAM,EAAC,cAAc,IAAG,IAAI;AAC5B,qBAAe,QAAQ,cAAc,IAAI;AACzC,qBAAe,SAAS,qBAAqB;AAC7C,qBAAe,SAAS,cAAc;AACtC;IACF;IACA,KAAK;AACH,uBAAI,KAAK,2EAA2E,EAAC;AACrF,gCAA0B,cAAc;AAExC;EACJ;AACF;AAEA,SAAS,0BAA0B,gBAAiC;AAClE,iBAAe,WAAW,QAAQ;AAClC,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAEhD,iBAAe,aAAa,OAAO,IAAI;AACvC,iBAAe,aAAa,eAAe,IAAI,OAAO;AACtD,iBAAe,aAAa,WAAW,IAAI;IACzC,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;;AAEX;AAEA,SAAS,oCAAoC,gBAAiC;AAC5E,iBAAe,WAAW,QAAQ;AAClC,iBAAe,WAAW,oBAAoB;AAC9C,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAChD,iBAAe,WAAW,sBAAsB;AAEhD,iBAAe,aAAa,OAAO,IAAI;AACvC,iBAAe,aAAa,WAAW,IAAI;AAC3C,iBAAe,aAAa,eAAe,IAAI,OAAO;AACtD,iBAAe,aAAa,WAAW,IAAI;IACzC,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;;AAEX;AAGA,SAAS,0BACP,QACA,sBACA,gBACA,YACA,MAAwB;AAExB,MAAI,qBAAqB,kBAAkB;AACzC,eACE,QACA,qBAAqB,kBACrB,wBACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EAEL;AACA,iBAAe,SAAS,kBAAkB,qBAAqB,mBAAmB,CAAC,GAAG,GAAG,GAAG,CAAC;AAE7F,MAAI,qBAAqB,0BAA0B;AACjD,eACE,QACA,qBAAqB,0BACrB,gCACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EAEL;AACA,QAAM,EAAC,iBAAiB,GAAG,kBAAkB,EAAC,IAAI;AAClD,iBAAe,SAAS,0BAA0B,CAAC,gBAAgB,eAAe;AACpF;AAEA,SAAS,wBACP,QACA,YACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,YAAY;AACf;EACF;AAEA,MAAI,4BAA4B,UAAU,GAAG;AAC3C,mBAAe,QAAQ,yBAAyB,IAAI;EACtD;AAEA,yBACE,QACA,WAAW,wBACX,gBACA,MACA,UAAU;AAEZ,oBAAkB,WAAW,mBAAmB,cAAc;AAC9D,6BACE,QACA,WAAW,4BACX,gBACA,MACA,UAAU;AAEZ,uBAAqB,QAAQ,WAAW,sBAAsB,gBAAgB,MAAM,UAAU;AAC9F,0BACE,QACA,WAAW,yBACX,gBACA,MACA,UAAU;AAEZ,sBAAoB,QAAQ,WAAW,qBAAqB,gBAAgB,MAAM,UAAU;AAC5F,4BACE,QACA,WAAW,2BACX,gBACA,MACA,UAAU;AAEZ,2BACE,QACA,WAAW,0BACX,gBACA,MACA,UAAU;AAEZ,iCAA+B,WAAW,iCAAiC,cAAc;AAC3F;AAEA,SAAS,4BAA4B,YAAkC;AACrE,SAAO,QACL,WAAW,0BACT,WAAW,qBACX,WAAW,8BACX,WAAW,wBACX,WAAW,2BACX,WAAW,uBACX,WAAW,6BACX,WAAW,wBAAwB;AAEzC;AAEA,SAAS,uBACP,QACA,WACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,qBAAqB;AACjC,mBAAe,SAAS,sBAAsB,UAAU;EAC1D;AACA,MAAI,UAAU,mBAAmB,QAAW;AAC1C,mBAAe,SAAS,0BAA0B,UAAU;EAC9D;AACA,MAAI,UAAU,sBAAsB;AAClC,eAAW,QAAQ,UAAU,sBAAsB,4BAA4B,gBAAgB;MAC7F,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AACA,MAAI,UAAU,iBAAiB;AAC7B,eAAW,QAAQ,UAAU,iBAAiB,gCAAgC,gBAAgB;MAC5F,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AACF;AAEA,SAAS,kBACP,WACA,gBAAiC;AAEjC,OAAI,uCAAW,SAAQ,QAAW;AAChC,mBAAe,SAAS,MAAM,UAAU;EAC1C;AACF;AAEA,SAAS,2BACP,QACA,WACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,uBAAuB,QAAW;AAC9C,mBAAe,SAAS,qBAAqB,UAAU;EACzD;AACA,MAAI,UAAU,qBAAqB;AACjC,eAAW,QAAQ,UAAU,qBAAqB,2BAA2B,gBAAgB;MAC3F,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AAEA,OAAK,UAAU,sBAAsB,KAAK,KAAK,UAAU,qBAAqB;AAC5E,qBAAI,KACF,2GAA2G,EAC5G;AACD,wCAAoC,cAAc;EACpD;AACF;AAEA,SAAS,qBACP,QACA,WACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,oBAAoB,QAAW;AAC3C,mBAAe,SAAS,kBAAkB,UAAU;EACtD;AACA,MAAI,UAAU,kBAAkB;AAC9B,eAAW,QAAQ,UAAU,kBAAkB,wBAAwB,gBAAgB;MACrF,gBAAgB;QACd,QAAQ;;MAEV;MACA;MACA,sBAAsB;KACvB;EACH;AACA,MAAI,UAAU,wBAAwB,QAAW;AAC/C,mBAAe,SAAS,sBAAsB,UAAU;EAC1D;AACA,MAAI,UAAU,kBAAkB;AAC9B,mBAAe,SAAS,mBAAmB,UAAU;EACvD;AACF;AAEA,SAAS,wBACP,QACA,WACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,oBAAoB,QAAW;AAC3C,mBAAe,SAAS,kBAAkB,UAAU;EACtD;AACA,MAAI,UAAU,6BAA6B,QAAW;AACpD,mBAAe,SAAS,2BAA2B,UAAU;EAC/D;AACA,MAAI,UAAU,kBAAkB;AAC9B,eAAW,QAAQ,UAAU,kBAAkB,wBAAwB,gBAAgB;MACrF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AACA,MAAI,UAAU,2BAA2B;AACvC,eACE,QACA,UAAU,2BACV,iCACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EAEL;AACA,MAAI,UAAU,wBAAwB;AACpC,eACE,QACA,UAAU,wBACV,8BACA,gBACA;MACE,gBAAgB;QACd,QAAQ;;MAEV;MACA;MACA,sBAAsB;KACvB;EAEL;AACF;AAEA,SAAS,oBACP,QACA,WACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,kBAAkB;AAC9B,mBAAe,SAAS,mBAAmB,UAAU;EACvD;AACA,MAAI,UAAU,yBAAyB,QAAW;AAChD,mBAAe,SAAS,uBAAuB,UAAU;EAC3D;AACA,MAAI,UAAU,mBAAmB;AAC/B,eAAW,QAAQ,UAAU,mBAAmB,yBAAyB,gBAAgB;MACvF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AACA,MAAI,UAAU,uBAAuB;AACnC,eACE,QACA,UAAU,uBACV,6BACA,gBACA;MACE,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EAEL;AACF;AAEA,SAAS,0BACP,QACA,WACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,sBAAsB,QAAW;AAC7C,mBAAe,SAAS,oBAAoB,UAAU;EACxD;AACA,MAAI,UAAU,mBAAmB,QAAW;AAC1C,mBAAe,SAAS,iBAAiB,UAAU;EACrD;AACA,MACE,UAAU,gCAAgC,UAC1C,UAAU,gCAAgC,QAC1C;AACA,mBAAe,SAAS,4BAA4B;MAClD,UAAU,+BAA+B;MACzC,UAAU,+BAA+B;;EAE7C;AACA,MAAI,UAAU,oBAAoB;AAChC,eAAW,QAAQ,UAAU,oBAAoB,0BAA0B,gBAAgB;MACzF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AACA,MAAI,UAAU,6BAA6B;AACzC,eACE,QACA,UAAU,6BACV,mCACA,gBACA;MACE,gBAAgB;QACd,QAAQ;;MAEV;MACA;MACA,sBAAsB;KACvB;EAEL;AACF;AAEA,SAAS,yBACP,QACA,WACA,gBACA,MACA,aAAkC,CAAA,GAAE;AAEpC,MAAI,CAAC,WAAW;AACd;EACF;AAEA,MAAI,UAAU,uBAAuB,QAAW;AAC9C,mBAAe,SAAS,qBAAqB,UAAU;EACzD;AACA,MAAI,UAAU,uBAAuB,QAAW;AAC9C,mBAAe,SAAS,qBAAqB,UAAU;EACzD;AACA,MAAI,UAAU,mBAAmB;AAC/B,eAAW,QAAQ,UAAU,mBAAmB,yBAAyB,gBAAgB;MACvF,gBAAgB;QACd,QAAQ;QACR,oBAAoB;;MAEtB;MACA;MACA,sBAAsB;KACvB;EACH;AACF;AAEA,SAAS,+BACP,WACA,gBAAiC;AAEjC,OAAI,uCAAW,sBAAqB,QAAW;AAC7C,mBAAe,SAAS,mBAAmB,UAAU;EACvD;AACF;AAGA,SAAS,WACP,QACA,aACA,aACA,gBACA,sBAA2C,CAAA,GAAE;AAt2B/C;AAw2BE,QAAM,EAAC,iBAAiB,CAAA,GAAI,MAAM,aAAa,CAAA,GAAI,qBAAoB,IAAI;AAC3E,QAAM,EAAC,QAAQ,mBAAkB,IAAI;AACrC,QAAM,uBAAuB,4BAA4B,WAAkC;AAC3F,MAAI,uBAAuB,GAAG;AAC5B,qBAAI,KACF,YAAY,OAAO,WAAW,aAAa,+FAA+F,EAC3I;AACD;EACF;AACA,MAAI,yBAAyB,KAAK,CAAC,WAAW,YAAY,GAAG;AAC3D,qBAAI,KACF,YAAY,OAAO,WAAW,gFAAgF,EAC/G;AACD;EACF;AAEA,QAAM,sBAAsB,mBAAmB,aAAa,IAAI;AAChE,QAAM,SAAQ,+BAAoB,YAApB,mBAA6B,WAA7B,mBAAqC;AACnD,MAAI,CAAC,OAAO;AACV,qBAAI,KAAK,wCAAwC,OAAO,WAAW,GAAG,EAAC;AACvE;EACF;AAEA,QAAM,cAAc;IAClB,OAAO;;IACP,OAAO;;IACP,WAAW;;IACX,WAAW;;IACX,IAAG,gEAAqB,YAArB,mBAA8B;;AAGnC,QAAM,cAAc;IAClB,IAAI,oBAAoB,eAAe,oBAAoB;IAC3D,SAAS,eAAe,WAAW;;AAGrC,MAAI;AAEJ,MAAI,MAAM,YAAY;AACpB,cAAU,wBAAwB,QAAQ,OAAO,WAAW;EAC9D,OAAO;AACL,UAAM,EAAC,OAAO,OAAM,IAAI,OAAO,qBAAqB,KAAK;AACzD,cAAU,OAAO,cAAc;MAC7B,GAAG;MACH;MACA;MACA,MAAM;KACP;EACH;AAEA,iBAAe,SAAS,WAAW,IAAI;AACvC,MAAI;AAAQ,mBAAe,QAAQ,MAAM,IAAI;AAC7C,MAAI,oBAAoB;AACtB,mBAAe,SAAS,kBAAkB,IAAI;EAChD;AACA,MAAI,sBAAsB;AACxB,UAAM,iCAAiC,kCAAkC,oBAAoB;AAC5F,mBAAe,SAAiC,+BAA+B,YAAY,IAC1F;AACD,mBAAe,SACd,+BAA+B,kBAAkB,IAC/C,0BAA0B,wBAAwB,WAAkC,CAAC;EAC3F;AACA,iBAAe,kBAAkB,KAAK,OAAO;AAC/C;AAEA,SAAS,mBAAmB,aAA0B,MAAwB;AAC5E,MAAI,YAAY,WAAW,YAAY,UAAU,UAAa,EAAC,6BAAM,WAAU;AAC7E,WAAO;EACT;AAEA,QAAM,uBAAuB,KAAK,SAAS,YAAY,KAAK;AAI5D,MAAI,CAAC,sBAAsB;AACzB,WAAO;EACT;AAEA,MAAI,aAAa,wBAAwB,qBAAqB,SAAS;AACrE,WAAO;MACL,GAAG;MACH,GAAG;MACH,SAAS,qBAAqB;;EAElC;AAEA,MAAI,EAAE,YAAY,uBAAuB;AACvC,WAAO;EACT;AAEA,SAAO;IACL,GAAG;IACH,SAAS;;AAEb;AAuCA,SAAS,gCACP,QACA,aAAgD;AAEhD,SAAO,OAAO,cAAc;IAC1B,GAAG;IACH,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,WAAW;GACZ;AACH;AAEA,SAAS,+BAA+B,OAAyB;AAC/D,SAAO,MAAM;AACf;AAQA,SAAS,0BACP,WACA,YACA,QAAqB;AAErB,QAAM,EAAC,aAAa,GAAG,cAAc,EAAC,IAAI,kCAAqB,QAAQ,MAAM;AAC7E,MAAI,QAAQ;AACZ,WAAS,IAAI,KAAK,KAAK;AACrB,UAAM,IAAI,KAAK,IAAI,GAAG,aAAa,CAAC;AACpC,UAAM,IAAI,KAAK,IAAI,GAAG,cAAc,CAAC;AACrC,QAAI,IAAI,cAAc,IAAI;AAAa;AACvC;EACF;AACA,SAAO;AACT;AASM,SAAU,wBACd,QACA,OACA,aAAgD;AA/hClD;AAkiCE,MAAI;AAEJ,MAAI,MAAM,QAAS,MAAc,IAAI,OAAM,WAAc,KAAK,CAAC,MAApB,mBAAuB,OAAM;AAEtE,aAAU,MAAmC;EAC/C,WAAW,aAAa,SAAS,MAAM,QAAS,MAAqC,OAAO,GAAG;AAE7F,aAAU,MAAqC;EACjD,OAAO;AACL,aAAS,CAAA;EACX;AAEA,MAAI,OAAO,WAAW,KAAK,GAAC,YAAO,CAAC,MAAR,mBAAW,OAAM;AAC3C,qBAAI,KACF,sFAAsF,EACvF;AACD,WAAO,gCAAgC,QAAQ,WAAW;EAC5D;AAEA,QAAM,YAAY,OAAO,CAAC;AAC1B,QAAM,YAAY,UAAU,SAAU,MAAc,SAAS;AAC7D,QAAM,aAAa,UAAU,UAAW,MAAc,UAAU;AAEhE,MAAI,aAAa,KAAK,cAAc,GAAG;AACrC,qBAAI,KAAK,+EAA+E,EAAC;AACzF,WAAO,gCAAgC,QAAQ,WAAW;EAC5D;AAEA,QAAM,SAAS,+BAA+B,SAAS;AAEvD,MAAI,CAAC,QAAQ;AACX,qBAAI,KAAK,mFAAmF,EAAC;AAC7F,WAAO,gCAAgC,QAAQ,WAAW;EAC5D;AAWA,QAAM,eAAe,0BAA0B,WAAW,YAAY,MAAM;AAC5E,QAAM,aAAa,KAAK,IAAI,OAAO,QAAQ,YAAY;AAEvD,MAAI,kBAAkB;AACtB,WAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,UAAM,QAAQ,OAAO,CAAC;AACtB,QAAI,CAAC,MAAM,QAAQ,MAAM,SAAS,KAAK,MAAM,UAAU,GAAG;AACxD,uBAAI,KAAK,sCAAsC,2CAA2C,EAAC;AAC3F;IACF;AACA,UAAM,cAAc,+BAA+B,KAAK;AACxD,QAAI,eAAe,gBAAgB,QAAQ;AACzC,uBAAI,KACF,sCAAsC,aAAa,mCAAmC,qBAAqB,EAC5G;AACD;IACF;AACA,UAAM,YAAY,KAAK,IAAI,GAAG,aAAa,CAAC;AAC5C,UAAM,YAAY,KAAK,IAAI,GAAG,cAAc,CAAC;AAC7C,QAAI,MAAM,UAAU,aAAa,MAAM,WAAW,WAAW;AAC3D,uBAAI,KACF,sCAAsC,gBAAgB,MAAM,SAAS,MAAM,+BACjD,aAAa,uBAAuB,EAC/D;AACD;IACF;AACA;EACF;AAEA,QAAM,UAAU,OAAO,cAAc;IACnC,GAAG;IACH;IACA,OAAO,qBAAQ,UAAU,qBAAQ;IACjC,OAAO;IACP,QAAQ;IACR,WAAW;IACX,MAAM,UAAU;GACjB;AAGD,WAAS,IAAI,GAAG,IAAI,iBAAiB,KAAK;AACxC,YAAQ,UAAU,OAAO,CAAC,EAAE,MAAM;MAChC,OAAO,OAAO,CAAC,EAAE;MACjB,QAAQ,OAAO,CAAC,EAAE;MAClB,UAAU;KACX;EACH;AAEA,SAAO;AACT;;;AI/nCA,IAAAC,eAAsB;AAEtB,yBAMO;AAQD,SAAU,gBACd,MACA,UAAkC,CAAA,GAAE;AAlBtC;AAoBE,QAAM;;IAEH,KAA8C,YAC/C,gBAAK,eAAL,mBAAkB,2BAAlB,mBAA2C;;AAC7C,MAAI,CAAC,aAAa,CAAC,MAAM,QAAQ,SAAS,KAAK,UAAU,WAAW,GAAG;AACrE,WAAO,CAAA;EACT;AAEA,QAAM,SAAkB,CAAA;AACxB,QAAM,iBAAiB,oBAAoB,KAAK,SAAS,CAAA,CAAE;AAC3D,QAAM,sBAAsB,oBAAI,IAAG;AAEnC,aAAW,QAAQ,KAAK,SAAS,CAAA,GAAI;AACnC,UAAM,aACH,KAAkD,WACnD,gBAAK,eAAL,mBAAiB,wBAAjB,mBAAsC;AACxC,QAAI,OAAO,eAAe,UAAU;AAElC;IACF;AACA,UAAM,YAAY,UAAU,UAAU;AACtC,QAAI,CAAC,WAAW;AAEd;IACF;AAEA,UAAM,QAAQ,wBACX,UAAU,SAAS,CAAC,GAAG,GAAG,CAAC,GAC5B,QAAQ,iBAAiB,IAAI;AAE/B,UAAM,YAAY,UAAU,aAAa;AACzC,UAAM,QAAQ,UAAU;AACxB,UAAM,cAAc,mBAAmB,MAAM,gBAAgB,mBAAmB;AAEhF,YAAQ,UAAU,MAAM;MACtB,KAAK;AACH,eAAO,KAAK,sBAAsB,aAAa,OAAO,SAAS,CAAC;AAChE;MACF,KAAK;AACH,eAAO,KAAK,gBAAgB,aAAa,OAAO,WAAW,KAAK,CAAC;AACjE;MACF,KAAK;AACH,eAAO,KAAK,eAAe,aAAa,OAAO,WAAW,OAAO,UAAU,IAAI,CAAC;AAChF;MACF;AAEE;IACJ;EACF;AAEA,SAAO;AACT;AAKA,SAAS,wBACP,OACA,eAAsB;AAEtB,MAAI,eAAe;AACjB,WAAO,MAAM,IAAI,eAAa,YAAY,GAAG;EAC/C;AACA,aAAO,wCAAoB,OAAO,KAAK;AACzC;AAKA,SAAS,gBACP,aACA,OACA,WACA,OAAc;AAEd,QAAM,WAAW,iBAAiB,WAAW;AAE7C,MAAI,cAAkD,CAAC,GAAG,GAAG,CAAC;AAC9D,MAAI,UAAU,UAAa,QAAQ,GAAG;AACpC,kBAAc,CAAC,GAAG,GAAG,KAAK,QAAQ,MAAM;EAC1C;AAEA,SAAO;IACL,MAAM;IACN;IACA;IACA;IACA;;AAEJ;AAKA,SAAS,sBACP,aACA,OACA,WAAiB;AAEjB,QAAM,YAAY,kBAAkB,WAAW;AAE/C,SAAO;IACL,MAAM;IACN;IACA;IACA;;AAEJ;AAKA,SAAS,eACP,aACA,OACA,WACA,OACA,OAA2D,CAAA,GAAE;AAE7D,QAAM,WAAW,iBAAiB,WAAW;AAC7C,QAAM,YAAY,kBAAkB,WAAW;AAE/C,MAAI,cAAkD,CAAC,GAAG,GAAG,CAAC;AAC9D,MAAI,UAAU,UAAa,QAAQ,GAAG;AACpC,kBAAc,CAAC,GAAG,GAAG,KAAK,QAAQ,MAAM;EAC1C;AAEA,SAAO;IACL,MAAM;IACN;IACA;IACA;IACA;IACA;IACA,gBAAgB,KAAK,kBAAkB;IACvC,gBAAgB,KAAK,kBAAkB,KAAK,KAAK;;AAErD;AAKA,SAAS,oBAAoB,OAA8B;AACzD,QAAM,iBAAiB,oBAAI,IAAG;AAE9B,aAAW,QAAQ,OAAO;AACxB,eAAW,aAAa,KAAK,YAAY,CAAA,GAAI;AAC3C,qBAAe,IAAI,UAAU,IAAI,IAAI;IACvC;EACF;AAEA,SAAO;AACT;AAKA,SAAS,mBACP,MACA,gBACA,qBAAyC;AAEzC,QAAM,oBAAoB,oBAAoB,IAAI,KAAK,EAAE;AACzD,MAAI,mBAAmB;AACrB,WAAO;EACT;AAEA,QAAM,cAAc,mBAAmB,IAAI;AAC3C,QAAM,aAAa,eAAe,IAAI,KAAK,EAAE;AAC7C,QAAM,cAAc,aAChB,IAAI,qBACF,mBAAmB,YAAY,gBAAgB,mBAAmB,CAAC,EACnE,cAAc,WAAW,IAC3B;AAEJ,sBAAoB,IAAI,KAAK,IAAI,WAAW;AAC5C,SAAO;AACT;AAKA,SAAS,mBAAmB,MAA2B;AACrD,MAAI,KAAK,QAAQ;AACf,WAAO,IAAI,qBAAQ,KAAK,MAAM;EAChC;AAEA,QAAM,SAAS,IAAI,qBAAO;AAE1B,MAAI,KAAK,aAAa;AACpB,WAAO,UAAU,KAAK,WAAW;EACnC;AAEA,MAAI,KAAK,UAAU;AACjB,WAAO,cAAc,IAAI,qBAAO,EAAG,eAAe,KAAK,QAAQ,CAAC;EAClE;AAEA,MAAI,KAAK,OAAO;AACd,WAAO,MAAM,KAAK,KAAK;EACzB;AAEA,SAAO;AACT;AAKA,SAAS,iBAAiB,aAAoB;AAC5C,SAAO,YAAY,iBAAiB,CAAC,GAAG,GAAG,CAAC,CAAC;AAC/C;AAKA,SAAS,kBAAkB,aAAoB;AAC7C,SAAO,YAAY,mBAAmB,CAAC,GAAG,GAAG,EAAE,CAAC;AAClD;;;ACvOA,IAAAC,iBAQO;AAOP,IAAAC,sBAA0B;;;ACZpB,SAAU,4BACd,UAOuB;AAGvB,UAAQ,UAAU;IAChB,KAAK,OAAO;AAAQ,aAAO;IAC3B,KAAK,OAAO;AAAO,aAAO;IAC1B,KAAK,OAAO;AAAY,aAAO;IAC/B,KAAK,OAAO;AAAW,aAAO;IAC9B,KAAK,OAAO;AAAgB,aAAO;IACnC;AAAS,YAAM,IAAI,MAAM,OAAO,QAAQ,CAAC;EAC3C;AACF;;;ACvBA,IAAAC,eASO;AACP,IAAAC,iBAA6B;AAC7B,IAAAC,sBAAgC;AAChC,IAAAD,iBAOO;AAGP,IAAM;;EAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiG1B,IAAM;;EAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiEtB,IAAM;;EAAgB;;;;;;;;;AAgChB,SAAU,mBAAmB,QAAgB,SAAkC;AACnF,QAAM,kBACJ,QAAQ,mBAAmB,IAAI,+BAAgB,QAAQ,EAAC,SAAS,CAAC,+BAAW,EAAC,CAAC;AAEjF,QAAM,mBAAmB,EAAC,GAAG,QAAQ,mBAAmB,SAAQ;AAChE,SAAO,iBAAiB;AACxB,QAAM,mBAAmB,OAAO,YAC9B,OAAO,QAAQ;IACb,GAAG;IACH,GAAG,QAAQ,mBAAmB;GAC/B,EAAE,OACD,CAAC,CAAC,MAAM,KAAK,MAAM,gBAAgB,YAAY,IAAI,KAAK,0BAA0B,KAAK,CAAC,CACzF;AAGH,QAAM,WAAW,gBAAgB,eAAe;IAC9C,IAAI,QAAQ;IACZ,UAAU;GACX;AACD,WAAS,SAAS,EAAC,aAAa,iBAAgB,CAAC;AAEjD,SAAO;AACT;AAGM,SAAU,gBAAgB,QAAgB,SAA+B;AAC7E,QAAM,EAAC,IAAI,UAAU,oBAAoB,aAAa,eAAe,CAAA,EAAE,IAAI;AAE3E,mBAAI,KAAK,GAAG,6BAA6B,mBAAmB,OAAO,EAAC;AAKpE,QAAM,mBAA0B,CAAA;AAIhC,QAAM,aAAuC;IAC3C,mBAAmB;IACnB,cAAc;IACd,aAAa;IACb,UAAU;;AAGZ,QAAM,aAAyB;IAC7B;IACA,QAAQ;IACR;IACA;IACA;IACA,UAAU,SAAS;IACnB;IACA,SAAS,CAAC,iCAAa,wBAAI;IAC3B,GAAG;IAEH,SAAS,EAAC,GAAG,mBAAmB,SAAS,GAAG,aAAa,QAAO;IAChE,YAAY,EAAC,GAAG,YAAY,GAAG,mBAAmB,YAAY,GAAG,aAAa,WAAU;;AAG1F,QAAM,WACJ,QAAQ,YACR,mBAAmB,QAAQ;IACzB,IAAI,KAAK,GAAG,gBAAgB;IAC5B;GACD;AACH,aAAW,WAAW;AAEtB,QAAM,QAAQ,IAAI,qBAAM,QAAQ,UAAU;AAE1C,QAAM,yBAAyB;IAC7B,GAAG,mBAAmB;IACtB,GAAG,aAAa;IAChB,GAAG,mBAAmB;IACtB,GAAG,aAAa;;AAElB,QAAM,wBAAwB,yBAC5B,MAAM,aAAa,WAAU,GAC7B,UACA,sBAAsB;AAExB,QAAM,aAAa,SAAS,qBAAqB;AACjD,SAAO,IAAI,yBAAU,EAAC,kBAAkB,MAAK,CAAC;AAChD;AAEA,SAAS,0BAA0B,OAAc;AAC/C,SACE,iBAAiB,uBACjB,iBAAiB,iCACjB,iBAAiB,wBACjB,iBAAiB,wBACjB,iBAAiB;AAErB;AAEA,SAAS,yBACP,SAKA,UACA,mBAA0C;AAE1C,QAAM,0BAA0B,oBAAI,IAAG;AACvC,aAAWE,WAAU,SAAS;AAC5B,eAAW,eAAe,OAAO,KAAKA,QAAO,gBAAgB,CAAA,CAAE,GAAG;AAChE,8BAAwB,IAAI,aAAaA,QAAO,IAAI;IACtD;AACA,eAAW,WAAWA,QAAO,iBAAiB,CAAA,GAAI;AAChD,8BAAwB,IAAI,QAAQ,MAAMA,QAAO,IAAI;IACvD;EACF;AAEA,QAAM,wBAAiE,CAAA;AACvE,aAAW,CAAC,cAAc,KAAK,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AACrE,QAAI,UAAU,QAAW;AACvB;IACF;AAEA,UAAM,aAAa,wBAAwB,IAAI,YAAY;AAC3D,QAAI,CAAC,cAAc,SAAS,WAAW,UAAU,GAAG;AAClD;IACF;AAEA,0BAAsB,UAAU,MAAM,CAAA;AACtC,0BAAsB,UAAU,EAAE,YAAY,IAAI;EACpD;AAEA,SAAO;AACT;;;AFjTA,IAAM,iBAA6C;EACjD,cAAc,CAAA;EACd,UAAU;EACV,+BAA+B;EAC/B,QAAQ;EACR,aAAa;EACb,eAAe;;AAOX,SAAU,UACd,QACA,MACA,UAA4B,CAAA,GAAE;AAa9B,QAAM,kBAAkB,EAAC,GAAG,gBAAgB,GAAG,QAAO;AACtD,QAAM,kBAAkB,IAAI,+BAAgB,QAAQ,EAAC,SAAS,CAAC,+BAAW,EAAC,CAAC;AAC5E,QAAM,aAAa,KAAK,aAAa,CAAA,GAAI,IAAI,CAAC,cAAc,kBAC1D,mBAAmB,QAAQ;IACzB,IAAI,kBAAkB,cAAc,aAAa;IACjD,oBAAoB,iBAClB,QACA,cACA,CAAA,GACA;MACE,GAAG;MACH;MACA,oBAAoB;KACrB;IAEH;GACD,CAAC;AAEJ,QAAM,8BAA8B,oBAAI,IAAG;AAC3C,GAAC,KAAK,aAAa,CAAA,GAAI,QAAQ,CAAC,cAAc,kBAAiB;AAC7D,gCAA4B,IAAI,aAAa,IAAI,UAAU,aAAa,CAAC;EAC3E,CAAC;AAED,QAAM,sBAAsB,oBAAI,IAAG;AACnC,OAAK,OAAO,QAAQ,CAAC,UAAU,QAAO;AACpC,UAAM,UAAU,sBACd,QACA,UACA,MACA,6BACA,eAAe;AAEjB,wBAAoB,IAAI,SAAS,IAAI,OAAO;EAC9C,CAAC;AAED,QAAM,yBAAyB,oBAAI,IAAG;AACtC,QAAM,sBAAsB,oBAAI,IAAG;AAEnC,OAAK,MAAM,QAAQ,CAAC,UAAU,QAAO;AACnC,UAAM,UAAU,sBAAsB,QAAQ,UAAU,eAAe;AACvE,2BAAuB,IAAI,KAAK,OAAO;AACvC,wBAAoB,IAAI,SAAS,IAAI,OAAO;EAC9C,CAAC;AAID,OAAK,MAAM,QAAQ,CAAC,UAAU,QAAO;AACnC,2BAAuB,IAAI,GAAG,EAAG,KAC9B,SAAS,YAAY,CAAA,GAAI,IAAI,CAAC,EAAC,GAAE,MAAK;AACrC,YAAM,QAAQ,oBAAoB,IAAI,EAAE;AACxC,UAAI,CAAC;AAAO,cAAM,IAAI,MAAM,qBAAqB,cAAc,KAAK;AACpE,aAAO;IACT,CAAC,CAAC;AAIJ,QAAI,SAAS,MAAM;AACjB,YAAM,OAAO,oBAAoB,IAAI,SAAS,KAAK,EAAE;AACrD,UAAI,CAAC,MAAM;AACT,cAAM,IAAI,MAAM,0BAA0B,SAAS,KAAK,cAAc,KAAK;MAC7E;AACA,6BAAuB,IAAI,GAAG,EAAG,IAAI,IAAI;IAC3C;EACF,CAAC;AAED,QAAM,SAAS,KAAK,OAAO,IAAI,eAAY;AACzC,UAAM,YAAY,UAAU,SAAS,CAAA,GAAI,IAAI,CAAC,EAAC,GAAE,MAAK;AACpD,YAAM,QAAQ,oBAAoB,IAAI,EAAE;AACxC,UAAI,CAAC;AACH,cAAM,IAAI,MAAM,qBAAqB,eAAe,UAAU,QAAQ,UAAU,IAAI;AACtF,aAAO;IACT,CAAC;AACD,WAAO,IAAI,yBAAU;MACnB,IAAI,UAAU,QAAQ,UAAU;MAChC;KACD;EACH,CAAC;AAED,SAAO,EAAC,QAAQ,WAAW,qBAAqB,qBAAqB,uBAAsB;AAC7F;AAGA,SAAS,sBACP,QACA,UACA,SAAmC;AAEnC,SAAO,IAAI,yBAAU;IACnB,IAAI,SAAS,QAAQ,SAAS;IAC9B,UAAU,CAAA;IACV,QAAQ,SAAS;IACjB,UAAU,SAAS;IACnB,UAAU,SAAS;IACnB,OAAO,SAAS;GACjB;AACH;AAGA,SAAS,sBACP,QACA,UACA,MACA,6BACA,SAAmC;AAEnC,QAAM,iBAAiB,SAAS,cAAc,CAAA;AAC9C,QAAM,aAAa,eAAe,IAAI,CAAC,eAAe,MACpD,2BAA2B;IACzB;IACA;IACA,gBAAgB;IAChB;IACA;IACA;IACA;GACD,CAAC;AAEJ,QAAM,OAAO,IAAI,yBAAU;IACzB,IAAI,SAAS,QAAQ,SAAS;IAC9B,UAAU;GACX;AAED,SAAO;AACT;AAcA,SAAS,2BAA2B,EAClC,QACA,eACA,gBACA,UACA,MACA,6BACA,QAAO,GAC2B;AAClC,QAAM,KAAK,cAAc,QAAQ,GAAG,SAAS,QAAQ,SAAS,gBAAgB;AAC9E,QAAM,WAAW,4BAA4B,cAAc,QAAQ,CAAC;AACpE,QAAM,cAAc,cAAc,UAC9B,cAAc,QAAQ,QACtB,eAAe,cAAc,UAAU;AAE3C,QAAM,WAAW,eAAe,IAAI,eAAe,QAAQ;AAE3D,QAAM,qBAAqB,iBAAiB,QAAQ,cAAc,UAAU,SAAS,YAAY;IAC/F,GAAG;IACH;GACD;AAED,QAAM,YAAY,gBAAgB,QAAQ;IACxC;IACA;IACA,UAAU,cAAc,WACpB,4BAA4B,IAAI,cAAc,SAAS,EAAE,KAAK,OAC9D;IACJ;IACA,cAAc,QAAQ;IACtB;GACD;AAED,YAAU,SAAS,CAAC,cAAc,WAAW,SAAS,KAAK,cAAc,WAAW,SAAS,GAAG;AAIhG,SAAO;AACT;AAGA,SAAS,eAAe,YAAe;AACrC,MAAI,cAAc;AAClB,aAAW,aAAa,OAAO,OAAO,UAAU,GAAG;AACjD,QAAI,WAAW;AACb,YAAM,EAAC,OAAO,MAAM,WAAU,IAAI;AAClC,YAAM,gBAAgB,QAAQ;AAC9B,WAAI,+BAAO,YAAW,UAAa,iBAAiB,GAAG;AACrD,sBAAc,KAAK,IAAI,aAAa,MAAM,SAAS,aAAa;MAClE;IACF;EACF;AACA,MAAI,CAAC,OAAO,SAAS,WAAW,GAAG;AACjC,UAAM,IAAI,MAAM,kDAAkD;EACpE;AACA,SAAO;AACT;AAGA,SAAS,eAAe,IAAY,eAAoB,UAA2B;AA7QnF;AA8QE,QAAM,aAAgD,CAAA;AACtD,aAAW,CAAC,eAAe,SAAS,KAAK,OAAO,QAAQ,cAAc,UAAU,GAAG;AACjF,UAAM,EAAC,YAAY,MAAM,OAAO,WAAU,IAAI;AAE9C,eAAW,aAAa,IAAI,EAAC,MAAM,QAAQ,YAAY,OAAO,WAAU;EAC1E;AAEA,SAAO,IAAI,wBAAS;IAClB;IACA;IACA,UAAS,mBAAc,YAAd,mBAAuB;IAChC;GACD;AACH;AAEA,SAAS,kBAAkB,cAAyC,eAAqB;AACvF,SAAO,aAAa,QAAQ,aAAa,MAAM,YAAY;AAC7D;;;AG3RA,IAAAC,eAAkB;;;ACJlB,IAAAC,eAAkB;AAClB,IAAAA,eAAyB;AAKzB,SAAS,iBACP,QACA,MACA,UAAkB;AAElB,UAAQ,MAAM;IACZ,KAAK;AACH,aAAO,OAAO,YAAY,QAAQ,EAAE,aAAY;IAElD,KAAK;AACH,aAAO,OAAO,YAAY,QAAQ,EAAE,aAAY;IAElD,KAAK;AACH,aAAO,OAAO,SAAS,QAAQ,EAAE,aAAY;IAE/C;AACE,uBAAI,KAAK,sBAAsB,MAAM,EAAC;AACtC,aAAO;EACX;AACF;AAGM,SAAU,YACd,MACA,EAAC,OAAO,eAAe,OAAM,GAC7B,QACA,MAAuB;AAEvB,QAAM,QAAQ,gBAAgB,MAAM,EAAC,OAAO,eAAe,OAAM,GAAG,IAAI;AACxE,MAAI,OAAO;AACT,qBAAiB,QAAQ,MAAM,KAAK;EACtC;AACF;AAGM,SAAU,gBACd,MACA,EAAC,OAAO,eAAe,OAAM,GAC7B,MAAwB;AAExB,QAAM,UAAU,MAAM,MAAM,SAAS,CAAC;AACtC,MAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW,GAAG;AAC7C,WAAO,OAAO,CAAC,KAAK;EACtB;AAEA,QAAM,gBAAgB,OAAO;AAE7B,QAAM,YAAY,MAAM,UAAU,OAAK,KAAK,aAAa;AACzD,MAAI,YAAY,GAAG;AACjB,WAAO,OAAO,OAAO,SAAS,CAAC,KAAK;EACtC;AACA,QAAM,gBAAgB,KAAK,IAAI,GAAG,YAAY,CAAC;AAE/C,QAAM,eAAe,MAAM,aAAa;AACxC,QAAM,WAAW,MAAM,SAAS;AAEhC,UAAQ,eAAe;IACrB,KAAK;AACH,aAAO,OAAO,aAAa;IAE7B,KAAK;AACH,UAAI,WAAW,cAAc;AAC3B,cAAM,SAAS,gBAAgB,iBAAiB,WAAW;AAC3D,eAAO,kBAAkB,MAAM,OAAO,aAAa,GAAG,OAAO,SAAS,GAAG,KAAK;MAChF;AACA,aAAO,OAAO,aAAa,KAAK;IAElC,KAAK;AACH,UAAI,WAAW,cAAc;AAC3B,cAAM,SAAS,gBAAgB,iBAAiB,WAAW;AAC3D,cAAM,QAAQ,WAAW;AAEzB,cAAM,KAAK,OAAO,IAAI,gBAAgB,CAAC;AACvC,cAAM,cAAc,OAAO,IAAI,gBAAgB,CAAC;AAChD,cAAM,aAAa,OAAO,IAAI,YAAY,CAAC;AAC3C,cAAM,KAAK,OAAO,IAAI,YAAY,CAAC;AAEnC,eAAO,uBAAuB,EAAC,IAAI,aAAa,YAAY,IAAI,OAAO,MAAK,CAAC;MAC/E;AACA,aAAO,OAAO,IAAI,gBAAgB,CAAC,KAAK;IAE1C;AACE,uBAAI,KAAK,iBAAiB,6BAA6B,EAAC;AACxD,aAAO;EACX;AACF;AAGA,SAAS,kBACP,MACA,OACA,MACA,OAAa;AAEb,MAAI,SAAS,YAAY;AAEvB,WAAO,IAAI,wBAAU,EAAG,MAAM,EAAC,OAAO,QAAQ,MAAM,MAAK,CAAC;EAC5D;AAEA,QAAM,SAAS,CAAA;AACf,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,WAAO,CAAC,IAAI,QAAQ,KAAK,CAAC,KAAK,IAAI,SAAS,MAAM,CAAC;EACrD;AACA,SAAO;AACT;AAGA,SAAS,uBAAuB,EAC9B,IACA,aACA,YACA,IACA,OACA,OAAO,EAAC,GAQT;AAEC,QAAM,SAAS,CAAA;AACf,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAClC,UAAM,KAAK,YAAY,CAAC,IAAI;AAC5B,UAAM,KAAK,WAAW,CAAC,IAAI;AAC3B,WAAO,CAAC,KACL,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,KACnD,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,MAC3C,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,GAAG,CAAC,KAAK,GAAG,CAAC,KAChD,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,KAAK;EACxC;AACA,SAAO;AACT;;;ADvGA,IAAM,qBAAN,MAAwB;;EAEtB;;EAEA;;EAEA;;EAEA,YAAoB;;EAEpB,UAAmB;;EAEnB,QAAgB;;EAEhB,gCAAgC,oBAAI,IAAG;;EAMvC,YAAY,OAA8B;AACxC,SAAK,YAAY,MAAM;AACvB,SAAK,sBAAsB,MAAM;AACjC,SAAK,YAAY,MAAM,aAAa,CAAA;AACpC,SAAK,UAAU,SAAS;AACxB,WAAO,OAAO,MAAM,KAAK;AAEzB,QACE,KAAK,UAAU,SAAS,KAAK,aAAW,QAAQ,SAAS,MAAM,KAC/D,CAAC,KAAK,UAAU,QAChB;AACA,YAAM,IAAI,MACR,aAAa,KAAK,UAAU,gFAAgF;IAEhH;EACF;;EAGA,QAAQ,QAAc;AACpB,QAAI,CAAC,KAAK,SAAS;AACjB;IACF;AAEA,UAAM,UAAU,SAAS;AACzB,UAAM,QAAQ,UAAU,KAAK,aAAa,KAAK;AAE/C,SAAK,UAAU,SAAS,QAAQ,aAAU;AACxC,UAAI,QAAQ,SAAS,QAAQ;AAC3B,cAAM,EAAC,SAAS,cAAc,KAAI,IAAI;AACtC,cAAM,aAAa,KAAK,oBAAoB,IAAI,YAAY;AAC5D,YAAI,CAAC,YAAY;AACf,gBAAM,IAAI,MAAM,qCAAqC,cAAc;QACrE;AAEA,oBAAY,MAAM,SAAS,YAAY,IAAI;AAC3C;MACF;AAEA,YAAM,WAAW,KAAK,UAAU,QAAQ,mBAAmB;AAC3D,UAAI,CAAC,UAAU;AACb,cAAM,IAAI,MACR,yCAAyC,QAAQ,2BAA2B,QAAQ,SAAS;MAEjG;AAEA,YAAM,QAAQ,gBAAgB,MAAM,QAAQ,OAAO;AACnD,UAAI,OAAO;AACT,YAAI,QAAQ,SAAS,YAAY;AAC/B,sCAA4B,UAAU,SAAS,KAAK;QACtD,OAAO;AACL,8CACE,UACA,SACA,OACA,KAAK,6BAA6B;QAEtC;MACF;IACF,CAAC;EACH;;AAcI,IAAO,eAAP,MAAmB;;EAEvB;;EAGA,YAAY,OAAwB;AAClC,SAAK,aAAa,MAAM,WAAW,IAAI,CAAC,WAAW,UAAS;AAC1D,YAAM,OAAO,UAAU,QAAQ,aAAa;AAC5C,aAAO,IAAI,mBAAmB;QAC5B,qBAAqB,MAAM;QAC3B,WAAW,MAAM;QACjB,WAAW,EAAC,MAAM,UAAU,UAAU,SAAQ;OAC/C;IACH,CAAC;EACH;;EAGA,QAAQ,MAAY;AAClB,qBAAI,KAAK,sEAAsE,EAAC;AAChF,SAAK,QAAQ,IAAI;EACnB;;EAGA,QAAQ,MAAY;AAClB,SAAK,WAAW,QAAQ,eAAa,UAAU,QAAQ,IAAI,CAAC;EAC9D;;EAGA,gBAAa;AACX,WAAO,KAAK;EACd;;AAGF,SAAS,4BACP,UACA,SACA,OAAe;AAEf,QAAMC,eACJ,QAAQ,cAAc,SAClB;IACE,CAAC,QAAQ,QAAQ,GAAG,6BAClB,wBAAwB,UAAU,QAAQ,QAAQ,GAClD,QAAQ,WACR,MAAM,CAAC,CAAC;MAGZ;IACE,CAAC,QAAQ,QAAQ,GAAG,MAAM,WAAW,IAAI,MAAM,CAAC,IAAI;;AAG5D,WAAS,SAAS,EAAC,aAAAA,aAAW,CAAC;AACjC;AAEA,SAAS,wBACP,UACA,UAAuC;AA1LzC;AA4LE,QAAM,gBAAgB,SAAS,aAAa,iBAAgB;AAC5D,QAAM,gBAAe,mBAAc,aAAa,MAA3B,mBAA+B;AACpD,SAAO,MAAM,QAAQ,YAAY,IAAI,CAAC,GAAG,YAAY,IAAI,CAAA;AAC3D;AAEA,SAAS,6BACP,cACA,WACA,WAAiB;AAEjB,QAAM,eAAe,CAAC,GAAG,YAAY;AACrC,eAAa,SAAS,IAAI;AAC1B,SAAO;AACT;AAEA,SAAS,oCACP,UACA,SACA,OACA,+BAGC;AAED,QAAM,iBAAiB,kCAAkC,QAAQ,WAAW;AAC5E,QAAM,mBAAmB,2BACvB,+BACA,UACA,OAAO;AAGT,UAAQ,QAAQ,MAAM;IACpB,KAAK;AACH,UAAI,QAAQ,cAAc,QAAW;AACnC,yBAAiB,OAAO,QAAQ,SAAS,IAAI,MAAM,CAAC;MACtD,OAAO;AACL,yBAAiB,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;MAC/C;AACA;IAEF,KAAK;AACH,uBAAiB,WAAW,MAAM,CAAC;AACnC;IAEF,KAAK;AACH,UAAI,QAAQ,cAAc,QAAW;AACnC,yBAAiB,MAAM,QAAQ,SAAS,IAAI,MAAM,CAAC;MACrD,OAAO;AACL,yBAAiB,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;MAC9C;AACA;EACJ;AAEA,WAAS,SAAS;IAChB,aAAa;MACX,CAAC,eAAe,kBAAkB,GAAG,+BACnC,QAAQ,eACR,gBAAgB;;GAGrB;AACH;AAEA,SAAS,2BACP,+BAIA,UACA,SAA6C;AAE7C,QAAM,gBAAgB,8BAA8B,IAAI,QAAQ,KAAK,CAAA;AACrE,MAAI,wBAAwB,cAAc,QAAQ,WAAW;AAC7D,MAAI,CAAC,uBAAuB;AAC1B,4BAAwB;MACtB,QAAQ,CAAC,GAAG,QAAQ,cAAc,MAAM;MACxC,UAAU,QAAQ,cAAc;MAChC,OAAO,CAAC,GAAG,QAAQ,cAAc,KAAK;;AAExC,kBAAc,QAAQ,WAAW,IAAI;AACrC,kCAA8B,IAAI,UAAU,aAAa;EAC3D;AAEA,SAAO;AACT;;;AE5QA,IAAAC,eAAkB;;;ACkBlB,IAAM,4BAA4D;EAChE,cAAc;EACd,SAAS;;AAGX,IAAM,kCAAkF;EACtF,4BAA4B;IAC1B,cAAc;IACd,SAAS;;EAEX,yBAAyB;IACvB,cAAc;IACd,SAAS;;EAEX,uBAAuB;IACrB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,iCAAiC;IAC/B,cAAc;IACd,SAAS;;EAEX,oBAAoB;IAClB,cAAc;IACd,SAAS;;EAEX,uBAAuB;IACrB,cAAc;IACd,SAAS;;EAEX,kBAAkB;IAChB,cAAc;IACd,SACE;;EAEJ,kBAAkB;IAChB,cAAc;IACd,SACE;;EAEJ,wBAAwB;IACtB,cAAc;IACd,SAAS;;EAEX,mBAAmB;IACjB,cAAc;IACd,SAAS;;EAEX,4BAA4B;IAC1B,cAAc;IACd,SACE;;EAEJ,sBAAsB;IACpB,cAAc;IACd,SAAS;;EAEX,yBAAyB;IACvB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,2BAA2B;IACzB,cAAc;IACd,SACE;;EAEJ,0BAA0B;IACxB,cAAc;IACd,SACE;;EAEJ,qCAAqC;IACnC,cAAc;IACd,SACE;;EAEJ,wBAAwB;IACtB,cAAc;IACd,SAAS;;EAEX,yBAAyB;IACvB,cAAc;IACd,SAAS;;EAEX,qBAAqB;IACnB,cAAc;IACd,SAAS;;EAEX,uBAAuB;IACrB,cAAc;IACd,SACE;;EAEJ,oCAAoC;IAClC,cAAc;IACd,SAAS;;EAEX,0BAA0B;IACxB,cAAc;IACd,SAAS;;EAEX,8BAA8B;IAC5B,cAAc;IACd,SAAS;;EAEX,SAAS;IACP,cAAc;IACd,SAAS;;EAEX,iBAAiB;IACf,cAAc;IACd,SAAS;;EAEX,wBAAwB;IACtB,cAAc;IACd,SAAS;;EAEX,mBAAmB;IACjB,cAAc;IACd,SAAS;;EAEX,UAAU;IACR,cAAc;IACd,SAAS;;;AAIP,SAAU,wBACd,MAAuB;AAEvB,QAAM,iBAAiB,MAAM,KAAK,0BAA0B,IAAI,CAAC,EAAE,KAAI;AACvE,QAAM,0BAA4D,eAAe,IAC/E,mBAAgB;AACd,UAAM,6BACJ,gCAAgC,aAAa,KAAK;AAEpD,WAAO;MACL;MACA;QACE;QACA,WACE,2BAA2B,iBAAiB,cAC5C,2BAA2B,iBAAiB;QAC9C,cAAc,2BAA2B;QACzC,SAAS,2BAA2B;;;EAG1C,CAAC;AAGH,SAAO,IAAI,IAAI,uBAAuB;AACxC;AAEM,SAAU,kCACd,eAAqB;AAErB,SAAO,gCAAgC,aAAa,KAAK;AAC3D;AAEA,SAAS,0BAA0B,MAAuB;AAjM1D;AAkME,QAAM,4BAA4B;AAClC,QAAM,iBAAiB,oBAAI,IAAG;AAE9B,oBAAkB,gBAAgB,KAAK,cAAc;AACrD,oBAAkB,gBAAgB,KAAK,kBAAkB;AACzD,oBAAkB,gBAAgB,0BAA0B,iBAAiB;AAC7E,oBAAkB,gBAAgB,OAAO,KAAK,KAAK,cAAc,CAAA,CAAE,CAAC;AAEpE,QACE,+BAA0B,WAA1B,mBAAkC,YACjC,KAAK,SAAS,CAAA,GAAI,KAAK,UAAQ,WAAW,IAAI,GAC/C;AACA,mBAAe,IAAI,qBAAqB;EAC1C;AAEA,OACG,KAAK,aAAa,CAAA,GAAI,KAAK,cAAW;AAlN3C,QAAAC;AAmNM,UAAM,eAAe;AACrB,WAAO,aAAa,WAASA,MAAA,aAAa,eAAb,gBAAAA,IAAyB;EACxD,CAAC,GACD;AACA,mBAAe,IAAI,qBAAqB;EAC1C;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,gBAA6B,oBAA8B,CAAA,GAAE;AACtF,aAAW,iBAAiB,mBAAmB;AAC7C,mBAAe,IAAI,aAAa;EAClC;AACF;;;ACzNO,IAAM,+BAAuD;EAClE,QAAQ;EACR,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;;AAID,IAAM,oCAAyD;EACpE,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;EACN,MAAM;;AAkBF,SAAU,qBAAqB,UAAsB;AA3C3D;AAiDE,QAAM,YAAY,kCAAkC,SAAS,aAAa;AAC1E,QAAM,aAAa,6BAA6B,SAAS,IAAI;AAC7D,QAAM,SAAS,aAAa,SAAS;AACrC,QAAM,EAAC,QAAQ,aAAa,EAAC,MAAI,cAAS,eAAT,mBAAqB,SAAQ,CAAA;AAE9D,QAAM,aAAa,IAAI,UAAU,QAAQ,cAAc,SAAS,cAAc,IAAI,MAAM;AAExF,SAAO,EAAC,YAAY,WAAU;AAChC;;;AF3BM,SAAU,oBAAoB,MAAuB;AACzD,QAAM,iBAAiB,KAAK,cAAc,CAAA;AAC1C,QAAM,kBAAkB,oBAAI,IAAG;AAC/B,QAAM,kBAAkB,oBAAI,IAAG;AAE/B,SAAO,eAAe,QAAQ,CAAC,WAAW,UAAS;AACjD,UAAM,OAAO,UAAU,QAAQ,aAAa;AAC5C,UAAM,eAAe,oBAAI,IAAG;AAC5B,UAAM,WAAmC,UAAU,SAAS,QAAQ,CAAC,EAAC,SAAS,OAAM,MAAK;AACxF,UAAI,gBAAgB,aAAa,IAAI,OAAO;AAC5C,UAAI,CAAC,eAAe;AAClB,cAAM,cAAc,UAAU,SAAS,OAAO;AAC9C,YAAI,CAAC,aAAa;AAChB,gBAAM,IAAI,MAAM,iCAAiC,SAAS;QAC5D;AACA,cAAM,EAAC,OAAO,gBAAgB,UAAU,OAAM,IAAI;AAClD,wBAAgB;UACd,OAAO,oBAAoB,KAAK,UAAU,KAAK,GAAG,eAAe;UACjE;UACA,QAAQ,oBAAoB,KAAK,UAAU,MAAM,GAAG,eAAe;;AAErE,qBAAa,IAAI,SAAS,aAAa;MACzC;AAEA,YAAM,gBAAgB,sBAAsB,MAAM,QAAQ,aAAa;AACvE,aAAO,gBAAgB,CAAC,aAAa,IAAI,CAAA;IAC3C,CAAC;AAED,WAAO,SAAS,SAAS,CAAC,EAAC,MAAM,SAAQ,CAAC,IAAI,CAAA;EAChD,CAAC;AACH;AAEA,SAAS,sBACP,MACA,QACA,SAA6B;AAE7B,MAAI,OAAO,SAAS,WAAW;AAC7B,WAAO,6BAA6B,MAAM,QAAQ,OAAO;EAC3D;AAEA,QAAM,OAAO,qBAAqB,OAAO,IAAI;AAC7C,MAAI,CAAC,MAAM;AACT,WAAO;EACT;AAEA,QAAM,aAAa,KAAK,MAAM,OAAO,QAAQ,CAAC;AAC9C,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,gCAAgC,OAAO,MAAM;EAC/D;AAEA,SAAO;IACL,MAAM;IACN;IACA,cAAc,WAAW;IACzB;;AAEJ;AAEA,SAAS,6BACP,MACA,QACA,SAA6B;AA5F/B;AA8FE,QAAM,WAAU,kBAAO,eAAP,mBAAoB,6BAApB,mBAA8C;AAC9D,MAAI,OAAO,YAAY,YAAY,CAAC,QAAQ,WAAW,GAAG,GAAG;AAC3D,qBAAI,KAAK,mFAAmF,EAAC;AAC7F,WAAO;EACT;AAEA,QAAM,kBAAkB,iBAAiB,OAAO;AAChD,UAAQ,gBAAgB,CAAC,GAAG;IAC1B,KAAK;AACH,aAAO,iCAAiC,MAAM,iBAAiB,SAAS,OAAO;IAEjF,KAAK;AACH,aAAO,qCAAqC,MAAM,iBAAiB,SAAS,OAAO;IAErF;AACE,sCACE,SACA,qBAAqB,gBAAgB,CAAC,qCAAqC;AAE7E,aAAO;EACX;AACF;AAEA,SAAS,iCACP,MACA,iBACA,SACA,SAAe;AAEf,MAAI,gBAAgB,WAAW,GAAG;AAChC,oCACE,SACA,4EAA4E;AAE9E,WAAO;EACT;AAEA,QAAM,YAAY,OAAO,gBAAgB,CAAC,CAAC;AAC3C,QAAM,aAAa,KAAK,MAAM,SAAS;AACvC,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,CAAC,YAAY;AAC/C,qBAAI,KACF,gCAAgC,uDAAuD,EACxF;AACD,WAAO;EACT;AAEA,QAAM,OAAO,qBAAqB,gBAAgB,CAAC,CAAC;AACpD,MAAI,CAAC,MAAM;AACT,oCACE,SACA,kBAAkB,gBAAgB,CAAC,qCAAqC;AAE1E,WAAO;EACT;AACA,MAAI,SAAS,WAAW;AACtB,qBAAI,KACF,gCAAgC,mFAAmF,EACpH;AACD,WAAO;EACT;AAEA,SAAO;IACL,MAAM;IACN;IACA,cAAc,WAAW;IACzB;;AAEJ;AAEA,SAAS,qCACP,MACA,iBACA,SACA,SAAe;AAEf,MAAI,gBAAgB,SAAS,GAAG;AAC9B,oCACE,SACA,0EAA0E;AAE5E,WAAO;EACT;AAEA,QAAM,gBAAgB,OAAO,gBAAgB,CAAC,CAAC;AAC/C,QAAM,WAAW,KAAK,UAAU,aAAa;AAC7C,MAAI,CAAC,OAAO,UAAU,aAAa,KAAK,CAAC,UAAU;AACjD,qBAAI,KACF,gCAAgC,2DAA2D,EAC5F;AACD,WAAO;EACT;AAEA,QAAM,iBAAiB,+BAA+B,UAAU,gBAAgB,MAAM,CAAC,CAAC;AACxF,MAAI,YAAY,gBAAgB;AAC9B,oCAAgC,SAAS,eAAe,MAAM;AAC9D,WAAO;EACT;AAEA,SAAO;IACL;IACA;IACA,qBAAqB;IACrB,GAAG;;AAEP;AAEA,SAAS,qBAAqB,MAAY;AACxC,UAAQ,MAAM;IACZ,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;AACH,aAAO;IAET;AACE,aAAO;EACX;AACF;AAEA,SAAS,+BACP,UACA,iBAAyB;AAvN3B;AAkOE,QAAM,yBAAyB,uCAAuC,UAAU,eAAe;AAC/F,MAAI,EAAE,YAAY,yBAAyB;AACzC,WAAO;EACT;AACA,MAAI,uBAAuB,WAAW,kCAAkC;AACtE,WAAO;EACT;AAEA,QAAM,cAAc,gBAAgB,KAAK,GAAG;AAE5C,UAAQ,aAAa;IACnB,KAAK;AACH,aAAO,SAAS,sBAAsB,IAClC,EAAC,MAAM,YAAY,UAAU,kBAAiB,IAC9C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,aAAO,SAAS,sBAAsB,IAClC,EAAC,MAAM,YAAY,UAAU,2BAA2B,WAAW,EAAC,IACpE,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,aAAO,SAAS,sBAAsB,IAClC,EAAC,MAAM,YAAY,UAAU,2BAA2B,WAAW,EAAC,IACpE,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,aAAO,SAAS,eAAe,IAC3B,EAAC,MAAM,YAAY,UAAU,cAAa,IAC1C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,aAAO,SAAS,kBAAkB,IAC9B,EAAC,MAAM,YAAY,UAAU,oBAAmB,IAChD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,aAAO,EAAC,MAAM,YAAY,UAAU,iBAAgB;IAEtD,KAAK;AACH,aAAO,EAAC,MAAM,YAAY,UAAU,cAAa;IAEnD,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,6BAC5B,EAAC,MAAM,YAAY,UAAU,0BAAyB,IACtD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,6BAC5B,EAAC,MAAM,YAAY,UAAU,sBAAqB,IAClD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,wBAC5B,EAAC,MAAM,YAAY,UAAU,MAAK,IAClC,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,iCAC5B,EAAC,MAAM,YAAY,UAAU,qBAAoB,IACjD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,2BAC5B,EAAC,MAAM,YAAY,UAAU,kBAAiB,IAC9C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,2BAC5B,EAAC,MAAM,YAAY,UAAU,sBAAqB,IAClD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,2BAC5B,EAAC,MAAM,YAAY,UAAU,mBAAkB,IAC/C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,8BAC5B,EAAC,MAAM,YAAY,UAAU,kBAAiB,IAC9C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,8BAC5B,EAAC,MAAM,YAAY,UAAU,2BAA0B,IACvD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,0BAC5B,EAAC,MAAM,YAAY,UAAU,mBAAkB,IAC/C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,0BAC5B,EAAC,MAAM,YAAY,UAAU,uBAAsB,IACnD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,gCAC5B,EAAC,MAAM,YAAY,UAAU,oBAAmB,IAChD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,gCAC5B,EAAC,MAAM,YAAY,UAAU,iBAAgB,IAC7C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,gCAC5B,EAAC,MAAM,YAAY,UAAU,6BAA6B,WAAW,EAAC,IACtE,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,gCAC5B,EAAC,MAAM,YAAY,UAAU,6BAA6B,WAAW,EAAC,IACtE,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,+BAC5B,EAAC,MAAM,YAAY,UAAU,qBAAoB,IACjD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,+BAC5B,EAAC,MAAM,YAAY,UAAU,qBAAoB,IACjD,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE,KAAK;AACH,eAAO,cAAS,YAAY,MAArB,mBAAyB,sCAC5B,EAAC,MAAM,YAAY,UAAU,mBAAkB,IAC/C,EAAC,QAAQ,oCAAoC,eAAe,EAAC;IAEnE;AACE,aAAO,EAAC,QAAQ,oCAAoC,eAAe,EAAC;EACxE;AACF;AAEA,SAAS,uCACP,UACA,iBAAyB;AAUzB,QAAM,iBAAiB,gBAAgB,YAAY,YAAY;AAC/D,MACE,iBAAiB,KACjB,gBAAgB,iBAAiB,CAAC,MAAM,2BACxC,iBAAiB,GACjB;AACA,WAAO,EAAC,QAAQ,iCAAgC;EAClD;AAEA,QAAM,wBAAwB,4BAC5B,gBAAgB,MAAM,GAAG,cAAc,CAAC;AAE1C,MAAI,CAAC,uBAAuB;AAC1B,WAAO;MACL,QAAQ,yCAAyC,gBAAgB,MAAM,GAAG,cAAc,CAAC;;EAE7F;AAEA,QAAM,cAAc,uBAAuB,UAAU,sBAAsB,YAAY;AACvF,MAAI,CAAC,aAAa;AAChB,WAAO;MACL,QAAQ,6BAA6B,gBAClC,MAAM,GAAG,cAAc,EACvB,KAAK,GAAG;;EAEf;AAEA,QAAM,uBAAuB,gBAAgB,iBAAiB,CAAC;AAC/D,MAAI,yBAAyB,YAAY;AACvC,WAAO;MACL,QACE;;EAEN;AACA,MACE,yBAAyB,YACzB,yBAAyB,cACzB,yBAAyB,SACzB;AACA,WAAO;MACL,QAAQ,mCAAmC;;EAE/C;AAEA,QAAM,mBAAmB,gBAAgB,iBAAiB,CAAC;AAC3D,MAAI,gBAAgB,SAAS,iBAAiB,GAAG;AAC/C,WAAO;MACL,QAAQ,yBAAyB;;EAErC;AAEA,MAAI;AACJ,MAAI,qBAAqB,QAAW;AAClC,gBAAY,OAAO,gBAAgB;AACnC,QAAI,yBAAyB,YAAY;AACvC,aAAO;QACL,QAAQ;;IAEZ;AACA,QAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,KAAK,YAAY,GAAG;AAClE,aAAO;QACL,QAAQ,yBAAyB,yCAAyC;;IAE9E;EACF;AAEA,SAAO;IACL,MAAM;IACN,aAAa,sBAAsB;IACnC,MAAM;IACN;IACA,eAAe,wBAAwB,WAAW;;AAEtD;AAEA,SAAS,uBACP,UACA,cAAsB;AAEtB,MAAI,QAAa;AACjB,aAAW,eAAe,cAAc;AACtC,YAAQ,+BAAQ;AAChB,QAAI,CAAC,OAAO;AACV,aAAO;IACT;EACF;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,SAAe;AACvC,SAAO,QACJ,MAAM,CAAC,EACP,MAAM,GAAG,EACT,IAAI,aAAW,QAAQ,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,CAAC;AACnE;AAEA,SAAS,oCAAoC,iBAAyB;AACpE,QAAM,gBAAgB,wBAAwB,eAAe;AAC7D,MAAI,eAAe;AACjB,UAAM,mBAAmB,kCAAkC,aAAa;AACxE,SAAI,qDAAkB,kBAAiB,QAAQ;AAC7C,aAAO,GAAG,oDAAoD,iBAAiB,QAC5E,OAAO,CAAC,EACR,YAAW,IAAK,iBAAiB,QAAQ,MAAM,CAAC;IACrD;EACF;AAEA,SAAO,mDAAmD,gBAAgB,KAAK,GAAG;AACpF;AAEA,SAAS,yCAAyC,iBAAyB;AACzE,QAAM,gBAAgB,wBAAwB,eAAe;AAC7D,MAAI,eAAe;AACjB,UAAM,mBAAmB,kCAAkC,aAAa;AACxE,SAAI,qDAAkB,kBAAiB,QAAQ;AAC7C,aAAO,GAAG,oDAAoD,iBAAiB,QAC5E,OAAO,CAAC,EACR,YAAW,IAAK,iBAAiB,QAAQ,MAAM,CAAC;IACrD;EACF;AAEA,SAAO,6BAA6B,gBAAgB,KAAK,GAAG;AAC9D;AAEA,SAAS,wBAAwB,iBAAyB;AACxD,QAAM,iBAAiB,gBAAgB,QAAQ,YAAY;AAC3D,QAAM,gBAAgB,gBAAgB,iBAAiB,CAAC;AACxD,SAAO,kBAAkB,KAAK,gBAAgB,gBAAgB;AAChE;AAEA,SAAS,gCAAgC,SAAiB,QAAc;AACtE,mBAAI,KAAK,gCAAgC,mCAAmC,QAAQ,EAAC;AACvF;AAGA,SAAS,oBACP,UACA,eAAuD;AAEvD,MAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B,WAAO,cAAc,IAAI,QAAQ;EACnC;AAEA,QAAM,EAAC,YAAY,OAAO,WAAU,IAAI,qBAAqB,QAAQ;AACrE,SAAO,eAAe,GAAG,mDAAmD;AAC5E,QAAM,SAAS,MAAM,KAAK,KAAK;AAE/B,gBAAc,IAAI,UAAU,MAAM;AAClC,SAAO;AACT;AAGA,SAAS,oBACP,UACA,eAAyD;AAEzD,MAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B,WAAO,cAAc,IAAI,QAAQ;EACnC;AAEA,QAAM,EAAC,YAAY,OAAO,WAAU,IAAI,qBAAqB,QAAQ;AACrE,SAAO,cAAc,GAAG,oDAAoD;AAE5E,QAAM,SAAS,CAAA;AAGf,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,YAAY;AACjD,WAAO,KAAK,MAAM,KAAK,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,CAAC;EACxD;AAEA,gBAAc,IAAI,UAAU,MAAM;AAClC,SAAO;AACT;AAGA,SAAS,OAAO,WAAoB,SAAgB;AAClD,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,OAAO;EACzB;AACF;;;AGnfM,SAAU,0BACd,QACA,MACA,SAA0B;AAE1B,QAAM,EAAC,QAAQ,WAAW,qBAAqB,qBAAqB,uBAAsB,IACxF,UAAU,QAAQ,MAAM,OAAO;AAEjC,QAAM,aAAa,oBAAoB,IAAI;AAC3C,QAAM,WAAW,IAAI,aAAa,EAAC,YAAY,qBAAqB,UAAS,CAAC;AAC9E,QAAM,SAAS,gBAAgB,MAAM,EAAC,gBAAe,mCAAS,kBAAiB,KAAI,CAAC;AACpF,QAAM,mBAAmB,wBAAwB,IAAI;AACrD,QAAM,cAAc,OAAO,IAAI,WAAS,oBAAoB,MAAM,UAAS,CAAE,CAAC;AAC9E,QAAM,cAAc,4BAA4B,WAAW;AAE3D,SAAO;IACL;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;AAEJ;AAEA,SAAS,oBAAoB,QAAmC;AAC9D,MAAI,CAAC,QAAQ;AACX,WAAO;MACL,QAAQ;MACR,QAAQ,CAAC,GAAG,GAAG,CAAC;MAChB,MAAM,CAAC,GAAG,GAAG,CAAC;MACd,QAAQ;MACR,0BAA0B;;EAE9B;AAEA,QAAM,mBAAyE;IAC7E,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;;AAE3C,QAAM,OAAiC;IACrC,iBAAiB,CAAC,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC;IAC9C,iBAAiB,CAAC,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC;IAC9C,iBAAiB,CAAC,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,CAAC;;AAEhD,QAAM,SAAmC;IACvC,iBAAiB,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI;IACnC,iBAAiB,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI;IACnC,iBAAiB,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,IAAI;;AAErC,QAAM,gBAAgB,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI;AAC5D,QAAM,SAAS,KAAK,IAAI,MAAM,KAAK,MAAM,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAK;AAE1E,SAAO;IACL,QAAQ;IACR;IACA;IACA;IACA,0BAA0B,KAAK,IAC5B,KAAK,IAAI,eAAe,IAAK,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC,IAAK,MAC3D,SAAS,GAAG;;AAGlB;AAEA,SAAS,4BAA4B,aAAmC;AACtE,MAAI,iBAA8E;AAElF,aAAW,kBAAkB,aAAa;AACxC,QAAI,CAAC,eAAe,QAAQ;AAC1B;IACF;AAEA,QAAI,CAAC,gBAAgB;AACnB,uBAAiB;QACf,CAAC,GAAG,eAAe,OAAO,CAAC,CAAC;QAC5B,CAAC,GAAG,eAAe,OAAO,CAAC,CAAC;;AAE9B;IACF;AAEA,aAAS,OAAO,GAAG,OAAO,GAAG,QAAQ;AACnC,qBAAe,CAAC,EAAE,IAAI,IAAI,KAAK,IAAI,eAAe,CAAC,EAAE,IAAI,GAAG,eAAe,OAAO,CAAC,EAAE,IAAI,CAAC;AAC1F,qBAAe,CAAC,EAAE,IAAI,IAAI,KAAK,IAAI,eAAe,CAAC,EAAE,IAAI,GAAG,eAAe,OAAO,CAAC,EAAE,IAAI,CAAC;IAC5F;EACF;AAEA,SAAO,oBAAoB,cAAc;AAC3C;",
|
|
6
|
+
"names": ["import_core", "GLEnum", "import_core", "import_engine", "import_shadertools", "import_core", "import_engine", "import_shadertools", "module", "import_core", "import_core", "pbrMaterial", "import_core", "_a"]
|
|
7
7
|
}
|