From 6e1618be8e74feeae9d1a0b1514921cb4cc2674b Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Tue, 11 Apr 2023 18:51:06 -0400 Subject: [PATCH 01/72] Add Skeleton.toJSON Addding a Skeleton.toJSON --- types/three/src/objects/Skeleton.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index b546bf01e..bbc4ad19f 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -112,4 +112,6 @@ export class Skeleton { * Call this method whenever this instance is no longer used in your app. */ dispose(): void; + + toJSON(): any; } From 25e7a7ebe79e4683afb279c36d9208088fbe5bb1 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Tue, 11 Apr 2023 19:00:43 -0400 Subject: [PATCH 02/72] Update Skeleton.d.ts Added Skeleton.fromJson https://github.com/mrdoob/three.js/blob/0fbae6f682f6e13dd9eb8acde02e4f50c0b73935/src/objects/Skeleton.js#L221 --- types/three/src/objects/Skeleton.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index bbc4ad19f..2c377b73d 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -114,4 +114,6 @@ export class Skeleton { dispose(): void; toJSON(): any; + + fromJson(json: any, bones: Record): void; } From 0784960bb2219f97e6f98e42862015afb9665695 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Tue, 11 Apr 2023 19:02:10 -0400 Subject: [PATCH 03/72] Update Skeleton.d.ts Optional parameter https://github.com/mrdoob/three.js/blob/0fbae6f682f6e13dd9eb8acde02e4f50c0b73935/src/objects/Skeleton.js#L15 --- types/three/src/objects/Skeleton.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index 2c377b73d..bdd68ba5d 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -32,7 +32,7 @@ export class Skeleton { * @param bones The array of {@link THREE.Bone | bones}. Default `[]`. * @param boneInverses An array of {@link THREE.Matrix4 | Matrix4s}. Default `[]`. */ - constructor(bones: Bone[], boneInverses?: Matrix4[]); + constructor(bones?: Bone[], boneInverses?: Matrix4[]); /** * {@link http://en.wikipedia.org/wiki/Universally_unique_identifier | UUID} of this object instance. From 41584b5d56e918de4d35d266427eaf90788acd07 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Tue, 11 Apr 2023 20:45:56 -0400 Subject: [PATCH 04/72] Update Skeleton.d.ts --- types/three/src/objects/Skeleton.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index bdd68ba5d..22dc9db4e 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -115,5 +115,5 @@ export class Skeleton { toJSON(): any; - fromJson(json: any, bones: Record): void; + fromJSON(json: any, bones: Record): void; } From d91d774855be5332639ec511c1000a975a5ea969 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:25:07 -0400 Subject: [PATCH 05/72] Update Skeleton.d.ts --- types/three/src/objects/Skeleton.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index 22dc9db4e..464258464 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -113,7 +113,7 @@ export class Skeleton { */ dispose(): void; - toJSON(): any; + toJSON(): unknown; - fromJSON(json: any, bones: Record): void; + fromJSON(json: unknown, bones: Record): void; } From 1c863da8f6bd9717e292f956a4ac9acfbd4f4665 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:38:18 -0400 Subject: [PATCH 06/72] BufferAttributeJSON JSON data for BufferAttribute --- types/three/src/Meta.d.ts | 5 +++++ types/three/src/Three.d.ts | 5 +++++ types/three/src/core/BufferAttribute.d.ts | 27 ++++++++++++++++++----- 3 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 types/three/src/Meta.d.ts diff --git a/types/three/src/Meta.d.ts b/types/three/src/Meta.d.ts new file mode 100644 index 000000000..c03244fae --- /dev/null +++ b/types/three/src/Meta.d.ts @@ -0,0 +1,5 @@ +export interface Meta { + version: Version + type: Type + generator: Generator +} \ No newline at end of file diff --git a/types/three/src/Three.d.ts b/types/three/src/Three.d.ts index 7964c4ee4..8209a5a03 100644 --- a/types/three/src/Three.d.ts +++ b/types/three/src/Three.d.ts @@ -232,3 +232,8 @@ export * from './textures/DepthTexture'; export * from './textures/FramebufferTexture'; export * from './textures/Source'; export * from './textures/Texture'; + +/** + * JSON + */ +export * from "./Meta" \ No newline at end of file diff --git a/types/three/src/core/BufferAttribute.d.ts b/types/three/src/core/BufferAttribute.d.ts index 612b55eae..61fcb75ee 100644 --- a/types/three/src/core/BufferAttribute.d.ts +++ b/types/three/src/core/BufferAttribute.d.ts @@ -2,6 +2,26 @@ import { Usage } from '../constants'; import { Matrix3 } from './../math/Matrix3'; import { Matrix4 } from './../math/Matrix4'; +export interface BufferAttributeJSON { + + readonly type: Type; + + itemSize: number; + + array: ArrayLike; + + normalized: boolean; + + name: string; + + usage: number; + + updateRage: { + offset: number; + count: number; + } +} + /** * This class stores data for an attribute (such as vertex positions, face indices, normals, colors, UVs, and any custom attributes ) * associated with a {@link THREE.BufferGeometry | BufferGeometry}, which allows for more efficient passing of data to the GPU @@ -280,12 +300,7 @@ export class BufferAttribute { /** * Convert this object to three.js to the `data.attributes` part of {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, */ - toJSON(): { - itemSize: number; - type: string; - array: number[]; - normalized: boolean; - }; + toJSON(): BufferAttributeJSON; } /** From 1d18f45f6a964b1d1e020a13ce46eb2e2e0f8f8f Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Wed, 26 Apr 2023 09:40:04 -0400 Subject: [PATCH 07/72] Format --- types/three/src/objects/Skeleton.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index 464258464..228504984 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -112,8 +112,8 @@ export class Skeleton { * Call this method whenever this instance is no longer used in your app. */ dispose(): void; - + toJSON(): unknown; - + fromJSON(json: unknown, bones: Record): void; } From 1eb2b8941d8ce57bf3fc943d0b099bc545a8b641 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:42:26 -0400 Subject: [PATCH 08/72] KeyframeTrackJSON --- types/three/src/animation/KeyframeTrack.d.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/types/three/src/animation/KeyframeTrack.d.ts b/types/three/src/animation/KeyframeTrack.d.ts index 891023fda..65b7ffdc0 100644 --- a/types/three/src/animation/KeyframeTrack.d.ts +++ b/types/three/src/animation/KeyframeTrack.d.ts @@ -4,6 +4,19 @@ import { CubicInterpolant } from './../math/interpolants/CubicInterpolant'; import { Interpolant } from '../math/Interpolant'; import { InterpolationModes } from '../constants'; +export interface KeyframeTrackJSON { + + type: Type; + + name: string; + + times: ArrayLike + + valus: ArrayLike + + interpolation: number; +} + export class KeyframeTrack { /** * @param name @@ -43,5 +56,5 @@ export class KeyframeTrack { optimize(): KeyframeTrack; clone(): this; - static toJSON(track: KeyframeTrack): any; + static toJSON(track: KeyframeTrack): KeyframeTrackJSON; } From 7108a71f7c80024e46466c39b7b41d086402257e Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:45:11 -0400 Subject: [PATCH 09/72] AnimationClipJSON, KeyframeTrackJSON --- types/three/src/animation/AnimationClip.d.ts | 21 ++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/types/three/src/animation/AnimationClip.d.ts b/types/three/src/animation/AnimationClip.d.ts index 60fecdf57..ed484a12d 100644 --- a/types/three/src/animation/AnimationClip.d.ts +++ b/types/three/src/animation/AnimationClip.d.ts @@ -1,8 +1,21 @@ -import { KeyframeTrack } from './KeyframeTrack'; +import { KeyframeTrack, KeyframeTrackJSON } from './KeyframeTrack'; import { Vector3 } from './../math/Vector3'; import { Bone } from './../objects/Bone'; import { AnimationBlendMode } from '../constants'; +export interface AnimationClipJSON { + + readonly uuid: string; + + name: string; + + duration: number; + + blendMode: number; + + tracks: KeyframeTrackJSON[]; +} + export interface MorphTarget { name: string; vertices: Vector3[]; @@ -45,7 +58,7 @@ export class AnimationClip { fps: number, noLoop: boolean, ): AnimationClip[]; - static parse(json: any): AnimationClip; - static parseAnimation(animation: any, bones: Bone[]): AnimationClip; - static toJSON(clip: AnimationClip): any; + static parse(json: AnimationClipJSON): AnimationClip; + static parseAnimation(animation: AnimationClipJSON, bones: Bone[]): AnimationClip; + static toJSON(clip: AnimationClip): AnimationClipJSON; } From 6037546eab1cf67c88097da368d4ec15a5d4c000 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:46:49 -0400 Subject: [PATCH 10/72] QuaternionTuple --- types/three/src/math/Quaternion.d.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/types/three/src/math/Quaternion.d.ts b/types/three/src/math/Quaternion.d.ts index 65a7f4c7b..d1b2d8d4e 100644 --- a/types/three/src/math/Quaternion.d.ts +++ b/types/three/src/math/Quaternion.d.ts @@ -4,6 +4,13 @@ import { Matrix4 } from './Matrix4'; import { BufferAttribute } from '../core/BufferAttribute'; import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute'; +export type QuaternionTuple = [ + x: number, + y: number, + z: number, + w: number +] + /** * Implementation of a quaternion. This is used for rotating things without incurring in the dreaded gimbal lock issue, amongst other advantages. * @@ -120,7 +127,7 @@ export class Quaternion { * @param array the source array or array-like. * @param offset (optional) offset into the array. Default is 0. */ - fromArray(array: number[] | ArrayLike, offset?: number): this; + fromArray(array: QuaternionTuple, offset?: number): this; /** * Returns an array [x, y, z, w], or copies x, y, z and w into the provided array. @@ -128,7 +135,7 @@ export class Quaternion { * @param offset (optional) optional offset into the array. * @return The created or provided array. */ - toArray(array?: number[], offset?: number): number[]; + toArray(array?: number[], offset?: number): QuaternionTuple; /** * Copies x, y, z and w into the provided array-like. @@ -136,7 +143,7 @@ export class Quaternion { * @param offset (optional) optional offset into the array. * @return The provided array-like. */ - toArray(array: ArrayLike, offset?: number): ArrayLike; + toArray(array: ArrayLike, offset?: number): QuaternionTuple; /** * Sets x, y, z, w properties of this quaternion from the attribute. From 10858ad548b543031e4c18fd4c0db0b5c5b30d31 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:48:26 -0400 Subject: [PATCH 11/72] EulerTuple --- types/three/src/math/Euler.d.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/types/three/src/math/Euler.d.ts b/types/three/src/math/Euler.d.ts index 6fec62e3e..a1a1e5c15 100644 --- a/types/three/src/math/Euler.d.ts +++ b/types/three/src/math/Euler.d.ts @@ -4,6 +4,13 @@ import { Vector3 } from './Vector3'; export type EulerOrder = 'XYZ' | 'YXZ' | 'ZXY' | 'ZYX' | 'YZX' | 'XZY'; +export type EulerTuple = [ + x: number, + y: number, + z: number, + order?: EulerOrder +] + export class Euler { constructor(x?: number, y?: number, z?: number, order?: EulerOrder); @@ -38,8 +45,8 @@ export class Euler { setFromVector3(v: Vector3, order?: EulerOrder): Euler; reorder(newOrder: EulerOrder): Euler; equals(euler: Euler): boolean; - fromArray(xyzo: [number, number, number, EulerOrder?, ...any[]]): Euler; - toArray(array?: Array, offset?: number): Array; + fromArray(array: EulerTuple): Euler; + toArray(array?: Partial, offset?: number): EulerTuple; _onChange(callback: () => void): this; static DEFAULT_ORDER: 'XYZ'; From e4b29d8742acd586adf0f2a144b20e3707a7a9a6 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 09:55:38 -0400 Subject: [PATCH 12/72] SkeletonJSON --- types/three/src/math/Matrix4.d.ts | 22 +++++----------------- types/three/src/objects/Skeleton.d.ts | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/types/three/src/math/Matrix4.d.ts b/types/three/src/math/Matrix4.d.ts index 9e94ddaca..dbcf8510b 100644 --- a/types/three/src/math/Matrix4.d.ts +++ b/types/three/src/math/Matrix4.d.ts @@ -4,23 +4,11 @@ import { Quaternion } from './Quaternion'; import { Matrix, Matrix3 } from './Matrix3'; export type Matrix4Tuple = [ - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, - number, -]; + n11: number, n12: number, n13: number, n14: number, + n21: number, n22: number, n23: number, n24: number, + n31: number, n32: number, n33: number, n34: number, + n41: number, n42: number, n43: number, n44: number +] /** * A 4x4 Matrix. diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index 228504984..d59d78bb4 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -1,6 +1,18 @@ import { Bone } from './Bone'; -import { Matrix4 } from './../math/Matrix4'; +import { Matrix4, Matrix4Tuple } from './../math/Matrix4'; import { DataTexture } from './../textures/DataTexture'; +import { Meta } from "../Meta"; + +export interface SkeletonJSON { + + readonly metadata: Meta<"Skeleton", "Skeleton.toJSON">; + + readonly uuid: string; + + bones: string[]; + + boneInverses: Matrix4Tuple[]; +} /** * Use an array of {@link Bone | bones} to create a {@link Skeleton} that can be used by a {@link THREE.SkinnedMesh | SkinnedMesh}. @@ -113,7 +125,7 @@ export class Skeleton { */ dispose(): void; - toJSON(): unknown; + toJSON(): SkeletonJSON; - fromJSON(json: unknown, bones: Record): void; + fromJSON(json: SkeletonJSON, bones: Record): void; } From 91b983457bee62044a5dc6f412b0ad783e6d95b3 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:05:12 -0400 Subject: [PATCH 13/72] Vector2Tuple --- types/three/src/math/Vector2.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/three/src/math/Vector2.d.ts b/types/three/src/math/Vector2.d.ts index 413186a79..bcf2a4155 100644 --- a/types/three/src/math/Vector2.d.ts +++ b/types/three/src/math/Vector2.d.ts @@ -1,7 +1,7 @@ import { Matrix3 } from './Matrix3'; import { BufferAttribute } from './../core/BufferAttribute'; -export type Vector2Tuple = [number, number]; +export type Vector2Tuple = [x: number, y: number]; /** * ( interface Vector ) From 2d11c2862c514362ee52be73455b330cdf6053ce Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:07:15 -0400 Subject: [PATCH 14/72] Matrix3Tuple --- types/three/src/math/Matrix3.d.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/types/three/src/math/Matrix3.d.ts b/types/three/src/math/Matrix3.d.ts index b5f47ddad..fe257f7f6 100644 --- a/types/three/src/math/Matrix3.d.ts +++ b/types/three/src/math/Matrix3.d.ts @@ -3,7 +3,11 @@ import { Matrix4 } from './Matrix4'; import { Vector3 } from './Vector3'; -export type Matrix3Tuple = [number, number, number, number, number, number, number, number, number]; +export type Matrix3Tuple = [ + n11: number, n12: number, n13: number, + n21: number, n22: number, n23: number, + n31: number, n32: number, n33: number +] /** * ( interface Matrix ) From 8210515e2278fe63ba7a439657807a2b1ee0611e Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:18:34 -0400 Subject: [PATCH 15/72] CurveJSON --- types/three/src/extras/core/Curve.d.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/types/three/src/extras/core/Curve.d.ts b/types/three/src/extras/core/Curve.d.ts index 8560b2a85..cb22050d8 100644 --- a/types/three/src/extras/core/Curve.d.ts +++ b/types/three/src/extras/core/Curve.d.ts @@ -3,6 +3,17 @@ import { Vector3 } from './../../math/Vector3'; // Extras / Core ///////////////////////////////////////////////////////////////////// +import { Meta } from "../Meta"; + +export class CurveJSON { + + readonly metadata: Meta<"Curve", "Curve.toJSON">; + + readonly type: Type; + + arcLengthDivisions: number; +} + /** * An extensible curve object which contains methods for interpolation * class Curve @@ -91,8 +102,8 @@ export class Curve { clone(): this; copy(source: Curve): this; - toJSON(): object; - fromJSON(json: object): this; + toJSON(): CurveJSON; + fromJSON(json: CurveJSON): this; /** * @deprecated since r84. From abf9c45ae8779949b5410f3c8b524a0d7798e64c Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:21:35 -0400 Subject: [PATCH 16/72] SourceJSON --- types/three/src/textures/Source.d.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/types/three/src/textures/Source.d.ts b/types/three/src/textures/Source.d.ts index 698d4d098..043c263f9 100644 --- a/types/three/src/textures/Source.d.ts +++ b/types/three/src/textures/Source.d.ts @@ -1,3 +1,17 @@ +export type SourceData = string | { + data: number[], + width: number, + height: number, + type: Type +} + +export class SourceJSON { + + readonly uuid: string; + + url: SourceData | SourceData[]; +} + /** * Represents the data {@link Source} of a texture. * @see {@link https://threejs.org/docs/index.html#api/en/textures/Source | Official Documentation} @@ -45,5 +59,5 @@ export class Source { * Convert the data {@link Source} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Optional object containing metadata. */ - toJSON(meta?: string | {}): {}; + toJSON(meta?: string | {}): SourceJSON } From 27cd36dc3a1ab24474424341644caa790e72308d Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:16:33 -0400 Subject: [PATCH 17/72] CurvePathJSON --- types/three/src/extras/core/CurvePath.d.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/types/three/src/extras/core/CurvePath.d.ts b/types/three/src/extras/core/CurvePath.d.ts index 2c031266d..7879268e9 100644 --- a/types/three/src/extras/core/CurvePath.d.ts +++ b/types/three/src/extras/core/CurvePath.d.ts @@ -1,6 +1,13 @@ -import { Curve } from './Curve'; +import { Curve, CurveJSON } from './Curve'; import { Vector } from './../../math/Vector2'; +export interface CurvePathJSON extends CurveJSON<"CurvePath"> { + + autoClose: boolean; + + curves: CurveJSON[]; +} + export class CurvePath extends Curve { constructor(); From da7bece58a73774bf383c3977af64ccabae4fe23 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:22:17 -0400 Subject: [PATCH 18/72] BufferGeometryJSON --- types/three/src/core/BufferGeometry.d.ts | 37 ++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index 5d61bb588..7ed407cf4 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -1,4 +1,4 @@ -import { BufferAttribute } from './BufferAttribute'; +import { BufferAttribute, BufferAttributeJSON } from './BufferAttribute'; import { InterleavedBufferAttribute } from './InterleavedBufferAttribute'; import { GLBufferAttribute } from './GLBufferAttribute'; import { Box3 } from './../math/Box3'; @@ -6,10 +6,41 @@ import { Sphere } from './../math/Sphere'; import { Matrix4 } from './../math/Matrix4'; import { Quaternion } from './../math/Quaternion'; import { Vector2 } from './../math/Vector2'; -import { Vector3 } from './../math/Vector3'; +import { Vector3, Vector3Tuple } from './../math/Vector3'; import { EventDispatcher } from './EventDispatcher'; import { BuiltinShaderAttributeName } from '../constants'; import * as BufferGeometryUtils from '../../examples/jsm/utils/BufferGeometryUtils'; +import { Meta } from '../Meta'; + +export interface BufferGeometryJSON { + + readonly metadata: Meta<"BufferGeometry", "BufferGeometry.toJSON">; + + readonly type: Type; + + readonly uuid: string; + + name: string; + + userData: Record; + + parameters: Record; + + data: { + + attributes: Record> + + index?: BufferAttributeJSON + + morphAttributes?: Record[]>; + + morphTargetsRelative?: boolean; + + groups?: Array<{ start: number, count: number, materialIndex?: number }>; + + boundingSphere?: { center: Vector3Tuple, radius: number }; + }; +} /** * A representation of mesh, line, or point geometry @@ -347,7 +378,7 @@ export class BufferGeometry extends EventDispatcher { /** * Convert the buffer geometry to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. */ - toJSON(): {}; + toJSON(): BufferGeometryJSON; /** * Creates a clone of this BufferGeometry From 657e668199a72be08e67dcfca67d7f74613c0eb5 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:25:58 -0400 Subject: [PATCH 19/72] TextureJSON --- types/three/src/textures/Texture.d.ts | 63 +++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 3 deletions(-) diff --git a/types/three/src/textures/Texture.d.ts b/types/three/src/textures/Texture.d.ts index 6a1b3111e..58aaeb8bc 100644 --- a/types/three/src/textures/Texture.d.ts +++ b/types/three/src/textures/Texture.d.ts @@ -1,6 +1,6 @@ import { Vector2 } from './../math/Vector2'; import { Matrix3 } from './../math/Matrix3'; -import { Source } from './Source'; +import { Source, SourceJSON } from './Source'; import { EventDispatcher } from './../core/EventDispatcher'; import { Mapping, @@ -14,10 +14,67 @@ import { AnyPixelFormat, AnyMapping, } from '../constants'; +import { Meta } from "../Meta"; + +export interface TextureJSON { + + readonly metadata: Meta<"Texture", "Texture.toJSON">; + + readonly type: Type; + + readonly uuid: string; + + name: string; + + userData: Record; + + image: SourceJSON["uuid"]; + + mapping: number; + cannel: number; + + repeat: [ + x: number, + y: number + ] + + offset: [ + x: number, + y: number + ] + + center: [ + x: number, + y: number + ] + + rotation: number + + wrap: [ + wrapS: number, + wrapT: number + ] + + format: number; + internalFormat: number; + + encoding: number; + + minFilter: number; + magFilter: number; + anisotropy: number; + + flipY: boolean; + + generateMipmaps: boolean; + premultiplyAlpha: boolean; + + unpackAlignment: number; +} /** Shim for OffscreenCanvas. */ // tslint:disable-next-line:no-empty-interface -export interface OffscreenCanvas extends EventTarget {} +export interface OffscreenCanvas extends EventTarget { } /** * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. @@ -425,7 +482,7 @@ export class Texture extends EventDispatcher { * Convert the texture to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Optional object containing metadata. */ - toJSON(meta?: string | {}): {}; + toJSON(meta?: string | {}): TextureJSON; /** * Frees the GPU-related resources allocated by this instance From b84f11c584708b542825cccdf140b411812525f3 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:32:43 -0400 Subject: [PATCH 20/72] PathJSON --- types/three/src/extras/core/Curve.d.ts | 4 ++-- types/three/src/extras/core/CurvePath.d.ts | 2 +- types/three/src/extras/core/Path.d.ts | 10 ++++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/types/three/src/extras/core/Curve.d.ts b/types/three/src/extras/core/Curve.d.ts index cb22050d8..a8acd7fcb 100644 --- a/types/three/src/extras/core/Curve.d.ts +++ b/types/three/src/extras/core/Curve.d.ts @@ -3,9 +3,9 @@ import { Vector3 } from './../../math/Vector3'; // Extras / Core ///////////////////////////////////////////////////////////////////// -import { Meta } from "../Meta"; +import { Meta } from "../../Meta"; -export class CurveJSON { +export class CurveJSON { readonly metadata: Meta<"Curve", "Curve.toJSON">; diff --git a/types/three/src/extras/core/CurvePath.d.ts b/types/three/src/extras/core/CurvePath.d.ts index 7879268e9..5e300cd82 100644 --- a/types/three/src/extras/core/CurvePath.d.ts +++ b/types/three/src/extras/core/CurvePath.d.ts @@ -1,7 +1,7 @@ import { Curve, CurveJSON } from './Curve'; import { Vector } from './../../math/Vector2'; -export interface CurvePathJSON extends CurveJSON<"CurvePath"> { +export interface CurvePathJSON extends CurveJSON { autoClose: boolean; diff --git a/types/three/src/extras/core/Path.d.ts b/types/three/src/extras/core/Path.d.ts index 48122a0a4..48948a366 100644 --- a/types/three/src/extras/core/Path.d.ts +++ b/types/three/src/extras/core/Path.d.ts @@ -1,5 +1,11 @@ -import { Vector2 } from './../../math/Vector2'; -import { CurvePath } from './CurvePath'; +import { Vector2, Vector2Tuple } from './../../math/Vector2'; +import { CurvePath, CurvePathJSON } from './CurvePath'; + + +export interface PathJSON extends CurvePathJSON<"Path"> { + + currentPoint: Vector2Tuple +} /** * a 2d path representation, comprising of points, lines, and cubes, similar to the html5 2d canvas api. It extends CurvePath. From a1cfcca9b0559679c4b6e517fffb0e691237f22e Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 13:35:50 -0400 Subject: [PATCH 21/72] Object3DJSON --- types/three/src/core/Object3D.d.ts | 45 +++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index 6c8e8e111..d683fb609 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -1,7 +1,7 @@ -import { Vector3 } from './../math/Vector3'; +import { Vector3, Vector3Tuple } from './../math/Vector3'; import { Euler } from './../math/Euler'; import { Quaternion } from './../math/Quaternion'; -import { Matrix4 } from './../math/Matrix4'; +import { Matrix4, Matrix4Tuple } from './../math/Matrix4'; import { Matrix3 } from './../math/Matrix3'; import { Layers } from './Layers'; import { WebGLRenderer } from './../renderers/WebGLRenderer'; @@ -12,7 +12,44 @@ import { Group } from './../objects/Group'; import { Intersection, Raycaster } from './Raycaster'; import { EventDispatcher, BaseEvent, Event } from './EventDispatcher'; import { BufferGeometry } from './BufferGeometry'; -import { AnimationClip } from '../animation/AnimationClip'; +import { AnimationClip, AnimationClipJSON } from '../animation/AnimationClip'; +import { Meta } from '../Meta'; + +export interface Object3DJSON { + + readonly metadata: Meta<"Object3D", "Object3D.toJSON">; + + readonly type: Type; + + readonly uuid: string; + + material?: Material["uuid"] | Material["uuid"][] + + animations?: AnimationClipJSON["uuid"][]; + + children: Object3D[]; + + name: string; + + castShadow?: boolean; + + receiveShadow?: boolean; + + frustumCulled?: boolean; + + renderOrder?: number; + + userData: Record; + + layers?: number; + + matrix: Matrix4Tuple; + + up?: Vector3Tuple; + + matrixAutoUpdate?: boolean; +} + /** * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. @@ -552,7 +589,7 @@ export class Object3D extends EventDispatcher { * Convert the object to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Object containing metadata such as materials, textures or images for the object. */ - toJSON(meta?: { geometries: any; materials: any; textures: any; images: any }): any; + toJSON(meta?: { geometries: any; materials: any; textures: any; images: any }): Object3DJSON; /** * Returns a clone of `this` object and optionally all descendants. From 3363b9eaab245bdde33db8c6ab76ec179c4c3a0c Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 26 Apr 2023 14:00:26 -0400 Subject: [PATCH 22/72] Prettier & Lint Fixes --- types/three/src/Meta.d.ts | 8 ++--- types/three/src/Three.d.ts | 4 +-- types/three/src/animation/AnimationClip.d.ts | 1 - types/three/src/animation/KeyframeTrack.d.ts | 7 ++--- types/three/src/core/BufferAttribute.d.ts | 5 ++- types/three/src/core/BufferGeometry.d.ts | 16 +++++----- types/three/src/core/Object3D.d.ts | 10 +++--- types/three/src/extras/core/Curve.d.ts | 7 ++--- types/three/src/extras/core/CurvePath.d.ts | 3 +- types/three/src/extras/core/Path.d.ts | 6 ++-- types/three/src/math/Euler.d.ts | 7 +---- types/three/src/math/Matrix3.d.ts | 14 ++++++--- types/three/src/math/Matrix4.d.ts | 22 ++++++++++--- types/three/src/math/Quaternion.d.ts | 7 +---- types/three/src/objects/Skeleton.d.ts | 5 ++- types/three/src/textures/Source.d.ts | 17 +++++----- types/three/src/textures/Texture.d.ts | 33 ++++++-------------- 17 files changed, 78 insertions(+), 94 deletions(-) diff --git a/types/three/src/Meta.d.ts b/types/three/src/Meta.d.ts index c03244fae..571f112ad 100644 --- a/types/three/src/Meta.d.ts +++ b/types/three/src/Meta.d.ts @@ -1,5 +1,5 @@ export interface Meta { - version: Version - type: Type - generator: Generator -} \ No newline at end of file + version: Version; + type: Type; + generator: Generator; +} diff --git a/types/three/src/Three.d.ts b/types/three/src/Three.d.ts index 8209a5a03..338647229 100644 --- a/types/three/src/Three.d.ts +++ b/types/three/src/Three.d.ts @@ -234,6 +234,6 @@ export * from './textures/Source'; export * from './textures/Texture'; /** - * JSON + * JSON */ -export * from "./Meta" \ No newline at end of file +export * from './Meta'; diff --git a/types/three/src/animation/AnimationClip.d.ts b/types/three/src/animation/AnimationClip.d.ts index ed484a12d..25f1cd068 100644 --- a/types/three/src/animation/AnimationClip.d.ts +++ b/types/three/src/animation/AnimationClip.d.ts @@ -4,7 +4,6 @@ import { Bone } from './../objects/Bone'; import { AnimationBlendMode } from '../constants'; export interface AnimationClipJSON { - readonly uuid: string; name: string; diff --git a/types/three/src/animation/KeyframeTrack.d.ts b/types/three/src/animation/KeyframeTrack.d.ts index 65b7ffdc0..40527d88d 100644 --- a/types/three/src/animation/KeyframeTrack.d.ts +++ b/types/three/src/animation/KeyframeTrack.d.ts @@ -4,15 +4,14 @@ import { CubicInterpolant } from './../math/interpolants/CubicInterpolant'; import { Interpolant } from '../math/Interpolant'; import { InterpolationModes } from '../constants'; -export interface KeyframeTrackJSON { - +export interface KeyframeTrackJSON { type: Type; name: string; - times: ArrayLike + times: ArrayLike; - valus: ArrayLike + valus: ArrayLike; interpolation: number; } diff --git a/types/three/src/core/BufferAttribute.d.ts b/types/three/src/core/BufferAttribute.d.ts index 61fcb75ee..d8f8e18e3 100644 --- a/types/three/src/core/BufferAttribute.d.ts +++ b/types/three/src/core/BufferAttribute.d.ts @@ -2,8 +2,7 @@ import { Usage } from '../constants'; import { Matrix3 } from './../math/Matrix3'; import { Matrix4 } from './../math/Matrix4'; -export interface BufferAttributeJSON { - +export interface BufferAttributeJSON { readonly type: Type; itemSize: number; @@ -19,7 +18,7 @@ export interface BufferAttributeJSON { - - readonly metadata: Meta<"BufferGeometry", "BufferGeometry.toJSON">; +export interface BufferGeometryJSON { + readonly metadata: Meta<'BufferGeometry', 'BufferGeometry.toJSON'>; readonly type: Type; @@ -27,18 +26,17 @@ export interface BufferGeometryJSON { parameters: Record; data: { + attributes: Record>; - attributes: Record> - - index?: BufferAttributeJSON + index?: BufferAttributeJSON; - morphAttributes?: Record[]>; + morphAttributes?: Record>>; morphTargetsRelative?: boolean; - groups?: Array<{ start: number, count: number, materialIndex?: number }>; + groups?: Array<{ start: number; count: number; materialIndex?: number }>; - boundingSphere?: { center: Vector3Tuple, radius: number }; + boundingSphere?: { center: Vector3Tuple; radius: number }; }; } diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index d683fb609..3eb8cb848 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -15,17 +15,16 @@ import { BufferGeometry } from './BufferGeometry'; import { AnimationClip, AnimationClipJSON } from '../animation/AnimationClip'; import { Meta } from '../Meta'; -export interface Object3DJSON { - - readonly metadata: Meta<"Object3D", "Object3D.toJSON">; +export interface Object3DJSON { + readonly metadata: Meta<'Object3D', 'Object3D.toJSON'>; readonly type: Type; readonly uuid: string; - material?: Material["uuid"] | Material["uuid"][] + material?: Material['uuid'] | Array; - animations?: AnimationClipJSON["uuid"][]; + animations?: Array; children: Object3D[]; @@ -50,7 +49,6 @@ export interface Object3DJSON { matrixAutoUpdate?: boolean; } - /** * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. * @remarks Note that this can be used for grouping objects via the {@link THREE.Object3D.add | .add()} method which adds the object as a child, diff --git a/types/three/src/extras/core/Curve.d.ts b/types/three/src/extras/core/Curve.d.ts index a8acd7fcb..232f8b74b 100644 --- a/types/three/src/extras/core/Curve.d.ts +++ b/types/three/src/extras/core/Curve.d.ts @@ -3,11 +3,10 @@ import { Vector3 } from './../../math/Vector3'; // Extras / Core ///////////////////////////////////////////////////////////////////// -import { Meta } from "../../Meta"; +import { Meta } from '../../Meta'; -export class CurveJSON { - - readonly metadata: Meta<"Curve", "Curve.toJSON">; +export class CurveJSON { + readonly metadata: Meta<'Curve', 'Curve.toJSON'>; readonly type: Type; diff --git a/types/three/src/extras/core/CurvePath.d.ts b/types/three/src/extras/core/CurvePath.d.ts index 5e300cd82..91cb1a5f4 100644 --- a/types/three/src/extras/core/CurvePath.d.ts +++ b/types/three/src/extras/core/CurvePath.d.ts @@ -1,8 +1,7 @@ import { Curve, CurveJSON } from './Curve'; import { Vector } from './../../math/Vector2'; -export interface CurvePathJSON extends CurveJSON { - +export interface CurvePathJSON extends CurveJSON { autoClose: boolean; curves: CurveJSON[]; diff --git a/types/three/src/extras/core/Path.d.ts b/types/three/src/extras/core/Path.d.ts index 48948a366..32bcd8d73 100644 --- a/types/three/src/extras/core/Path.d.ts +++ b/types/three/src/extras/core/Path.d.ts @@ -1,10 +1,8 @@ import { Vector2, Vector2Tuple } from './../../math/Vector2'; import { CurvePath, CurvePathJSON } from './CurvePath'; - -export interface PathJSON extends CurvePathJSON<"Path"> { - - currentPoint: Vector2Tuple +export interface PathJSON extends CurvePathJSON<'Path'> { + currentPoint: Vector2Tuple; } /** diff --git a/types/three/src/math/Euler.d.ts b/types/three/src/math/Euler.d.ts index a1a1e5c15..8296943e4 100644 --- a/types/three/src/math/Euler.d.ts +++ b/types/three/src/math/Euler.d.ts @@ -4,12 +4,7 @@ import { Vector3 } from './Vector3'; export type EulerOrder = 'XYZ' | 'YXZ' | 'ZXY' | 'ZYX' | 'YZX' | 'XZY'; -export type EulerTuple = [ - x: number, - y: number, - z: number, - order?: EulerOrder -] +export type EulerTuple = [x: number, y: number, z: number, order?: EulerOrder]; export class Euler { constructor(x?: number, y?: number, z?: number, order?: EulerOrder); diff --git a/types/three/src/math/Matrix3.d.ts b/types/three/src/math/Matrix3.d.ts index fe257f7f6..07a701004 100644 --- a/types/three/src/math/Matrix3.d.ts +++ b/types/three/src/math/Matrix3.d.ts @@ -4,10 +4,16 @@ import { Matrix4 } from './Matrix4'; import { Vector3 } from './Vector3'; export type Matrix3Tuple = [ - n11: number, n12: number, n13: number, - n21: number, n22: number, n23: number, - n31: number, n32: number, n33: number -] + n11: number, + n12: number, + n13: number, + n21: number, + n22: number, + n23: number, + n31: number, + n32: number, + n33: number, +]; /** * ( interface Matrix ) diff --git a/types/three/src/math/Matrix4.d.ts b/types/three/src/math/Matrix4.d.ts index dbcf8510b..f0e537d7b 100644 --- a/types/three/src/math/Matrix4.d.ts +++ b/types/three/src/math/Matrix4.d.ts @@ -4,11 +4,23 @@ import { Quaternion } from './Quaternion'; import { Matrix, Matrix3 } from './Matrix3'; export type Matrix4Tuple = [ - n11: number, n12: number, n13: number, n14: number, - n21: number, n22: number, n23: number, n24: number, - n31: number, n32: number, n33: number, n34: number, - n41: number, n42: number, n43: number, n44: number -] + n11: number, + n12: number, + n13: number, + n14: number, + n21: number, + n22: number, + n23: number, + n24: number, + n31: number, + n32: number, + n33: number, + n34: number, + n41: number, + n42: number, + n43: number, + n44: number, +]; /** * A 4x4 Matrix. diff --git a/types/three/src/math/Quaternion.d.ts b/types/three/src/math/Quaternion.d.ts index d1b2d8d4e..67acdc66e 100644 --- a/types/three/src/math/Quaternion.d.ts +++ b/types/three/src/math/Quaternion.d.ts @@ -4,12 +4,7 @@ import { Matrix4 } from './Matrix4'; import { BufferAttribute } from '../core/BufferAttribute'; import { InterleavedBufferAttribute } from '../core/InterleavedBufferAttribute'; -export type QuaternionTuple = [ - x: number, - y: number, - z: number, - w: number -] +export type QuaternionTuple = [x: number, y: number, z: number, w: number]; /** * Implementation of a quaternion. This is used for rotating things without incurring in the dreaded gimbal lock issue, amongst other advantages. diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index d59d78bb4..5d3ccb030 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -1,11 +1,10 @@ import { Bone } from './Bone'; import { Matrix4, Matrix4Tuple } from './../math/Matrix4'; import { DataTexture } from './../textures/DataTexture'; -import { Meta } from "../Meta"; +import { Meta } from '../Meta'; export interface SkeletonJSON { - - readonly metadata: Meta<"Skeleton", "Skeleton.toJSON">; + readonly metadata: Meta<'Skeleton', 'Skeleton.toJSON'>; readonly uuid: string; diff --git a/types/three/src/textures/Source.d.ts b/types/three/src/textures/Source.d.ts index 043c263f9..243c24691 100644 --- a/types/three/src/textures/Source.d.ts +++ b/types/three/src/textures/Source.d.ts @@ -1,12 +1,13 @@ -export type SourceData = string | { - data: number[], - width: number, - height: number, - type: Type -} +export type SourceData = + | string + | { + data: number[]; + width: number; + height: number; + type: Type; + }; export class SourceJSON { - readonly uuid: string; url: SourceData | SourceData[]; @@ -59,5 +60,5 @@ export class Source { * Convert the data {@link Source} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Optional object containing metadata. */ - toJSON(meta?: string | {}): SourceJSON + toJSON(meta?: string | {}): SourceJSON; } diff --git a/types/three/src/textures/Texture.d.ts b/types/three/src/textures/Texture.d.ts index 58aaeb8bc..f816e36b9 100644 --- a/types/three/src/textures/Texture.d.ts +++ b/types/three/src/textures/Texture.d.ts @@ -14,11 +14,10 @@ import { AnyPixelFormat, AnyMapping, } from '../constants'; -import { Meta } from "../Meta"; +import { Meta } from '../Meta'; -export interface TextureJSON { - - readonly metadata: Meta<"Texture", "Texture.toJSON">; +export interface TextureJSON { + readonly metadata: Meta<'Texture', 'Texture.toJSON'>; readonly type: Type; @@ -28,32 +27,20 @@ export interface TextureJSON { userData: Record; - image: SourceJSON["uuid"]; + image: SourceJSON['uuid']; mapping: number; cannel: number; - repeat: [ - x: number, - y: number - ] + repeat: [x: number, y: number]; - offset: [ - x: number, - y: number - ] + offset: [x: number, y: number]; - center: [ - x: number, - y: number - ] + center: [x: number, y: number]; - rotation: number + rotation: number; - wrap: [ - wrapS: number, - wrapT: number - ] + wrap: [wrapS: number, wrapT: number]; format: number; internalFormat: number; @@ -74,7 +61,7 @@ export interface TextureJSON { /** Shim for OffscreenCanvas. */ // tslint:disable-next-line:no-empty-interface -export interface OffscreenCanvas extends EventTarget { } +export interface OffscreenCanvas extends EventTarget {} /** * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. From 941c740d47ff9f6e001ec1da60540659813cc7a0 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 27 Apr 2023 13:51:44 -0400 Subject: [PATCH 23/72] BoneJSON --- types/three/src/objects/Bone.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/three/src/objects/Bone.d.ts b/types/three/src/objects/Bone.d.ts index a6ea73d0b..e84a1299d 100644 --- a/types/three/src/objects/Bone.d.ts +++ b/types/three/src/objects/Bone.d.ts @@ -1,4 +1,6 @@ -import { Object3D } from './../core/Object3D'; +import { Object3D, Object3DJSON } from './../core/Object3D'; + +export interface BoneJSON extends Object3DJSON {} /** * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} From fb652f53967b7ef8f3c250741a80838389ea8db7 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 27 Apr 2023 13:52:15 -0400 Subject: [PATCH 24/72] GroupJSON --- types/three/src/objects/Group.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/three/src/objects/Group.d.ts b/types/three/src/objects/Group.d.ts index 9b46c6e9b..20d989d79 100644 --- a/types/three/src/objects/Group.d.ts +++ b/types/three/src/objects/Group.d.ts @@ -1,4 +1,6 @@ -import { Object3D } from './../core/Object3D'; +import { Object3D, Object3DJSON } from './../core/Object3D'; + +export interface GroupJSON extends Object3DJSON { } /** * Its purpose is to make working with groups of objects syntactically clearer. From eae204696db3f251237ffce0c58b0a5e0683c9ce Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 27 Apr 2023 13:58:08 -0400 Subject: [PATCH 25/72] MeshJSON, InstancedMeshJSON --- types/three/src/objects/InstancedMesh.d.ts | 15 ++++++++++++--- types/three/src/objects/Mesh.d.ts | 9 ++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/types/three/src/objects/InstancedMesh.d.ts b/types/three/src/objects/InstancedMesh.d.ts index a54ad1fd5..79758230a 100644 --- a/types/three/src/objects/InstancedMesh.d.ts +++ b/types/three/src/objects/InstancedMesh.d.ts @@ -1,11 +1,20 @@ import { BufferGeometry } from '../core/BufferGeometry'; import { Material } from './../materials/Material'; -import { BufferAttribute } from './../core/BufferAttribute'; import { InstancedBufferAttribute } from '../core/InstancedBufferAttribute'; -import { Mesh } from './Mesh'; +import { Mesh, MeshJSON } from './Mesh'; import { Matrix4 } from './../math/Matrix4'; import { Color } from './../math/Color'; -import { Box3, Sphere } from '../Three'; +import { Matrix4Tuple } from '../math/Matrix4'; +import { BufferAttributeJSON } from './../core/BufferAttribute'; + +export interface InstancedMeshJSON extends MeshJSON { + + count: number; + + instanceMatrix: Matrix4Tuple + + instanceColor: BufferAttributeJSON; +} /** * A special version of {@link THREE.Mesh | Mesh} with instanced rendering support diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index 0a0300adb..fdca14110 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -1,10 +1,13 @@ import { Material } from './../materials/Material'; -import { Raycaster } from './../core/Raycaster'; -import { Object3D } from './../core/Object3D'; +import { Object3D, Object3DJSON } from './../core/Object3D'; import { BufferGeometry } from '../core/BufferGeometry'; -import { Intersection } from '../core/Raycaster'; import { Vector3 } from '../math/Vector3'; +export interface MeshJSON extends Object3DJSON { + + geometry: BufferGeometry["uuid"]; +} + /** * Class representing triangular {@link https://en.wikipedia.org/wiki/Polygon_mesh | polygon mesh} based objects. * @remarks From 10c1909a9820ca31e1cca3cfc081c4cdde6badd6 Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 27 Apr 2023 13:59:05 -0400 Subject: [PATCH 26/72] SkinnedMeshJSON --- types/three/src/objects/SkinnedMesh.d.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/types/three/src/objects/SkinnedMesh.d.ts b/types/three/src/objects/SkinnedMesh.d.ts index c95cdb31c..5ff048cf0 100644 --- a/types/three/src/objects/SkinnedMesh.d.ts +++ b/types/three/src/objects/SkinnedMesh.d.ts @@ -1,10 +1,21 @@ import { Material } from './../materials/Material'; -import { Matrix4 } from './../math/Matrix4'; +import { Matrix4, Matrix4Tuple } from './../math/Matrix4'; import { Vector3 } from './../math/Vector3'; import { Skeleton } from './Skeleton'; -import { Mesh } from './Mesh'; +import { Mesh, MeshJSON } from './Mesh'; import { BufferGeometry } from '../core/BufferGeometry'; +export interface SkinnedMeshJSON extends MeshJSON { + + bindMode: string; + + bindMatrix: Matrix4Tuple; + + skeleton?: Skeleton["uuid"]; + + +} + /** * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry. * @remarks From 84e01eeab9b6d6152e5b6599ec25eec4a83b732b Mon Sep 17 00:00:00 2001 From: Hoodgail Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 27 Apr 2023 13:59:28 -0400 Subject: [PATCH 27/72] Format --- types/three/src/objects/Group.d.ts | 2 +- types/three/src/objects/InstancedMesh.d.ts | 5 ++--- types/three/src/objects/Mesh.d.ts | 5 ++--- types/three/src/objects/SkinnedMesh.d.ts | 7 ++----- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/types/three/src/objects/Group.d.ts b/types/three/src/objects/Group.d.ts index 20d989d79..e755607b1 100644 --- a/types/three/src/objects/Group.d.ts +++ b/types/three/src/objects/Group.d.ts @@ -1,6 +1,6 @@ import { Object3D, Object3DJSON } from './../core/Object3D'; -export interface GroupJSON extends Object3DJSON { } +export interface GroupJSON extends Object3DJSON {} /** * Its purpose is to make working with groups of objects syntactically clearer. diff --git a/types/three/src/objects/InstancedMesh.d.ts b/types/three/src/objects/InstancedMesh.d.ts index 79758230a..b05168b14 100644 --- a/types/three/src/objects/InstancedMesh.d.ts +++ b/types/three/src/objects/InstancedMesh.d.ts @@ -7,11 +7,10 @@ import { Color } from './../math/Color'; import { Matrix4Tuple } from '../math/Matrix4'; import { BufferAttributeJSON } from './../core/BufferAttribute'; -export interface InstancedMeshJSON extends MeshJSON { - +export interface InstancedMeshJSON extends MeshJSON { count: number; - instanceMatrix: Matrix4Tuple + instanceMatrix: Matrix4Tuple; instanceColor: BufferAttributeJSON; } diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index fdca14110..d74192865 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -3,9 +3,8 @@ import { Object3D, Object3DJSON } from './../core/Object3D'; import { BufferGeometry } from '../core/BufferGeometry'; import { Vector3 } from '../math/Vector3'; -export interface MeshJSON extends Object3DJSON { - - geometry: BufferGeometry["uuid"]; +export interface MeshJSON extends Object3DJSON { + geometry: BufferGeometry['uuid']; } /** diff --git a/types/three/src/objects/SkinnedMesh.d.ts b/types/three/src/objects/SkinnedMesh.d.ts index 5ff048cf0..d151307aa 100644 --- a/types/three/src/objects/SkinnedMesh.d.ts +++ b/types/three/src/objects/SkinnedMesh.d.ts @@ -5,15 +5,12 @@ import { Skeleton } from './Skeleton'; import { Mesh, MeshJSON } from './Mesh'; import { BufferGeometry } from '../core/BufferGeometry'; -export interface SkinnedMeshJSON extends MeshJSON { - +export interface SkinnedMeshJSON extends MeshJSON { bindMode: string; bindMatrix: Matrix4Tuple; - skeleton?: Skeleton["uuid"]; - - + skeleton?: Skeleton['uuid']; } /** From 8109927fa28df9359537ea3cdc1b4c777b905a12 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 07:28:57 -0400 Subject: [PATCH 28/72] Format --- package-lock.json | 6680 ++++++++++++++++++ types/three/src/Three.d.ts | 2 +- types/three/src/animation/KeyframeTrack.d.ts | 2 +- types/three/src/core/BufferAttribute.d.ts | 2 +- types/three/src/core/BufferGeometry.d.ts | 6 +- types/three/src/core/Object3D.d.ts | 10 +- types/three/src/extras/core/Curve.d.ts | 6 +- types/three/src/extras/core/CurvePath.d.ts | 3 +- types/three/src/extras/core/Path.d.ts | 2 +- types/three/src/objects/Bone.d.ts | 2 +- types/three/src/objects/Group.d.ts | 2 +- types/three/src/objects/InstancedMesh.d.ts | 4 +- types/three/src/objects/Mesh.d.ts | 4 +- types/three/src/objects/Skeleton.d.ts | 4 +- types/three/src/objects/SkinnedMesh.d.ts | 4 +- types/three/src/textures/Source.d.ts | 10 +- types/three/src/textures/Texture.d.ts | 10 +- 17 files changed, 6716 insertions(+), 37 deletions(-) create mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..50d0893c4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6680 @@ +{ + "name": "three-ts-types", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "license": "MIT", + "devDependencies": { + "@definitelytyped/definitions-parser": "latest", + "@definitelytyped/dts-critic": "latest", + "@definitelytyped/dtslint": "latest", + "@definitelytyped/dtslint-runner": "latest", + "@definitelytyped/eslint-plugin": "latest", + "@definitelytyped/header-parser": "latest", + "@definitelytyped/typescript-versions": "latest", + "@definitelytyped/utils": "latest", + "@types/stats.js": "*", + "@types/webxr": "*", + "dprint": "^0.46.2", + "source-map-support": "^0.5.21", + "typescript": "latest" + } + }, + "node_modules/@andrewbranch/untar.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", + "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", + "dev": true + }, + "node_modules/@arethetypeswrong/cli": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.15.1.tgz", + "integrity": "sha512-c4+MVbhktzLDnUFpvWvVkGRAb7zwd9b9ZW4eG62PkBsRRsTM6TKUNR23mLhz6tyYTalyqe8E6v09q4k0KuN3eQ==", + "dev": true, + "dependencies": { + "@arethetypeswrong/core": "0.15.1", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.1", + "marked": "^9.1.2", + "marked-terminal": "^6.0.0", + "semver": "^7.5.4" + }, + "bin": { + "attw": "dist/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@arethetypeswrong/core": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.15.1.tgz", + "integrity": "sha512-FYp6GBAgsNz81BkfItRz8RLZO03w5+BaeiPma1uCfmxTnxbtuMrI/dbzGiOk8VghO108uFI0oJo0OkewdSHw7g==", + "dev": true, + "dependencies": { + "@andrewbranch/untar.js": "^1.0.3", + "fflate": "^0.8.2", + "semver": "^7.5.4", + "ts-expose-internals-conditionally": "1.0.0-empty.0", + "typescript": "5.3.3", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@arethetypeswrong/core/node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@definitelytyped/definitions-parser": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@definitelytyped/definitions-parser/-/definitions-parser-0.1.14.tgz", + "integrity": "sha512-7CMnOuw6WoJ8kqrlGjMwm7azHP1pDhDa3HgJmwhNUjH+1BE4DvMihv0FUu7GwUK0cIzlIqJ/wMgOlKBhqL5Hdw==", + "dev": true, + "dependencies": { + "@definitelytyped/header-parser": "0.2.11", + "@definitelytyped/typescript-versions": "0.1.3", + "@definitelytyped/utils": "0.1.7", + "@types/node": "^18.19.7", + "@types/semver": "^7.5.6", + "pacote": "^17.0.5", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=18.18.0" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/@definitelytyped/dts-critic": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@definitelytyped/dts-critic/-/dts-critic-0.1.12.tgz", + "integrity": "sha512-TP6oXpuNcs+Egfw3BKhCk/HWEscVd3ahjQbQhZ9xBjYxuFB5fVy2RDPjMcacooT7Wo9m3Zllp4XrkfMB1kgBIg==", + "dev": true, + "dependencies": { + "@definitelytyped/header-parser": "0.2.11", + "typescript": "^5.5.2", + "yargs": "^17.7.2" + }, + "engines": { + "node": ">=18.18.0" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/@definitelytyped/dtslint": { + "version": "0.2.22", + "resolved": "https://registry.npmjs.org/@definitelytyped/dtslint/-/dtslint-0.2.22.tgz", + "integrity": "sha512-NAWIxpw3c/Pn6pyauEfLVdX9hQLv7W8V/kmxvqhFkDDSflW+rA6T8XZP/F64jthPMZiDAfVkRMgUC4m3ivMOLA==", + "dev": true, + "dependencies": { + "@arethetypeswrong/cli": "0.15.1", + "@arethetypeswrong/core": "0.15.1", + "@definitelytyped/header-parser": "0.2.11", + "@definitelytyped/typescript-packages": "0.1.3", + "@definitelytyped/typescript-versions": "0.1.3", + "@definitelytyped/utils": "0.1.7", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.14.1", + "@typescript-eslint/types": "^7.14.1", + "@typescript-eslint/typescript-estree": "^7.14.1", + "@typescript-eslint/utils": "^7.14.1", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.29.1", + "semver": "^7.5.4", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "dtslint": "dist/index.js" + }, + "engines": { + "node": ">=18.18.0" + }, + "peerDependencies": { + "typescript": ">= 3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev || >= 3.8.0-dev || >= 3.9.0-dev || >= 4.0.0-dev || >=5.0.0-dev" + } + }, + "node_modules/@definitelytyped/dtslint-runner": { + "version": "0.1.25", + "resolved": "https://registry.npmjs.org/@definitelytyped/dtslint-runner/-/dtslint-runner-0.1.25.tgz", + "integrity": "sha512-LtHoQVy8Fd6qcbDItLAxi2SwPY/0Zyaq/ITFHz0ovHCaPd5+8tN3Y+20akPxGxcU807EsRsAkxJz5MnXr2yPXg==", + "dev": true, + "dependencies": { + "@definitelytyped/definitions-parser": "0.1.14", + "@definitelytyped/dtslint": "0.2.22", + "@definitelytyped/utils": "0.1.7", + "@octokit/rest": "^20.0.2", + "yargs": "^17.7.2" + }, + "bin": { + "dtslint-runner": "dist/index.js" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@definitelytyped/eslint-plugin": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@definitelytyped/eslint-plugin/-/eslint-plugin-0.1.17.tgz", + "integrity": "sha512-JyFP7XNc+yAHdiYr8RS/cLeleKc/WKbwUi13HpaEx9kAhu/CisiVCxZUzuvJrSAcxg+u2XilRGYtwkyvJWv5eA==", + "dev": true, + "dependencies": { + "@definitelytyped/utils": "0.1.7", + "@typescript-eslint/types": "^7.14.1", + "@typescript-eslint/utils": "^7.14.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=18.18.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.14.1", + "eslint": "^8.40.0", + "eslint-plugin-jsdoc": "^44.0.0", + "typescript": ">= 3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev || >= 3.8.0-dev || >= 3.9.0-dev || >= 4.0.0-dev || >=5.0.0-dev" + } + }, + "node_modules/@definitelytyped/header-parser": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@definitelytyped/header-parser/-/header-parser-0.2.11.tgz", + "integrity": "sha512-OUE+bz0puVYJaJUz39CeOrV7NYpfyRLZyEhRGJhLdTH+nzAnItiXNHRqsbw2jWKXuOSloez3VNcylyKqd10d6w==", + "dev": true, + "dependencies": { + "@definitelytyped/typescript-versions": "0.1.3", + "@definitelytyped/utils": "0.1.7", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@definitelytyped/typescript-packages": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-packages/-/typescript-packages-0.1.3.tgz", + "integrity": "sha512-CqLVMhkoeOURA5hRpOXD/5SrXWrV+podeNnrqZ6g8mYKu+c1+pxiVJHd5zhgSjFb5VhfDz/UfwDwZfEYae3zQA==", + "dev": true, + "dependencies": { + "@definitelytyped/typescript-versions": "0.1.3", + "typescript-4.8": "npm:typescript@~4.8.0-0", + "typescript-4.9": "npm:typescript@~4.9.0-0", + "typescript-5.0": "npm:typescript@~5.0.0-0", + "typescript-5.1": "npm:typescript@~5.1.0-0", + "typescript-5.2": "npm:typescript@~5.2.0-0", + "typescript-5.3": "npm:typescript@~5.3.0-0", + "typescript-5.4": "npm:typescript@~5.4.0-0", + "typescript-5.5": "npm:typescript@~5.5.0-0", + "typescript-5.6": "npm:typescript@~5.6.0-0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@definitelytyped/typescript-versions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.3.tgz", + "integrity": "sha512-/OSa91o/iZWVnsIZD6C0yryQSMv4UKtoEyxOz2baqE4j4lOV/+ZLR+9A5Gew96lFaUkmWzA1x+rhx013mzaI7w==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@definitelytyped/utils": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.7.tgz", + "integrity": "sha512-t58AeNg6+mvyMnBHyPC6JQqWMW0Iwyb+vlpBz4V0d0iDY9H8gGCnLFg9vtN1nC+JXfTXBlf9efu9unMUeaPCiA==", + "dev": true, + "dependencies": { + "@qiwi/npm-registry-client": "^8.9.1", + "@types/node": "^18.19.7", + "cachedir": "^2.0.0", + "charm": "^1.0.2", + "minimatch": "^9.0.3", + "tar": "^6.2.1", + "tar-stream": "^3.1.6", + "which": "^4.0.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@dprint/darwin-arm64": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.3.tgz", + "integrity": "sha512-1ycDpGvclGHF3UG5V6peymPDg6ouNTqM6BjhVELQ6zwr+X98AMhq/1slgO8hwHtPcaS5qhTAS+PkzOmBJRegow==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/darwin-x64": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.3.tgz", + "integrity": "sha512-v5IpLmrY836Q5hJAxZuX097ZNQvoZgO6JKO4bK4l6XDhhHAw2XTIUr41+FM5r36ENxyASMk0NpHjhcHtih3o0g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@dprint/linux-arm64-glibc": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.3.tgz", + "integrity": "sha512-9P13g1vgV8RfQH2qBGa8YAfaOeWA42RIhj7lmWRpkDFtwau96reMKwnBBn8bHUnc5e6bSsbPUOMb/X1KMUKz/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-arm64-musl": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.3.tgz", + "integrity": "sha512-AAcdcMSZ6DEIoY9E0xQHjkZP+THP7EWsQge4TWzglSIjzn31YltglHAGYFcLB4CTJYpF0NsFDNFktzgkO+s0og==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-glibc": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.3.tgz", + "integrity": "sha512-c5cQ3G1rC64nBZ8Pd2LGWwzkEk4D7Ax9NrBbwYmNPvs6mFbGlJPC1+RD95x2WwIrIlMIciLG+Kxmt25PzBphmg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/linux-x64-musl": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.3.tgz", + "integrity": "sha512-ONtk2QtLcV0TqWOCOqzUFQixgk3JC+vnJLB5L6tQwT7BX5LzeircfE/1f4dg459iqejNC9MBXZkHnXqabvWSow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@dprint/win32-x64": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.3.tgz", + "integrity": "sha512-xvj4DSEilf0gGdT7CqnwNEgfWNuWqT6eIBxHDEUbmcn1vZ7IwirtqRq/nm3lmYtQaJ4EbtMQZvACHZwxC7G96w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.39.4", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.39.4.tgz", + "integrity": "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg==", + "dev": true, + "peer": true, + "dependencies": { + "comment-parser": "1.3.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.7.tgz", + "integrity": "sha512-WaOVvto604d5IpdCRV2KjQu8PzkfE96d50CQGKgywXh2GxXmDeUO5EWcBC4V57uFyrNqx83+MewuJh3WTR3xPA==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", + "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", + "dev": true, + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", + "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@npmcli/package-json/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-1.1.0.tgz", + "integrity": "sha512-PfnWuOkQgu7gCbnSsAisaX7hKOdZ4wSAhAzH3/ph5dSGau52kCRrMMGbiSQLwyTZpgldkZ49b0brkOr1AzGBHQ==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-7.0.4.tgz", + "integrity": "sha512-9ApYM/3+rBt9V80aYg6tZfzj3UWdiYyCt7gJUD1VJKvWF5nwKDSICXbYIQbspFTq6TOpbsEtIC0LArB8d9PFmg==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "dev": true, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", + "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", + "dev": true, + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.3.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", + "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", + "dev": true, + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", + "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", + "dev": true, + "dependencies": { + "@octokit/request": "^8.3.0", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "22.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", + "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", + "dev": true + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.1.tgz", + "integrity": "sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==", + "dev": true, + "dependencies": { + "@octokit/types": "^13.5.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", + "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", + "dev": true, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.2.tgz", + "integrity": "sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==", + "dev": true, + "dependencies": { + "@octokit/types": "^13.5.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", + "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", + "dev": true, + "dependencies": { + "@octokit/endpoint": "^9.0.1", + "@octokit/request-error": "^5.1.0", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", + "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", + "dev": true, + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.1.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.1.tgz", + "integrity": "sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==", + "dev": true, + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.3.1", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.2.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", + "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", + "dev": true, + "dependencies": { + "@octokit/openapi-types": "^22.2.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@qiwi/npm-registry-client": { + "version": "8.9.1", + "resolved": "https://registry.npmjs.org/@qiwi/npm-registry-client/-/npm-registry-client-8.9.1.tgz", + "integrity": "sha512-rZF+mG+NfijR0SHphhTLHRr4aM4gtfdwoAMY6we2VGQam8vkN1cxGG1Lg/Llrj8Dd0Mu6VjdFQRyMMRZxtZR2A==", + "dev": true, + "dependencies": { + "concat-stream": "^2.0.0", + "graceful-fs": "^4.2.4", + "normalize-package-data": "~1.0.1 || ^2.0.0 || ^3.0.0", + "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^8.0.0", + "once": "^1.4.0", + "request": "^2.88.2", + "retry": "^0.12.0", + "safe-buffer": "^5.2.1", + "semver": "2 >=2.2.1 || 3.x || 4 || 5 || 7", + "slide": "^1.1.6", + "ssri": "^8.0.0" + }, + "optionalDependencies": { + "npmlog": "2 || ^3.1.0 || ^4.0.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", + "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", + "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", + "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", + "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", + "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", + "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/stats.js": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", + "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", + "dev": true + }, + "node_modules/@types/webxr": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.19.tgz", + "integrity": "sha512-4hxA+NwohSgImdTSlPXEqDqqFktNgmTXQ05ff1uWam05tNGroCMp4G+4XVl6qWm1p7GQ/9oD41kAYsSssF6Mzw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", + "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/type-utils": "7.15.0", + "@typescript-eslint/utils": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", + "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", + "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", + "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.15.0", + "@typescript-eslint/utils": "7.15.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", + "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", + "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/visitor-keys": "7.15.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", + "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.15.0", + "@typescript-eslint/types": "7.15.0", + "@typescript-eslint/typescript-estree": "7.15.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", + "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.15.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true, + "optional": true + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "deprecated": "This package is no longer supported.", + "dev": true, + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "optional": true + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", + "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", + "dev": true + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "dev": true + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", + "dev": true + }, + "node_modules/cacache": { + "version": "18.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.3.tgz", + "integrity": "sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/cachedir": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/charm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", + "integrity": "sha512-wqW3VdPnlSWT4eRiYX+hcs+C6ViBPUWk1qTCd+37qw9kEm/a5n2qcyQDMBWvSYKN/ctqZzeXNQaeBjOetJJUkw==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/comment-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", + "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "optional": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "optional": true + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dprint": { + "version": "0.46.3", + "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.3.tgz", + "integrity": "sha512-ACEd7B7sO/uvPvV/nsHbtkIeMqeD2a8XGO1DokROtKDUmI5WbuflGZOwyjFCYwy4rkX6FXoYBzGdEQ6um7BjCA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "dprint": "bin.js" + }, + "optionalDependencies": { + "@dprint/darwin-arm64": "0.46.3", + "@dprint/darwin-x64": "0.46.3", + "@dprint/linux-arm64-glibc": "0.46.3", + "@dprint/linux-arm64-musl": "0.46.3", + "@dprint/linux-x64-glibc": "0.46.3", + "@dprint/linux-x64-musl": "0.46.3", + "@dprint/win32-x64": "0.46.3" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecc-jsbn/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "44.2.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-44.2.7.tgz", + "integrity": "sha512-PcAJO7Wh4xIHPT+StBRpEbWgwCpIrYk75zL31RMbduVVHpgiy3Y8aXQ6pdbRJOq0fxHuepWSEAve8ZrPWTSKRg==", + "dev": true, + "peer": true, + "dependencies": { + "@es-joy/jsdoccomment": "~0.39.4", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.3.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "semver": "^7.5.1", + "spdx-expression-parse": "^3.0.1" + }, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", + "dev": true, + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", + "dev": true, + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", + "dev": true, + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", + "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "optional": true + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", + "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", + "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "dev": true, + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", + "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/marked-terminal": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.2.0.tgz", + "integrity": "sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "node-emoji": "^2.1.3", + "supports-hyperlinks": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <12" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-json-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", + "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", + "dev": true, + "dependencies": { + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" + } + }, + "node_modules/minipass-json-stream/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.1.0.tgz", + "integrity": "sha512-B4J5M1cABxPc5PwfjhbV5hoy2DP9p8lFXASnEN6hugXOa61416tnTZ29x9sSwAd0o99XNIcpvDDy1swAExsVKA==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-bundled": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", + "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz", + "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "semver": "^7.3.4", + "validate-npm-package-name": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-arg/node_modules/validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", + "dev": true, + "dependencies": { + "builtins": "^1.0.3" + } + }, + "node_modules/npm-packlist": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", + "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.1.tgz", + "integrity": "sha512-Udm1f0l2nXb3wxDpKjfohwgdFUSV50UVwzEIpDXVsbDMXVIEF81a/i0UhuQbhrPMMmdiq3+YMFLFIRVLs3hxQw==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm-pick-manifest/node_modules/npm-package-arg": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", + "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.2.1.tgz", + "integrity": "sha512-8l+7jxhim55S85fjiDGJ1rZXBWGtRLi1OSb4Z3BPLObPuIaeKRlPRiYMSHU4/81ck3t71Z+UwDDl47gcpmfQQA==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^1.1.0", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm-registry-fetch/node_modules/npm-package-arg": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", + "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", + "dev": true + }, + "node_modules/pacote": { + "version": "17.0.7", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.7.tgz", + "integrity": "sha512-sgvnoUMlkv9xHwDUKjKQFXVyUi8dtJGKp3vg6sYy+TxbDic5RjZCHF3ygv0EJgNRZ2GfRONjlKPUfokJ9lDpwQ==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^7.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^16.0.0", + "proc-log": "^4.0.0", + "promise-retry": "^2.0.1", + "read-package-json": "^7.0.0", + "read-package-json-fast": "^3.0.0", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "lib/bin.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/pacote/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/pacote/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/pacote/node_modules/npm-package-arg": { + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", + "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/pacote/node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "optional": true + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/read-package-json": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-7.0.1.tgz", + "integrity": "sha512-8PcDiZ8DXUjLf687Ol4BR8Bpm2umR7vhoZOzNRt+uxD9GpBh/K+CAAALVIiYFknmvlmyg7hM7BSNUXPaCCqd0Q==", + "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", + "dev": true, + "dependencies": { + "glob": "^10.2.2", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/read-package-json/node_modules/lru-cache": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", + "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/read-package-json/node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "optional": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "optional": true + }, + "node_modules/sigstore": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", + "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk/node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-expose-internals-conditionally": { + "version": "1.0.0-empty.0", + "resolved": "https://registry.npmjs.org/ts-expose-internals-conditionally/-/ts-expose-internals-conditionally-1.0.0-empty.0.tgz", + "integrity": "sha512-F8m9NOF6ZhdOClDVdlM8gj3fDCav4ZIFSs/EI3ksQbAAXVSCN/Jh5OCJDDZWBuBy9psFc6jULGDlPwjMYMhJDw==", + "dev": true + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tuf-js": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", + "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", + "dev": true, + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-4.8": { + "name": "typescript", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-4.9": { + "name": "typescript", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-5.0": { + "name": "typescript", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/typescript-5.1": { + "name": "typescript", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-5.2": { + "name": "typescript", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-5.3": { + "name": "typescript", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-5.4": { + "name": "typescript", + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-5.5": { + "name": "typescript", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-5.6": { + "name": "typescript", + "version": "5.6.0-dev.20240708", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.0-dev.20240708.tgz", + "integrity": "sha512-znYUhYs3kjemvesSDNvtU17+eUiQnX4RNegVbFdWQ54mXzYrg+0nI2isOO/RQCeGHFuO1M6uR/2/bC+mcDnAVQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", + "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", + "dev": true + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/types/three/src/Three.d.ts b/types/three/src/Three.d.ts index e1ada95a6..6a096fba0 100644 --- a/types/three/src/Three.d.ts +++ b/types/three/src/Three.d.ts @@ -240,4 +240,4 @@ export { createCanvasElement } from "./utils.js"; /** * JSON */ -export * from './Meta.js'; \ No newline at end of file +export * from "./Meta.js"; diff --git a/types/three/src/animation/KeyframeTrack.d.ts b/types/three/src/animation/KeyframeTrack.d.ts index 51051d946..905857343 100644 --- a/types/three/src/animation/KeyframeTrack.d.ts +++ b/types/three/src/animation/KeyframeTrack.d.ts @@ -4,7 +4,7 @@ import { CubicInterpolant } from "../math/interpolants/CubicInterpolant.js"; import { DiscreteInterpolant } from "../math/interpolants/DiscreteInterpolant.js"; import { LinearInterpolant } from "../math/interpolants/LinearInterpolant.js"; -export interface KeyframeTrackJSON { +export interface KeyframeTrackJSON { type: Type; name: string; diff --git a/types/three/src/core/BufferAttribute.d.ts b/types/three/src/core/BufferAttribute.d.ts index 39b19f839..928b10285 100644 --- a/types/three/src/core/BufferAttribute.d.ts +++ b/types/three/src/core/BufferAttribute.d.ts @@ -13,7 +13,7 @@ export type TypedArray = | Float32Array | Float64Array; -export interface BufferAttributeJSON { +export interface BufferAttributeJSON { readonly type: Type; itemSize: number; diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index 442488277..f7962f6ef 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -1,10 +1,10 @@ -import { Meta } from '../Meta.js'; import { Box3 } from "../math/Box3.js"; import { Matrix4 } from "../math/Matrix4.js"; import { Quaternion } from "../math/Quaternion.js"; import { Sphere } from "../math/Sphere.js"; import { Vector2 } from "../math/Vector2.js"; import { Vector3, Vector3Tuple } from "../math/Vector3.js"; +import { Meta } from "../Meta.js"; import { BufferAttribute, BufferAttributeJSON } from "./BufferAttribute.js"; import { EventDispatcher } from "./EventDispatcher.js"; import { GLBufferAttribute } from "./GLBufferAttribute.js"; @@ -16,8 +16,8 @@ export type NormalOrGLBufferAttributes = Record< BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute >; -export interface BufferGeometryJSON { - readonly metadata: Meta<'BufferGeometry', 'BufferGeometry.toJSON'>; +export interface BufferGeometryJSON { + readonly metadata: Meta<"BufferGeometry", "BufferGeometry.toJSON">; readonly type: Type; diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index d5ff55bb0..3f42afb45 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -1,4 +1,3 @@ -import { Meta } from '../Meta.js'; import { AnimationClip, AnimationClipJSON } from "../animation/AnimationClip.js"; import { Camera } from "../cameras/Camera.js"; import { Material } from "../materials/Material.js"; @@ -7,6 +6,7 @@ import { Matrix3 } from "../math/Matrix3.js"; import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; import { Quaternion } from "../math/Quaternion.js"; import { Vector3, Vector3Tuple } from "../math/Vector3.js"; +import { Meta } from "../Meta.js"; import { Group } from "../objects/Group.js"; import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; import { Scene } from "../scenes/Scene.js"; @@ -15,16 +15,16 @@ import { EventDispatcher } from "./EventDispatcher.js"; import { Layers } from "./Layers.js"; import { Intersection, Raycaster } from "./Raycaster.js"; -export interface Object3DJSON { - readonly metadata: Meta<'Object3D', 'Object3D.toJSON'>; +export interface Object3DJSON { + readonly metadata: Meta<"Object3D", "Object3D.toJSON">; readonly type: Type; readonly uuid: string; - material?: Material['uuid'] | Array; + material?: Material["uuid"] | Array; - animations?: Array; + animations?: Array; children: Object3D[]; diff --git a/types/three/src/extras/core/Curve.d.ts b/types/three/src/extras/core/Curve.d.ts index 63c67e7a2..2a9aaa008 100644 --- a/types/three/src/extras/core/Curve.d.ts +++ b/types/three/src/extras/core/Curve.d.ts @@ -1,10 +1,10 @@ import { Vector2 } from "../../math/Vector2.js"; import { Vector3 } from "../../math/Vector3.js"; -import { Meta } from '../../Meta.js'; +import { Meta } from "../../Meta.js"; -export class CurveJSON { - readonly metadata: Meta<'Curve', 'Curve.toJSON'>; +export class CurveJSON { + readonly metadata: Meta<"Curve", "Curve.toJSON">; readonly type: Type; diff --git a/types/three/src/extras/core/CurvePath.d.ts b/types/three/src/extras/core/CurvePath.d.ts index ad6551bd7..db302cc09 100644 --- a/types/three/src/extras/core/CurvePath.d.ts +++ b/types/three/src/extras/core/CurvePath.d.ts @@ -2,13 +2,12 @@ import { Vector2 } from "../../math/Vector2.js"; import { Vector3 } from "../../math/Vector3.js"; import { Curve, CurveJSON } from "./Curve.js"; -export interface CurvePathJSON extends CurveJSON { +export interface CurvePathJSON extends CurveJSON { autoClose: boolean; curves: CurveJSON[]; } - /** * Curved Path - a curve path is simply a array of connected curves, but retains the api of a curve. * @remarks diff --git a/types/three/src/extras/core/Path.d.ts b/types/three/src/extras/core/Path.d.ts index 20661b91f..c939fdb84 100644 --- a/types/three/src/extras/core/Path.d.ts +++ b/types/three/src/extras/core/Path.d.ts @@ -1,6 +1,6 @@ import { Vector2, Vector2Tuple } from "../../math/Vector2.js"; import { CurvePath, CurvePathJSON } from "./CurvePath.js"; -export interface PathJSON extends CurvePathJSON<'Path'> { +export interface PathJSON extends CurvePathJSON<"Path"> { currentPoint: Vector2Tuple; } diff --git a/types/three/src/objects/Bone.d.ts b/types/three/src/objects/Bone.d.ts index c00aeb0b4..610be0661 100644 --- a/types/three/src/objects/Bone.d.ts +++ b/types/three/src/objects/Bone.d.ts @@ -1,6 +1,6 @@ import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; -export interface BoneJSON extends Object3DJSON { } +export interface BoneJSON extends Object3DJSON {} /** * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} diff --git a/types/three/src/objects/Group.d.ts b/types/three/src/objects/Group.d.ts index b1e8a6997..0ae2fe5b4 100644 --- a/types/three/src/objects/Group.d.ts +++ b/types/three/src/objects/Group.d.ts @@ -1,6 +1,6 @@ import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; -export interface GroupJSON extends Object3DJSON { } +export interface GroupJSON extends Object3DJSON {} /** * Its purpose is to make working with groups of objects syntactically clearer. diff --git a/types/three/src/objects/InstancedMesh.d.ts b/types/three/src/objects/InstancedMesh.d.ts index d33d16e83..cbf824bf0 100644 --- a/types/three/src/objects/InstancedMesh.d.ts +++ b/types/three/src/objects/InstancedMesh.d.ts @@ -1,6 +1,6 @@ +import { BufferAttributeJSON } from "./../core/BufferAttribute.js"; import { BufferGeometry } from "../core/BufferGeometry.js"; import { InstancedBufferAttribute } from "../core/InstancedBufferAttribute.js"; -import { BufferAttributeJSON } from './../core/BufferAttribute.js'; import { Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Box3 } from "../math/Box3.js"; @@ -10,7 +10,7 @@ import { Sphere } from "../math/Sphere.js"; import { DataTexture } from "../textures/DataTexture.js"; import { Mesh, MeshJSON } from "./Mesh.js"; -export interface InstancedMeshJSON extends MeshJSON { +export interface InstancedMeshJSON extends MeshJSON { count: number; instanceMatrix: Matrix4Tuple; diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index fafb68323..aa6919289 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -3,8 +3,8 @@ import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Vector3 } from "../math/Vector3.js"; -export interface MeshJSON extends Object3DJSON { - geometry: BufferGeometry['uuid']; +export interface MeshJSON extends Object3DJSON { + geometry: BufferGeometry["uuid"]; } /** diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index 60dceafc0..e635d9208 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -1,9 +1,9 @@ import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Meta } from "../Meta.js"; import { DataTexture } from "../textures/DataTexture.js"; import { Bone } from "./Bone.js"; -import { Meta } from '../Meta.js'; export interface SkeletonJSON { - readonly metadata: Meta<'Skeleton', 'Skeleton.toJSON'>; + readonly metadata: Meta<"Skeleton", "Skeleton.toJSON">; readonly uuid: string; diff --git a/types/three/src/objects/SkinnedMesh.d.ts b/types/three/src/objects/SkinnedMesh.d.ts index 6ed99f23f..ca8784665 100644 --- a/types/three/src/objects/SkinnedMesh.d.ts +++ b/types/three/src/objects/SkinnedMesh.d.ts @@ -9,12 +9,12 @@ import { Vector3 } from "../math/Vector3.js"; import { Mesh, MeshJSON } from "./Mesh.js"; import { Skeleton } from "./Skeleton.js"; -export interface SkinnedMeshJSON extends MeshJSON { +export interface SkinnedMeshJSON extends MeshJSON { bindMode: string; bindMatrix: Matrix4Tuple; - skeleton?: Skeleton['uuid']; + skeleton?: Skeleton["uuid"]; } /** diff --git a/types/three/src/textures/Source.d.ts b/types/three/src/textures/Source.d.ts index 43cee321a..c43f01d22 100644 --- a/types/three/src/textures/Source.d.ts +++ b/types/three/src/textures/Source.d.ts @@ -1,11 +1,11 @@ export type SourceData = | string | { - data: number[]; - width: number; - height: number; - type: Type; - }; + data: number[]; + width: number; + height: number; + type: Type; + }; export class SourceJSON { readonly uuid: string; diff --git a/types/three/src/textures/Texture.d.ts b/types/three/src/textures/Texture.d.ts index 638accdcf..ee373a1d4 100644 --- a/types/three/src/textures/Texture.d.ts +++ b/types/three/src/textures/Texture.d.ts @@ -13,13 +13,13 @@ import { import { EventDispatcher } from "../core/EventDispatcher.js"; import { Matrix3 } from "../math/Matrix3.js"; import { Vector2 } from "../math/Vector2.js"; +import { Meta } from "../Meta.js"; import { CompressedTextureMipmap } from "./CompressedTexture.js"; import { CubeTexture } from "./CubeTexture.js"; import { Source, SourceJSON } from "./Source.js"; -import { Meta } from '../Meta.js'; -export interface TextureJSON { - readonly metadata: Meta<'Texture', 'Texture.toJSON'>; +export interface TextureJSON { + readonly metadata: Meta<"Texture", "Texture.toJSON">; readonly type: Type; @@ -29,7 +29,7 @@ export interface TextureJSON { userData: Record; - image: SourceJSON['uuid']; + image: SourceJSON["uuid"]; mapping: number; cannel: number; @@ -63,7 +63,7 @@ export interface TextureJSON { /** Shim for OffscreenCanvas. */ // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface OffscreenCanvas extends EventTarget { } +export interface OffscreenCanvas extends EventTarget {} /** * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. From 09a32730e31445cfc1b68af9189ee6d7622a0283 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 07:33:24 -0400 Subject: [PATCH 29/72] Scene & Fog --- types/three/src/scenes/Fog.d.ts | 13 +++++++++++++ types/three/src/scenes/Scene.d.ts | 22 +++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/types/three/src/scenes/Fog.d.ts b/types/three/src/scenes/Fog.d.ts index 857607987..5edb7ab57 100644 --- a/types/three/src/scenes/Fog.d.ts +++ b/types/three/src/scenes/Fog.d.ts @@ -1,5 +1,18 @@ import { Color, ColorRepresentation } from "../math/Color.js"; +export interface FogJSON { + + type: "Fog"; + + name: string; + + color: number; + + near: number; + + far: number; +} + export interface FogBase { /** * Optional name of the `Fog` object diff --git a/types/three/src/scenes/Scene.d.ts b/types/three/src/scenes/Scene.d.ts index 565356c8d..ffd239811 100644 --- a/types/three/src/scenes/Scene.d.ts +++ b/types/three/src/scenes/Scene.d.ts @@ -1,10 +1,26 @@ -import { Object3D } from "../core/Object3D.js"; +import { Object3D, Object3DJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Color } from "../math/Color.js"; -import { Euler } from "../math/Euler.js"; +import { Euler, EulerTuple } from "../math/Euler.js"; import { CubeTexture } from "../textures/CubeTexture.js"; import { Texture } from "../textures/Texture.js"; -import { FogBase } from "./Fog.js"; +import { FogBase, FogJSON } from "./Fog.js"; + +export interface SceneJSON extends Object3DJSON { + + fog?: FogJSON; // Assuming the fog has a string representation; adjust as needed. + + backgroundBlurriness?: number; + + backgroundIntensity?: number; + + backgroundRotation: EulerTuple; // Assuming it's a quaternion + + environmentIntensity?: number; + + environmentRotation: EulerTuple; // Assuming it's a quaternion +} + /** * Scenes allow you to set up what and where is to be rendered by three.js From 3b9b810efa17841cdc48e02cbe32e78a820508d5 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 07:42:46 -0400 Subject: [PATCH 30/72] Camera --- types/three/src/cameras/Camera.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/three/src/cameras/Camera.d.ts b/types/three/src/cameras/Camera.d.ts index b49add52e..b02e21739 100644 --- a/types/three/src/cameras/Camera.d.ts +++ b/types/three/src/cameras/Camera.d.ts @@ -1,10 +1,12 @@ import { CoordinateSystem } from "../constants.js"; import { Layers } from "../core/Layers.js"; -import { Object3D } from "../core/Object3D.js"; +import { Object3D, Object3DJSON } from "../core/Object3D.js"; import { Matrix4 } from "../math/Matrix4.js"; import { Vector3 } from "../math/Vector3.js"; import { Vector4 } from "../math/Vector4.js"; +export interface CameraJSON extends Object3DJSON { } + /** * Abstract base class for cameras * @remarks From 1a7ecd02871b589e57f5e495e2dfd3b54729bd01 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 07:45:36 -0400 Subject: [PATCH 31/72] PerspectiveCamera --- .../three/src/cameras/PerspectiveCamera.d.ts | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/types/three/src/cameras/PerspectiveCamera.d.ts b/types/three/src/cameras/PerspectiveCamera.d.ts index ce9b70d7d..bd1c56465 100644 --- a/types/three/src/cameras/PerspectiveCamera.d.ts +++ b/types/three/src/cameras/PerspectiveCamera.d.ts @@ -1,5 +1,31 @@ import { Vector2 } from "../math/Vector2.js"; -import { Camera } from "./Camera.js"; +import { Camera, CameraJSON } from "./Camera.js"; + +export interface PerspectiveCameraJSON extends CameraJSON { + + fov: number; + zoom: number; + + near: number; + far: number; + focus: number; + + aspect: number; + + view?: { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + } + + filmGauge: number; + filmOffset: number; +} + /** * Camera that uses {@link https://en.wikipedia.org/wiki/Perspective_(graphical) | perspective projection}. From 354ac1e1c08bd9540f29b19bf16011b8c7d8f43f Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 07:47:01 -0400 Subject: [PATCH 32/72] OrthographicCamera --- .../three/src/cameras/OrthographicCamera.d.ts | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/types/three/src/cameras/OrthographicCamera.d.ts b/types/three/src/cameras/OrthographicCamera.d.ts index 5c0aafd0c..a4ff62c57 100644 --- a/types/three/src/cameras/OrthographicCamera.d.ts +++ b/types/three/src/cameras/OrthographicCamera.d.ts @@ -1,4 +1,28 @@ -import { Camera } from "./Camera.js"; +import { Camera, CameraJSON } from "./Camera.js"; + +export interface OrthographicCameraJSON extends CameraJSON { + + zoom: number; + + view?: { + enabled: boolean; + fullWidth: number; + fullHeight: number; + offsetX: number; + offsetY: number; + width: number; + height: number; + } + + left: number; + right: number; + top: number; + bottom: number; + near: number; + far: number; +} + + /** * Camera that uses {@link https://en.wikipedia.org/wiki/Orthographic_projection | orthographic projection}. From 4bf2524e9add0a6322866487639e387b33515a7c Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 08:04:53 -0400 Subject: [PATCH 33/72] Format --- types/three/src/cameras/Camera.d.ts | 2 +- types/three/src/cameras/OrthographicCamera.d.ts | 5 +---- types/three/src/cameras/PerspectiveCamera.d.ts | 4 +--- types/three/src/scenes/Fog.d.ts | 1 - types/three/src/scenes/Scene.d.ts | 2 -- 5 files changed, 3 insertions(+), 11 deletions(-) diff --git a/types/three/src/cameras/Camera.d.ts b/types/three/src/cameras/Camera.d.ts index b02e21739..f819a5a9b 100644 --- a/types/three/src/cameras/Camera.d.ts +++ b/types/three/src/cameras/Camera.d.ts @@ -5,7 +5,7 @@ import { Matrix4 } from "../math/Matrix4.js"; import { Vector3 } from "../math/Vector3.js"; import { Vector4 } from "../math/Vector4.js"; -export interface CameraJSON extends Object3DJSON { } +export interface CameraJSON extends Object3DJSON {} /** * Abstract base class for cameras diff --git a/types/three/src/cameras/OrthographicCamera.d.ts b/types/three/src/cameras/OrthographicCamera.d.ts index a4ff62c57..3915aa479 100644 --- a/types/three/src/cameras/OrthographicCamera.d.ts +++ b/types/three/src/cameras/OrthographicCamera.d.ts @@ -1,7 +1,6 @@ import { Camera, CameraJSON } from "./Camera.js"; export interface OrthographicCameraJSON extends CameraJSON { - zoom: number; view?: { @@ -12,7 +11,7 @@ export interface OrthographicCameraJSON extends CameraJSON { - fov: number; zoom: number; @@ -20,13 +19,12 @@ export interface PerspectiveCameraJSON extends Object3DJSON { - fog?: FogJSON; // Assuming the fog has a string representation; adjust as needed. backgroundBlurriness?: number; @@ -21,7 +20,6 @@ export interface SceneJSON extends Object3DJSON Date: Mon, 8 Jul 2024 08:08:20 -0400 Subject: [PATCH 34/72] Remove Meta.d.ts https://github.com/three-types/three-ts-types/pull/426/files/3363b9eaab245bdde33db8c6ab76ec179c4c3a0c#r1178560510 --- types/three/src/Meta.d.ts | 5 ----- types/three/src/Three.d.ts | 4 ---- types/three/src/core/BufferGeometry.d.ts | 2 +- types/three/src/core/Object3D.d.ts | 6 +++++- types/three/src/extras/core/Curve.d.ts | 3 +-- types/three/src/objects/Skeleton.d.ts | 2 +- types/three/src/textures/Texture.d.ts | 2 +- 7 files changed, 9 insertions(+), 15 deletions(-) delete mode 100644 types/three/src/Meta.d.ts diff --git a/types/three/src/Meta.d.ts b/types/three/src/Meta.d.ts deleted file mode 100644 index 571f112ad..000000000 --- a/types/three/src/Meta.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface Meta { - version: Version; - type: Type; - generator: Generator; -} diff --git a/types/three/src/Three.d.ts b/types/three/src/Three.d.ts index 6a096fba0..d52369e68 100644 --- a/types/three/src/Three.d.ts +++ b/types/three/src/Three.d.ts @@ -237,7 +237,3 @@ export * from "./textures/VideoTexture.js"; * Utils */ export { createCanvasElement } from "./utils.js"; -/** - * JSON - */ -export * from "./Meta.js"; diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index f7962f6ef..a271931a2 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -4,11 +4,11 @@ import { Quaternion } from "../math/Quaternion.js"; import { Sphere } from "../math/Sphere.js"; import { Vector2 } from "../math/Vector2.js"; import { Vector3, Vector3Tuple } from "../math/Vector3.js"; -import { Meta } from "../Meta.js"; import { BufferAttribute, BufferAttributeJSON } from "./BufferAttribute.js"; import { EventDispatcher } from "./EventDispatcher.js"; import { GLBufferAttribute } from "./GLBufferAttribute.js"; import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; +import { Meta } from "./Object3D.js"; export type NormalBufferAttributes = Record; export type NormalOrGLBufferAttributes = Record< diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index 3f42afb45..3356e661a 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -6,7 +6,6 @@ import { Matrix3 } from "../math/Matrix3.js"; import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; import { Quaternion } from "../math/Quaternion.js"; import { Vector3, Vector3Tuple } from "../math/Vector3.js"; -import { Meta } from "../Meta.js"; import { Group } from "../objects/Group.js"; import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; import { Scene } from "../scenes/Scene.js"; @@ -14,6 +13,11 @@ import { BufferGeometry } from "./BufferGeometry.js"; import { EventDispatcher } from "./EventDispatcher.js"; import { Layers } from "./Layers.js"; import { Intersection, Raycaster } from "./Raycaster.js"; +export interface Meta { + version: Version; + type: Type; + generator: Generator; +} export interface Object3DJSON { readonly metadata: Meta<"Object3D", "Object3D.toJSON">; diff --git a/types/three/src/extras/core/Curve.d.ts b/types/three/src/extras/core/Curve.d.ts index 2a9aaa008..4a7fce312 100644 --- a/types/three/src/extras/core/Curve.d.ts +++ b/types/three/src/extras/core/Curve.d.ts @@ -1,7 +1,6 @@ import { Vector2 } from "../../math/Vector2.js"; import { Vector3 } from "../../math/Vector3.js"; - -import { Meta } from "../../Meta.js"; +import { Meta } from "../../Three.js"; export class CurveJSON { readonly metadata: Meta<"Curve", "Curve.toJSON">; diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index e635d9208..5b30fead1 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -1,6 +1,6 @@ import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; -import { Meta } from "../Meta.js"; import { DataTexture } from "../textures/DataTexture.js"; +import { Meta } from "../Three.js"; import { Bone } from "./Bone.js"; export interface SkeletonJSON { readonly metadata: Meta<"Skeleton", "Skeleton.toJSON">; diff --git a/types/three/src/textures/Texture.d.ts b/types/three/src/textures/Texture.d.ts index ee373a1d4..d0483eb76 100644 --- a/types/three/src/textures/Texture.d.ts +++ b/types/three/src/textures/Texture.d.ts @@ -13,7 +13,7 @@ import { import { EventDispatcher } from "../core/EventDispatcher.js"; import { Matrix3 } from "../math/Matrix3.js"; import { Vector2 } from "../math/Vector2.js"; -import { Meta } from "../Meta.js"; +import { Meta } from "../Three.js"; import { CompressedTextureMipmap } from "./CompressedTexture.js"; import { CubeTexture } from "./CubeTexture.js"; import { Source, SourceJSON } from "./Source.js"; From b4978b8dc54d6989e670d7fa345f6f7c8efbb819 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 08:13:23 -0400 Subject: [PATCH 35/72] Fix Error: 41:18 error Array type using 'Array' is forbidden for simple types. Use 'GeometryGroup[]' instead @typescript-eslint/array-type Error: 3:18 error An interface declaring no members is equivalent to its supertype @typescript-eslint/no-empty-interface Error: 3:18 error An interface declaring no members is equivalent to its supertype @typescript-eslint/no-empty-interface --- types/three/src/core/BufferGeometry.d.ts | 2 +- types/three/src/objects/Bone.d.ts | 4 +++- types/three/src/objects/Group.d.ts | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index a271931a2..cdf5a60c7 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -38,7 +38,7 @@ export interface BufferGeometryJSON { morphTargetsRelative?: boolean; - groups?: Array; + groups?: GeometryGroup[]; boundingSphere?: { center: Vector3Tuple; radius: number }; }; diff --git a/types/three/src/objects/Bone.d.ts b/types/three/src/objects/Bone.d.ts index 610be0661..c874f1189 100644 --- a/types/three/src/objects/Bone.d.ts +++ b/types/three/src/objects/Bone.d.ts @@ -1,6 +1,8 @@ import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; -export interface BoneJSON extends Object3DJSON {} +export interface BoneJSON extends Object3DJSON { + readonly type: Type; +} /** * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} diff --git a/types/three/src/objects/Group.d.ts b/types/three/src/objects/Group.d.ts index 0ae2fe5b4..8203347cd 100644 --- a/types/three/src/objects/Group.d.ts +++ b/types/three/src/objects/Group.d.ts @@ -1,6 +1,8 @@ import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; -export interface GroupJSON extends Object3DJSON {} +export interface GroupJSON extends Object3DJSON { + readonly type: Type; +} /** * Its purpose is to make working with groups of objects syntactically clearer. From 06e4c40bb5d1170dfc30f46ddc024742a01bb6d3 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 18:53:21 -0400 Subject: [PATCH 36/72] Line --- types/three/src/objects/Line.d.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/types/three/src/objects/Line.d.ts b/types/three/src/objects/Line.d.ts index 2d76dec69..f2a58810a 100644 --- a/types/three/src/objects/Line.d.ts +++ b/types/three/src/objects/Line.d.ts @@ -1,7 +1,12 @@ -import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { BufferGeometry, BufferGeometryJSON } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; +export interface LineJSON extends Object3DJSON { + geometry: BufferGeometryJSON["uuid"]; + material: Material["uuid"] | Array; +} + /** * A continuous line. * @remarks From db45a67ad4be1d732c765daeabeed456b7bba4de Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 18:54:03 -0400 Subject: [PATCH 37/72] LineLoop --- types/three/src/objects/LineLoop.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/three/src/objects/LineLoop.d.ts b/types/three/src/objects/LineLoop.d.ts index 0a070a838..7d7f3380e 100644 --- a/types/three/src/objects/LineLoop.d.ts +++ b/types/three/src/objects/LineLoop.d.ts @@ -1,7 +1,12 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; import { Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; -import { Line } from "./Line.js"; +import { Line, LineJSON } from "./Line.js"; + +export interface LineLoopJSON extends LineJSON { + readonly type: Type; +} + /** * A continuous line that connects back to the start. From 8d33434242808e4cf62de903b91632ccf44e6f7f Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 18:54:36 -0400 Subject: [PATCH 38/72] LineSegments --- types/three/src/objects/LineSegments.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/three/src/objects/LineSegments.d.ts b/types/three/src/objects/LineSegments.d.ts index 9a8199bdc..697ef58d6 100644 --- a/types/three/src/objects/LineSegments.d.ts +++ b/types/three/src/objects/LineSegments.d.ts @@ -1,7 +1,12 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; import { Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; -import { Line } from "./Line.js"; +import { Line, LineJSON } from "./Line.js"; + +export interface LineSegmentsJSON extends LineJSON { + readonly type: Type; +} + /** * A series of lines drawn between pairs of vertices. From 82bde3bdd5a473eab279099a9fbe084b95db473a Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 18:58:47 -0400 Subject: [PATCH 39/72] CubeCamera --- types/three/src/cameras/CubeCamera.d.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/types/three/src/cameras/CubeCamera.d.ts b/types/three/src/cameras/CubeCamera.d.ts index e6e82fb19..9ed6b267b 100644 --- a/types/three/src/cameras/CubeCamera.d.ts +++ b/types/three/src/cameras/CubeCamera.d.ts @@ -1,8 +1,12 @@ import { CoordinateSystem } from "../constants.js"; -import { Object3D } from "../core/Object3D.js"; +import { Object3D, Object3DJSON } from "../core/Object3D.js"; import { WebGLCubeRenderTarget } from "../renderers/WebGLCubeRenderTarget.js"; import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; +export interface CubeCameraJSON extends Object3DJSON { + readonly type: Type; +} + /** * Creates **6** {@link THREE.PerspectiveCamera | cameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. * @remarks The cameras are added to the {@link children} array. From 694d5c60ab8a44d406e5dc749b9d61ca81750c97 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:03:25 -0400 Subject: [PATCH 40/72] Sprite --- types/three/src/objects/Sprite.d.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/types/three/src/objects/Sprite.d.ts b/types/three/src/objects/Sprite.d.ts index 427b8b414..5c2361892 100644 --- a/types/three/src/objects/Sprite.d.ts +++ b/types/three/src/objects/Sprite.d.ts @@ -1,7 +1,12 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; import { SpriteMaterial } from "../materials/Materials.js"; -import { Vector2 } from "../math/Vector2.js"; +import { Vector2, Vector2Tuple } from "../math/Vector2.js"; + +export interface SpriteJSON extends Object3DJSON { + readonly type: Type; +} + /** * A {@link Sprite} is a plane that always faces towards the camera, generally with a partially transparent texture applied. From 4aa06373f4aaa42a5d775a255f1bc3d51485bac9 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:05:10 -0400 Subject: [PATCH 41/72] Points --- types/three/src/objects/Points.d.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/types/three/src/objects/Points.d.ts b/types/three/src/objects/Points.d.ts index ab6b172c6..34be12812 100644 --- a/types/three/src/objects/Points.d.ts +++ b/types/three/src/objects/Points.d.ts @@ -1,10 +1,15 @@ import { BufferAttribute } from "../core/BufferAttribute.js"; -import { BufferGeometry, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; +import { BufferGeometry, BufferGeometryJSON, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; import { GLBufferAttribute } from "../core/GLBufferAttribute.js"; import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; +export interface PointsJSON extends Object3DJSON { + readonly type: Type; +} + + /** * A class for displaying {@link Points} * @remarks From a9bc70701c9595a2003d4a1c841db8929385b0ec Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:07:11 -0400 Subject: [PATCH 42/72] BatchedMesh --- types/three/src/objects/BatchedMesh.d.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/types/three/src/objects/BatchedMesh.d.ts b/types/three/src/objects/BatchedMesh.d.ts index 2669b5c08..f5d57277d 100644 --- a/types/three/src/objects/BatchedMesh.d.ts +++ b/types/three/src/objects/BatchedMesh.d.ts @@ -5,7 +5,11 @@ import { Box3 } from "../math/Box3.js"; import { Color } from "../math/Color.js"; import { Matrix4 } from "../math/Matrix4.js"; import { Sphere } from "../math/Sphere.js"; -import { Mesh } from "./Mesh.js"; +import { Mesh, MeshJSON } from "./Mesh.js"; + +export interface BatchedMeshJSON extends MeshJSON { + readonly type: Type; +} /** * A special version of {@link Mesh} with multi draw batch rendering support. Use {@link BatchedMesh} if you have to From b036f51d1490ff67a8c519321f158ad3c06e27e9 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:09:07 -0400 Subject: [PATCH 43/72] LOD --- types/three/src/objects/LOD.d.ts | 13 ++++++++++++- types/three/src/objects/Line.d.ts | 3 +-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/types/three/src/objects/LOD.d.ts b/types/three/src/objects/LOD.d.ts index 013ce60a7..6d3cd0d35 100644 --- a/types/three/src/objects/LOD.d.ts +++ b/types/three/src/objects/LOD.d.ts @@ -1,5 +1,16 @@ import { Camera } from "../cameras/Camera.js"; -import { Object3D, Object3DEventMap } from "../core/Object3D.js"; +import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; + +export interface LODJSON extends Object3DJSON { + + autoUpdate?: boolean; + + levels: Array<{ + object: Object3DJSON["uuid"]; + distance: number; + hysteresis: number; + }>; +} /** * Every level is associated with an object, and rendering can be switched between them at the distances specified diff --git a/types/three/src/objects/Line.d.ts b/types/three/src/objects/Line.d.ts index f2a58810a..23ed2dfa4 100644 --- a/types/three/src/objects/Line.d.ts +++ b/types/three/src/objects/Line.d.ts @@ -3,8 +3,7 @@ import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; export interface LineJSON extends Object3DJSON { - geometry: BufferGeometryJSON["uuid"]; - material: Material["uuid"] | Array; + readonly type: Type; } /** From 502c20d4bbf5705d97d5c4ee0c70a757fc8fade7 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:10:12 -0400 Subject: [PATCH 44/72] Minor fixes --- types/three/src/objects/Mesh.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index aa6919289..63e788ab5 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -4,7 +4,7 @@ import { Material } from "../materials/Material.js"; import { Vector3 } from "../math/Vector3.js"; export interface MeshJSON extends Object3DJSON { - geometry: BufferGeometry["uuid"]; + readonly type: Type } /** From 8114128b17e7b181d0994d0758844ad5c2749cef Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:22:02 -0400 Subject: [PATCH 45/72] Light & LightShadow --- types/three/src/lights/Light.d.ts | 22 ++++++++++++++++++++-- types/three/src/lights/LightShadow.d.ts | 24 ++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/types/three/src/lights/Light.d.ts b/types/three/src/lights/Light.d.ts index 403b84ab3..3412a69b2 100644 --- a/types/three/src/lights/Light.d.ts +++ b/types/three/src/lights/Light.d.ts @@ -1,6 +1,24 @@ -import { Object3D } from "../core/Object3D.js"; +import { Object3D, Object3DJSON } from "../core/Object3D.js"; import { Color, ColorRepresentation } from "../math/Color.js"; -import { LightShadow } from "./LightShadow.js"; +import { LightShadow, LightShadowJSON } from "./LightShadow.js"; + +export interface LightJSON extends Object3DJSON { + color: number; + intensity: number; + + groundColor?: number; + + distance?: number; + + angle?: number; + penumbra?: number; + decay?: number; + + shadow?: LightShadowJSON; + + target?: Object3DJSON["uuid"]; +} + /** * Abstract base class for lights. diff --git a/types/three/src/lights/LightShadow.d.ts b/types/three/src/lights/LightShadow.d.ts index d3caaed7d..b2bc5c665 100644 --- a/types/three/src/lights/LightShadow.d.ts +++ b/types/three/src/lights/LightShadow.d.ts @@ -1,11 +1,31 @@ -import { Camera } from "../cameras/Camera.js"; +import { Camera, CameraJSON } from "../cameras/Camera.js"; import { Frustum } from "../math/Frustum.js"; import { Matrix4 } from "../math/Matrix4.js"; -import { Vector2 } from "../math/Vector2.js"; +import { Vector2, Vector2Tuple } from "../math/Vector2.js"; import { Vector4 } from "../math/Vector4.js"; import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; import { Light } from "./Light.js"; +type Without = { + [P in keyof T]: P extends K ? undefined : T[P]; +}; + +export interface LightShadowJSON { + + intensity?: number; + + bias?: number; + + normalBias?: number; + + radius?: number; + + mapSize?: Vector2Tuple; + + camera: Without + +} + /** * Serves as a base class for the other shadow classes. * @see {@link https://threejs.org/docs/index.html#api/en/lights/shadows/LightShadow | Official Documentation} From 5458ba75e175fafa2821f33c208850f8afd627d6 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:23:08 -0400 Subject: [PATCH 46/72] HemisphereLight --- types/three/src/lights/HemisphereLight.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/three/src/lights/HemisphereLight.d.ts b/types/three/src/lights/HemisphereLight.d.ts index 1a796dfc8..23ba4bd45 100644 --- a/types/three/src/lights/HemisphereLight.d.ts +++ b/types/three/src/lights/HemisphereLight.d.ts @@ -1,6 +1,11 @@ import { Color, ColorRepresentation } from "../math/Color.js"; import { Vector3 } from "../math/Vector3.js"; -import { Light } from "./Light.js"; +import { Light, LightJSON } from "./Light.js"; + +export interface HemisphereLightJSON extends LightJSON { + readonly type: Type; +} + /** * A light source positioned directly above the scene, with color fading from the sky color to the ground color. From 1d86dd402ec38e47f45a037a8f8fc22d58916303 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:23:38 -0400 Subject: [PATCH 47/72] SpotLight --- types/three/src/lights/SpotLight.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/three/src/lights/SpotLight.d.ts b/types/three/src/lights/SpotLight.d.ts index 7f42488a8..3c9b262d3 100644 --- a/types/three/src/lights/SpotLight.d.ts +++ b/types/three/src/lights/SpotLight.d.ts @@ -2,9 +2,14 @@ import { Object3D } from "../core/Object3D.js"; import { ColorRepresentation } from "../math/Color.js"; import { Vector3 } from "../math/Vector3.js"; import { Texture } from "../textures/Texture.js"; -import { Light } from "./Light.js"; +import { Light, LightJSON } from "./Light.js"; import { SpotLightShadow } from "./SpotLightShadow.js"; +export interface SpotLightJSON extends LightJSON { + readonly type: Type; +} + + /** * This light gets emitted from a single point in one direction, along a cone that increases in size the further from the light it gets. * @example From 5eff13c59261b012e728a378854800a01fd19d1d Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:24:09 -0400 Subject: [PATCH 48/72] PointLight --- types/three/src/lights/PointLight.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/three/src/lights/PointLight.d.ts b/types/three/src/lights/PointLight.d.ts index c13044e12..52ae9caa4 100644 --- a/types/three/src/lights/PointLight.d.ts +++ b/types/three/src/lights/PointLight.d.ts @@ -1,7 +1,12 @@ import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; +import { Light, LightJSON } from "./Light.js"; import { PointLightShadow } from "./PointLightShadow.js"; +export interface PointLightJSON extends LightJSON { + readonly type: Type; +} + + /** * A light that gets emitted from a single point in all directions * @remarks From 450cf65770d6550e6a13d40a0e647dbc47368d82 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Mon, 8 Jul 2024 19:24:35 -0400 Subject: [PATCH 49/72] AmbientLight --- types/three/src/lights/AmbientLight.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/three/src/lights/AmbientLight.d.ts b/types/three/src/lights/AmbientLight.d.ts index 7000a37e7..957d001a0 100644 --- a/types/three/src/lights/AmbientLight.d.ts +++ b/types/three/src/lights/AmbientLight.d.ts @@ -1,5 +1,10 @@ import { ColorRepresentation } from "../math/Color.js"; -import { Light } from "./Light.js"; +import { Light, LightJSON } from "./Light.js"; + +export interface AmbientLightJSON extends LightJSON { + readonly type: Type; +} + /** * This light globally illuminates all objects in the scene equally. From ec4d19a5c9cba4d1e831d1db25ce91a936bf5f38 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 11 Jul 2024 19:05:11 -0400 Subject: [PATCH 50/72] Light, Dir light & Light shadow --- types/three/src/cameras/Camera.d.ts | 4 +++- types/three/src/lights/DirectionalLight.d.ts | 7 ++++++- types/three/src/lights/DirectionalLightShadow.d.ts | 6 ++++-- types/three/src/lights/Light.d.ts | 4 ++-- types/three/src/lights/LightShadow.d.ts | 2 +- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/types/three/src/cameras/Camera.d.ts b/types/three/src/cameras/Camera.d.ts index f819a5a9b..c55e7444d 100644 --- a/types/three/src/cameras/Camera.d.ts +++ b/types/three/src/cameras/Camera.d.ts @@ -5,7 +5,9 @@ import { Matrix4 } from "../math/Matrix4.js"; import { Vector3 } from "../math/Vector3.js"; import { Vector4 } from "../math/Vector4.js"; -export interface CameraJSON extends Object3DJSON {} +export interface CameraJSON extends Object3DJSON { + readonly type: Type; +} /** * Abstract base class for cameras diff --git a/types/three/src/lights/DirectionalLight.d.ts b/types/three/src/lights/DirectionalLight.d.ts index 3d43b7d89..ad603ba75 100644 --- a/types/three/src/lights/DirectionalLight.d.ts +++ b/types/three/src/lights/DirectionalLight.d.ts @@ -2,7 +2,12 @@ import { Object3D } from "../core/Object3D.js"; import { ColorRepresentation } from "../math/Color.js"; import { Vector3 } from "../math/Vector3.js"; import { DirectionalLightShadow } from "./DirectionalLightShadow.js"; -import { Light } from "./Light.js"; +import { Light, LightJSON } from "./Light.js"; + +export interface AmbientLightJSON extends LightJSON { + readonly type: Type; +} + /** * A light that gets emitted in a specific direction diff --git a/types/three/src/lights/DirectionalLightShadow.d.ts b/types/three/src/lights/DirectionalLightShadow.d.ts index 805e4fa0b..cb3e6150c 100644 --- a/types/three/src/lights/DirectionalLightShadow.d.ts +++ b/types/three/src/lights/DirectionalLightShadow.d.ts @@ -1,5 +1,7 @@ -import { OrthographicCamera } from "../cameras/OrthographicCamera.js"; -import { LightShadow } from "./LightShadow.js"; +import { OrthographicCamera, OrthographicCameraJSON } from "../cameras/OrthographicCamera.js"; +import { LightShadow, LightShadowJSON } from "./LightShadow.js"; + +export type DirectionalLightShadowJSON = LightShadowJSON /** * This is used internally by {@link DirectionalLight | DirectionalLights} for calculating shadows. diff --git a/types/three/src/lights/Light.d.ts b/types/three/src/lights/Light.d.ts index 3412a69b2..89724b0a0 100644 --- a/types/three/src/lights/Light.d.ts +++ b/types/three/src/lights/Light.d.ts @@ -2,7 +2,7 @@ import { Object3D, Object3DJSON } from "../core/Object3D.js"; import { Color, ColorRepresentation } from "../math/Color.js"; import { LightShadow, LightShadowJSON } from "./LightShadow.js"; -export interface LightJSON extends Object3DJSON { +export interface LightJSON extends Object3DJSON { color: number; intensity: number; @@ -14,7 +14,7 @@ export interface LightJSON extends Object3DJSON = { [P in keyof T]: P extends K ? undefined : T[P]; }; -export interface LightShadowJSON { +export interface LightShadowJSON = CameraJSON> { intensity?: number; From b2f0aa997d701942b25665c17fd3cf3a6428fb57 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 11 Jul 2024 19:09:23 -0400 Subject: [PATCH 51/72] Format --- types/three/src/lights/AmbientLight.d.ts | 1 - types/three/src/lights/DirectionalLight.d.ts | 1 - types/three/src/lights/DirectionalLightShadow.d.ts | 2 +- types/three/src/lights/HemisphereLight.d.ts | 1 - types/three/src/lights/Light.d.ts | 5 +++-- types/three/src/lights/LightShadow.d.ts | 4 +--- types/three/src/lights/PointLight.d.ts | 1 - types/three/src/lights/SpotLight.d.ts | 1 - types/three/src/objects/LOD.d.ts | 1 - types/three/src/objects/LineLoop.d.ts | 1 - types/three/src/objects/LineSegments.d.ts | 1 - types/three/src/objects/Mesh.d.ts | 2 +- types/three/src/objects/Points.d.ts | 1 - types/three/src/objects/Sprite.d.ts | 1 - 14 files changed, 6 insertions(+), 17 deletions(-) diff --git a/types/three/src/lights/AmbientLight.d.ts b/types/three/src/lights/AmbientLight.d.ts index 957d001a0..377986075 100644 --- a/types/three/src/lights/AmbientLight.d.ts +++ b/types/three/src/lights/AmbientLight.d.ts @@ -5,7 +5,6 @@ export interface AmbientLightJSON extends readonly type: Type; } - /** * This light globally illuminates all objects in the scene equally. * @remarks This light cannot be used to cast shadows as it does not have a direction. diff --git a/types/three/src/lights/DirectionalLight.d.ts b/types/three/src/lights/DirectionalLight.d.ts index ad603ba75..3de996016 100644 --- a/types/three/src/lights/DirectionalLight.d.ts +++ b/types/three/src/lights/DirectionalLight.d.ts @@ -8,7 +8,6 @@ export interface AmbientLightJSON extends readonly type: Type; } - /** * A light that gets emitted in a specific direction * @remarks diff --git a/types/three/src/lights/DirectionalLightShadow.d.ts b/types/three/src/lights/DirectionalLightShadow.d.ts index cb3e6150c..a34ceb7b8 100644 --- a/types/three/src/lights/DirectionalLightShadow.d.ts +++ b/types/three/src/lights/DirectionalLightShadow.d.ts @@ -1,7 +1,7 @@ import { OrthographicCamera, OrthographicCameraJSON } from "../cameras/OrthographicCamera.js"; import { LightShadow, LightShadowJSON } from "./LightShadow.js"; -export type DirectionalLightShadowJSON = LightShadowJSON +export type DirectionalLightShadowJSON = LightShadowJSON; /** * This is used internally by {@link DirectionalLight | DirectionalLights} for calculating shadows. diff --git a/types/three/src/lights/HemisphereLight.d.ts b/types/three/src/lights/HemisphereLight.d.ts index 23ba4bd45..3ee7bc9c3 100644 --- a/types/three/src/lights/HemisphereLight.d.ts +++ b/types/three/src/lights/HemisphereLight.d.ts @@ -6,7 +6,6 @@ export interface HemisphereLightJSON ex readonly type: Type; } - /** * A light source positioned directly above the scene, with color fading from the sky color to the ground color. * @remarks This light cannot be used to cast shadows. diff --git a/types/three/src/lights/Light.d.ts b/types/three/src/lights/Light.d.ts index 89724b0a0..da81ad82b 100644 --- a/types/three/src/lights/Light.d.ts +++ b/types/three/src/lights/Light.d.ts @@ -2,7 +2,9 @@ import { Object3D, Object3DJSON } from "../core/Object3D.js"; import { Color, ColorRepresentation } from "../math/Color.js"; import { LightShadow, LightShadowJSON } from "./LightShadow.js"; -export interface LightJSON extends Object3DJSON { +export interface LightJSON + extends Object3DJSON +{ color: number; intensity: number; @@ -19,7 +21,6 @@ export interface LightJSON = { }; export interface LightShadowJSON = CameraJSON> { - intensity?: number; bias?: number; @@ -22,8 +21,7 @@ export interface LightShadowJSON = CameraJSON mapSize?: Vector2Tuple; - camera: Without - + camera: Without; } /** diff --git a/types/three/src/lights/PointLight.d.ts b/types/three/src/lights/PointLight.d.ts index 52ae9caa4..dd39d52a7 100644 --- a/types/three/src/lights/PointLight.d.ts +++ b/types/three/src/lights/PointLight.d.ts @@ -6,7 +6,6 @@ export interface PointLightJSON extends Ligh readonly type: Type; } - /** * A light that gets emitted from a single point in all directions * @remarks diff --git a/types/three/src/lights/SpotLight.d.ts b/types/three/src/lights/SpotLight.d.ts index 3c9b262d3..33ad267d1 100644 --- a/types/three/src/lights/SpotLight.d.ts +++ b/types/three/src/lights/SpotLight.d.ts @@ -9,7 +9,6 @@ export interface SpotLightJSON extends LightJ readonly type: Type; } - /** * This light gets emitted from a single point in one direction, along a cone that increases in size the further from the light it gets. * @example diff --git a/types/three/src/objects/LOD.d.ts b/types/three/src/objects/LOD.d.ts index 6d3cd0d35..0fc4c3c05 100644 --- a/types/three/src/objects/LOD.d.ts +++ b/types/three/src/objects/LOD.d.ts @@ -2,7 +2,6 @@ import { Camera } from "../cameras/Camera.js"; import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; export interface LODJSON extends Object3DJSON { - autoUpdate?: boolean; levels: Array<{ diff --git a/types/three/src/objects/LineLoop.d.ts b/types/three/src/objects/LineLoop.d.ts index 7d7f3380e..f5915eb8a 100644 --- a/types/three/src/objects/LineLoop.d.ts +++ b/types/three/src/objects/LineLoop.d.ts @@ -7,7 +7,6 @@ export interface LineLoopJSON extends LineJSON readonly type: Type; } - /** * A continuous line that connects back to the start. * @remarks diff --git a/types/three/src/objects/LineSegments.d.ts b/types/three/src/objects/LineSegments.d.ts index 697ef58d6..a75fb57dd 100644 --- a/types/three/src/objects/LineSegments.d.ts +++ b/types/three/src/objects/LineSegments.d.ts @@ -7,7 +7,6 @@ export interface LineSegmentsJSON extends readonly type: Type; } - /** * A series of lines drawn between pairs of vertices. * @remarks diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index 63e788ab5..83a5e175b 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -4,7 +4,7 @@ import { Material } from "../materials/Material.js"; import { Vector3 } from "../math/Vector3.js"; export interface MeshJSON extends Object3DJSON { - readonly type: Type + readonly type: Type; } /** diff --git a/types/three/src/objects/Points.d.ts b/types/three/src/objects/Points.d.ts index 34be12812..1822f3102 100644 --- a/types/three/src/objects/Points.d.ts +++ b/types/three/src/objects/Points.d.ts @@ -9,7 +9,6 @@ export interface PointsJSON extends Object3DJSON readonly type: Type; } - /** * A class for displaying {@link Points} * @remarks diff --git a/types/three/src/objects/Sprite.d.ts b/types/three/src/objects/Sprite.d.ts index 5c2361892..34f1988af 100644 --- a/types/three/src/objects/Sprite.d.ts +++ b/types/three/src/objects/Sprite.d.ts @@ -7,7 +7,6 @@ export interface SpriteJSON extends Object3DJSON readonly type: Type; } - /** * A {@link Sprite} is a plane that always faces towards the camera, generally with a partially transparent texture applied. * @remarks Sprites do not cast shadows, setting `castShadow = true` will have no effect. From 406cfd3078b0f7fb31595a4ad813800aba1f5256 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 11 Jul 2024 19:12:05 -0400 Subject: [PATCH 52/72] Typo --- types/three/src/lights/DirectionalLight.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/three/src/lights/DirectionalLight.d.ts b/types/three/src/lights/DirectionalLight.d.ts index 3de996016..c191aa252 100644 --- a/types/three/src/lights/DirectionalLight.d.ts +++ b/types/three/src/lights/DirectionalLight.d.ts @@ -4,7 +4,7 @@ import { Vector3 } from "../math/Vector3.js"; import { DirectionalLightShadow } from "./DirectionalLightShadow.js"; import { Light, LightJSON } from "./Light.js"; -export interface AmbientLightJSON extends LightJSON { +export interface DirectionalLightJSON extends LightJSON { readonly type: Type; } From 5a6ac75ba3c13b2eefe9c96c9b499b2723267ab9 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Thu, 11 Jul 2024 19:13:21 -0400 Subject: [PATCH 53/72] Fixx: 9:6 error All declarations in this module are exported automatically. Prefer to explicitly write 'export' for clarity. If you have a good reason not to export this declaration, add 'export {}' to the module to shut off automatic exporting @definitelytyped/strict-export-declare-modifier --- types/three/src/lights/LightShadow.d.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/types/three/src/lights/LightShadow.d.ts b/types/three/src/lights/LightShadow.d.ts index 36c12d01d..c494e2448 100644 --- a/types/three/src/lights/LightShadow.d.ts +++ b/types/three/src/lights/LightShadow.d.ts @@ -6,10 +6,6 @@ import { Vector4 } from "../math/Vector4.js"; import { WebGLRenderTarget } from "../renderers/WebGLRenderTarget.js"; import { Light } from "./Light.js"; -type Without = { - [P in keyof T]: P extends K ? undefined : T[P]; -}; - export interface LightShadowJSON = CameraJSON> { intensity?: number; @@ -21,7 +17,9 @@ export interface LightShadowJSON = CameraJSON mapSize?: Vector2Tuple; - camera: Without; + camera: { + [P in keyof TCamera]: P extends "matrix" ? undefined : TCamera[P]; + }; } /** From bd56b5fe145bcd7969e7e4df9fcd28acdc573d90 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 21:31:18 -0400 Subject: [PATCH 54/72] Remove package-lock.json --- package-lock.json | 6680 --------------------------------------------- 1 file changed, 6680 deletions(-) delete mode 100644 package-lock.json diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 50d0893c4..000000000 --- a/package-lock.json +++ /dev/null @@ -1,6680 +0,0 @@ -{ - "name": "three-ts-types", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "license": "MIT", - "devDependencies": { - "@definitelytyped/definitions-parser": "latest", - "@definitelytyped/dts-critic": "latest", - "@definitelytyped/dtslint": "latest", - "@definitelytyped/dtslint-runner": "latest", - "@definitelytyped/eslint-plugin": "latest", - "@definitelytyped/header-parser": "latest", - "@definitelytyped/typescript-versions": "latest", - "@definitelytyped/utils": "latest", - "@types/stats.js": "*", - "@types/webxr": "*", - "dprint": "^0.46.2", - "source-map-support": "^0.5.21", - "typescript": "latest" - } - }, - "node_modules/@andrewbranch/untar.js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", - "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", - "dev": true - }, - "node_modules/@arethetypeswrong/cli": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.15.1.tgz", - "integrity": "sha512-c4+MVbhktzLDnUFpvWvVkGRAb7zwd9b9ZW4eG62PkBsRRsTM6TKUNR23mLhz6tyYTalyqe8E6v09q4k0KuN3eQ==", - "dev": true, - "dependencies": { - "@arethetypeswrong/core": "0.15.1", - "chalk": "^4.1.2", - "cli-table3": "^0.6.3", - "commander": "^10.0.1", - "marked": "^9.1.2", - "marked-terminal": "^6.0.0", - "semver": "^7.5.4" - }, - "bin": { - "attw": "dist/index.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@arethetypeswrong/core": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.15.1.tgz", - "integrity": "sha512-FYp6GBAgsNz81BkfItRz8RLZO03w5+BaeiPma1uCfmxTnxbtuMrI/dbzGiOk8VghO108uFI0oJo0OkewdSHw7g==", - "dev": true, - "dependencies": { - "@andrewbranch/untar.js": "^1.0.3", - "fflate": "^0.8.2", - "semver": "^7.5.4", - "ts-expose-internals-conditionally": "1.0.0-empty.0", - "typescript": "5.3.3", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@arethetypeswrong/core/node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@definitelytyped/definitions-parser": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/@definitelytyped/definitions-parser/-/definitions-parser-0.1.14.tgz", - "integrity": "sha512-7CMnOuw6WoJ8kqrlGjMwm7azHP1pDhDa3HgJmwhNUjH+1BE4DvMihv0FUu7GwUK0cIzlIqJ/wMgOlKBhqL5Hdw==", - "dev": true, - "dependencies": { - "@definitelytyped/header-parser": "0.2.11", - "@definitelytyped/typescript-versions": "0.1.3", - "@definitelytyped/utils": "0.1.7", - "@types/node": "^18.19.7", - "@types/semver": "^7.5.6", - "pacote": "^17.0.5", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=18.18.0" - }, - "peerDependencies": { - "typescript": "*" - } - }, - "node_modules/@definitelytyped/dts-critic": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@definitelytyped/dts-critic/-/dts-critic-0.1.12.tgz", - "integrity": "sha512-TP6oXpuNcs+Egfw3BKhCk/HWEscVd3ahjQbQhZ9xBjYxuFB5fVy2RDPjMcacooT7Wo9m3Zllp4XrkfMB1kgBIg==", - "dev": true, - "dependencies": { - "@definitelytyped/header-parser": "0.2.11", - "typescript": "^5.5.2", - "yargs": "^17.7.2" - }, - "engines": { - "node": ">=18.18.0" - }, - "peerDependencies": { - "typescript": "*" - } - }, - "node_modules/@definitelytyped/dtslint": { - "version": "0.2.22", - "resolved": "https://registry.npmjs.org/@definitelytyped/dtslint/-/dtslint-0.2.22.tgz", - "integrity": "sha512-NAWIxpw3c/Pn6pyauEfLVdX9hQLv7W8V/kmxvqhFkDDSflW+rA6T8XZP/F64jthPMZiDAfVkRMgUC4m3ivMOLA==", - "dev": true, - "dependencies": { - "@arethetypeswrong/cli": "0.15.1", - "@arethetypeswrong/core": "0.15.1", - "@definitelytyped/header-parser": "0.2.11", - "@definitelytyped/typescript-packages": "0.1.3", - "@definitelytyped/typescript-versions": "0.1.3", - "@definitelytyped/utils": "0.1.7", - "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.14.1", - "@typescript-eslint/types": "^7.14.1", - "@typescript-eslint/typescript-estree": "^7.14.1", - "@typescript-eslint/utils": "^7.14.1", - "eslint": "^8.57.0", - "eslint-plugin-import": "^2.29.1", - "semver": "^7.5.4", - "strip-json-comments": "^3.1.1" - }, - "bin": { - "dtslint": "dist/index.js" - }, - "engines": { - "node": ">=18.18.0" - }, - "peerDependencies": { - "typescript": ">= 3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev || >= 3.8.0-dev || >= 3.9.0-dev || >= 4.0.0-dev || >=5.0.0-dev" - } - }, - "node_modules/@definitelytyped/dtslint-runner": { - "version": "0.1.25", - "resolved": "https://registry.npmjs.org/@definitelytyped/dtslint-runner/-/dtslint-runner-0.1.25.tgz", - "integrity": "sha512-LtHoQVy8Fd6qcbDItLAxi2SwPY/0Zyaq/ITFHz0ovHCaPd5+8tN3Y+20akPxGxcU807EsRsAkxJz5MnXr2yPXg==", - "dev": true, - "dependencies": { - "@definitelytyped/definitions-parser": "0.1.14", - "@definitelytyped/dtslint": "0.2.22", - "@definitelytyped/utils": "0.1.7", - "@octokit/rest": "^20.0.2", - "yargs": "^17.7.2" - }, - "bin": { - "dtslint-runner": "dist/index.js" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@definitelytyped/eslint-plugin": { - "version": "0.1.17", - "resolved": "https://registry.npmjs.org/@definitelytyped/eslint-plugin/-/eslint-plugin-0.1.17.tgz", - "integrity": "sha512-JyFP7XNc+yAHdiYr8RS/cLeleKc/WKbwUi13HpaEx9kAhu/CisiVCxZUzuvJrSAcxg+u2XilRGYtwkyvJWv5eA==", - "dev": true, - "dependencies": { - "@definitelytyped/utils": "0.1.7", - "@typescript-eslint/types": "^7.14.1", - "@typescript-eslint/utils": "^7.14.1", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=18.18.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.14.1", - "eslint": "^8.40.0", - "eslint-plugin-jsdoc": "^44.0.0", - "typescript": ">= 3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev || >= 3.8.0-dev || >= 3.9.0-dev || >= 4.0.0-dev || >=5.0.0-dev" - } - }, - "node_modules/@definitelytyped/header-parser": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@definitelytyped/header-parser/-/header-parser-0.2.11.tgz", - "integrity": "sha512-OUE+bz0puVYJaJUz39CeOrV7NYpfyRLZyEhRGJhLdTH+nzAnItiXNHRqsbw2jWKXuOSloez3VNcylyKqd10d6w==", - "dev": true, - "dependencies": { - "@definitelytyped/typescript-versions": "0.1.3", - "@definitelytyped/utils": "0.1.7", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@definitelytyped/typescript-packages": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-packages/-/typescript-packages-0.1.3.tgz", - "integrity": "sha512-CqLVMhkoeOURA5hRpOXD/5SrXWrV+podeNnrqZ6g8mYKu+c1+pxiVJHd5zhgSjFb5VhfDz/UfwDwZfEYae3zQA==", - "dev": true, - "dependencies": { - "@definitelytyped/typescript-versions": "0.1.3", - "typescript-4.8": "npm:typescript@~4.8.0-0", - "typescript-4.9": "npm:typescript@~4.9.0-0", - "typescript-5.0": "npm:typescript@~5.0.0-0", - "typescript-5.1": "npm:typescript@~5.1.0-0", - "typescript-5.2": "npm:typescript@~5.2.0-0", - "typescript-5.3": "npm:typescript@~5.3.0-0", - "typescript-5.4": "npm:typescript@~5.4.0-0", - "typescript-5.5": "npm:typescript@~5.5.0-0", - "typescript-5.6": "npm:typescript@~5.6.0-0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@definitelytyped/typescript-versions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@definitelytyped/typescript-versions/-/typescript-versions-0.1.3.tgz", - "integrity": "sha512-/OSa91o/iZWVnsIZD6C0yryQSMv4UKtoEyxOz2baqE4j4lOV/+ZLR+9A5Gew96lFaUkmWzA1x+rhx013mzaI7w==", - "dev": true, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@definitelytyped/utils": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@definitelytyped/utils/-/utils-0.1.7.tgz", - "integrity": "sha512-t58AeNg6+mvyMnBHyPC6JQqWMW0Iwyb+vlpBz4V0d0iDY9H8gGCnLFg9vtN1nC+JXfTXBlf9efu9unMUeaPCiA==", - "dev": true, - "dependencies": { - "@qiwi/npm-registry-client": "^8.9.1", - "@types/node": "^18.19.7", - "cachedir": "^2.0.0", - "charm": "^1.0.2", - "minimatch": "^9.0.3", - "tar": "^6.2.1", - "tar-stream": "^3.1.6", - "which": "^4.0.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@dprint/darwin-arm64": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.3.tgz", - "integrity": "sha512-1ycDpGvclGHF3UG5V6peymPDg6ouNTqM6BjhVELQ6zwr+X98AMhq/1slgO8hwHtPcaS5qhTAS+PkzOmBJRegow==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@dprint/darwin-x64": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.3.tgz", - "integrity": "sha512-v5IpLmrY836Q5hJAxZuX097ZNQvoZgO6JKO4bK4l6XDhhHAw2XTIUr41+FM5r36ENxyASMk0NpHjhcHtih3o0g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@dprint/linux-arm64-glibc": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.3.tgz", - "integrity": "sha512-9P13g1vgV8RfQH2qBGa8YAfaOeWA42RIhj7lmWRpkDFtwau96reMKwnBBn8bHUnc5e6bSsbPUOMb/X1KMUKz/g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/linux-arm64-musl": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.3.tgz", - "integrity": "sha512-AAcdcMSZ6DEIoY9E0xQHjkZP+THP7EWsQge4TWzglSIjzn31YltglHAGYFcLB4CTJYpF0NsFDNFktzgkO+s0og==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/linux-x64-glibc": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.3.tgz", - "integrity": "sha512-c5cQ3G1rC64nBZ8Pd2LGWwzkEk4D7Ax9NrBbwYmNPvs6mFbGlJPC1+RD95x2WwIrIlMIciLG+Kxmt25PzBphmg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/linux-x64-musl": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.3.tgz", - "integrity": "sha512-ONtk2QtLcV0TqWOCOqzUFQixgk3JC+vnJLB5L6tQwT7BX5LzeircfE/1f4dg459iqejNC9MBXZkHnXqabvWSow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@dprint/win32-x64": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.3.tgz", - "integrity": "sha512-xvj4DSEilf0gGdT7CqnwNEgfWNuWqT6eIBxHDEUbmcn1vZ7IwirtqRq/nm3lmYtQaJ4EbtMQZvACHZwxC7G96w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.39.4", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.39.4.tgz", - "integrity": "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg==", - "dev": true, - "peer": true, - "dependencies": { - "comment-parser": "1.3.1", - "esquery": "^1.5.0", - "jsdoc-type-pratt-parser": "~4.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", - "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/agent/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@npmcli/fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", - "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.7.tgz", - "integrity": "sha512-WaOVvto604d5IpdCRV2KjQu8PzkfE96d50CQGKgywXh2GxXmDeUO5EWcBC4V57uFyrNqx83+MewuJh3WTR3xPA==", - "dev": true, - "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^4.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", - "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", - "dev": true, - "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "bin": { - "installed-package-contents": "bin/index.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/node-gyp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", - "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/package-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", - "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", - "dev": true, - "dependencies": { - "@npmcli/git": "^5.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^4.0.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/package-json/node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/package-json/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/@npmcli/package-json/node_modules/normalize-package-data": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", - "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/promise-spawn": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", - "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", - "dev": true, - "dependencies": { - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/redact": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-1.1.0.tgz", - "integrity": "sha512-PfnWuOkQgu7gCbnSsAisaX7hKOdZ4wSAhAzH3/ph5dSGau52kCRrMMGbiSQLwyTZpgldkZ49b0brkOr1AzGBHQ==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/run-script": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-7.0.4.tgz", - "integrity": "sha512-9ApYM/3+rBt9V80aYg6tZfzj3UWdiYyCt7gJUD1VJKvWF5nwKDSICXbYIQbspFTq6TOpbsEtIC0LArB8d9PFmg==", - "dev": true, - "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", - "dev": true, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/core": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz", - "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==", - "dev": true, - "dependencies": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.1.0", - "@octokit/request": "^8.3.1", - "@octokit/request-error": "^5.1.0", - "@octokit/types": "^13.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/endpoint": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.5.tgz", - "integrity": "sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==", - "dev": true, - "dependencies": { - "@octokit/types": "^13.1.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/graphql": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz", - "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==", - "dev": true, - "dependencies": { - "@octokit/request": "^8.3.0", - "@octokit/types": "^13.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "22.2.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz", - "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==", - "dev": true - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.1.tgz", - "integrity": "sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==", - "dev": true, - "dependencies": { - "@octokit/types": "^13.5.0" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "@octokit/core": "5" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz", - "integrity": "sha512-GihNqNpGHorUrO7Qa9JbAl0dbLnqJVrV8OXe2Zm5/Y4wFkZQDfTreBzVmiRfJVfE4mClXdihHnbpyyO9FSX4HA==", - "dev": true, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "@octokit/core": "5" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.2.tgz", - "integrity": "sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==", - "dev": true, - "dependencies": { - "@octokit/types": "^13.5.0" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "@octokit/core": "^5" - } - }, - "node_modules/@octokit/request": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz", - "integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==", - "dev": true, - "dependencies": { - "@octokit/endpoint": "^9.0.1", - "@octokit/request-error": "^5.1.0", - "@octokit/types": "^13.1.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/request-error": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.0.tgz", - "integrity": "sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==", - "dev": true, - "dependencies": { - "@octokit/types": "^13.1.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/rest": { - "version": "20.1.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.1.tgz", - "integrity": "sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==", - "dev": true, - "dependencies": { - "@octokit/core": "^5.0.2", - "@octokit/plugin-paginate-rest": "11.3.1", - "@octokit/plugin-request-log": "^4.0.0", - "@octokit/plugin-rest-endpoint-methods": "13.2.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/types": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz", - "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==", - "dev": true, - "dependencies": { - "@octokit/openapi-types": "^22.2.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@qiwi/npm-registry-client": { - "version": "8.9.1", - "resolved": "https://registry.npmjs.org/@qiwi/npm-registry-client/-/npm-registry-client-8.9.1.tgz", - "integrity": "sha512-rZF+mG+NfijR0SHphhTLHRr4aM4gtfdwoAMY6we2VGQam8vkN1cxGG1Lg/Llrj8Dd0Mu6VjdFQRyMMRZxtZR2A==", - "dev": true, - "dependencies": { - "concat-stream": "^2.0.0", - "graceful-fs": "^4.2.4", - "normalize-package-data": "~1.0.1 || ^2.0.0 || ^3.0.0", - "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^8.0.0", - "once": "^1.4.0", - "request": "^2.88.2", - "retry": "^0.12.0", - "safe-buffer": "^5.2.1", - "semver": "2 >=2.2.1 || 3.x || 4 || 5 || 7", - "slide": "^1.1.6", - "ssri": "^8.0.0" - }, - "optionalDependencies": { - "npmlog": "2 || ^3.1.0 || ^4.0.0" - } - }, - "node_modules/@sigstore/bundle": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", - "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", - "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", - "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/sign": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", - "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/tuf": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", - "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^2.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/verify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", - "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", - "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@tufjs/models": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", - "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", - "dev": true, - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", - "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "node_modules/@types/stats.js": { - "version": "0.17.3", - "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", - "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", - "dev": true - }, - "node_modules/@types/webxr": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.19.tgz", - "integrity": "sha512-4hxA+NwohSgImdTSlPXEqDqqFktNgmTXQ05ff1uWam05tNGroCMp4G+4XVl6qWm1p7GQ/9oD41kAYsSssF6Mzw==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz", - "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/type-utils": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz", - "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz", - "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz", - "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.15.0", - "@typescript-eslint/utils": "7.15.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz", - "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz", - "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/visitor-keys": "7.15.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz", - "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.15.0", - "@typescript-eslint/types": "7.15.0", - "@typescript-eslint/typescript-estree": "7.15.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz", - "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.15.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansicolors": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", - "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", - "dev": true - }, - "node_modules/aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "node_modules/are-docs-informative": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", - "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", - "dev": true, - "peer": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "deprecated": "This package is no longer supported.", - "dev": true, - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "node_modules/are-we-there-yet/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "optional": true - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/are-we-there-yet/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - }, - "node_modules/are-we-there-yet/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.0.tgz", - "integrity": "sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==", - "dev": true - }, - "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", - "dev": true, - "optional": true - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==", - "dev": true - }, - "node_modules/cacache": { - "version": "18.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.3.tgz", - "integrity": "sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/cacache/node_modules/ssri": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", - "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/cachedir": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", - "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cardinal": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", - "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", - "dev": true, - "dependencies": { - "ansicolors": "~0.3.2", - "redeyed": "~2.1.0" - }, - "bin": { - "cdl": "bin/cdl.js" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/charm": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", - "integrity": "sha512-wqW3VdPnlSWT4eRiYX+hcs+C6ViBPUWk1qTCd+37qw9kEm/a5n2qcyQDMBWvSYKN/ctqZzeXNQaeBjOetJJUkw==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", - "dev": true, - "peer": true, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true, - "optional": true - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn/node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "dev": true, - "optional": true - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dprint": { - "version": "0.46.3", - "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.3.tgz", - "integrity": "sha512-ACEd7B7sO/uvPvV/nsHbtkIeMqeD2a8XGO1DokROtKDUmI5WbuflGZOwyjFCYwy4rkX6FXoYBzGdEQ6um7BjCA==", - "dev": true, - "hasInstallScript": true, - "bin": { - "dprint": "bin.js" - }, - "optionalDependencies": { - "@dprint/darwin-arm64": "0.46.3", - "@dprint/darwin-x64": "0.46.3", - "@dprint/linux-arm64-glibc": "0.46.3", - "@dprint/linux-arm64-musl": "0.46.3", - "@dprint/linux-x64-glibc": "0.46.3", - "@dprint/linux-x64-musl": "0.46.3", - "@dprint/win32-x64": "0.46.3" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecc-jsbn/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/emojilib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", - "dev": true - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jsdoc": { - "version": "44.2.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-44.2.7.tgz", - "integrity": "sha512-PcAJO7Wh4xIHPT+StBRpEbWgwCpIrYk75zL31RMbduVVHpgiy3Y8aXQ6pdbRJOq0fxHuepWSEAve8ZrPWTSKRg==", - "dev": true, - "peer": true, - "dependencies": { - "@es-joy/jsdoccomment": "~0.39.4", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.3.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.5.0", - "semver": "^7.5.1", - "spdx-expression-parse": "^3.0.1" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/exponential-backoff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", - "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", - "dev": true - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "dev": true - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", - "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "optional": true, - "dependencies": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "node_modules/gauge/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "dev": true, - "optional": true, - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "dev": true, - "optional": true, - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gauge/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "optional": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/glob": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.3.tgz", - "integrity": "sha512-Q38SGlYRpVtDBPSWEylRyctn7uDeTp4NQERTLiCT1FqA9JXPYWqAVmQU6qh4r/zMM5ehxTcbaO8EjhWnvEhmyg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true, - "optional": true - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-walk": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", - "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", - "dev": true, - "dependencies": { - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dev": true, - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", - "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true - }, - "node_modules/jackspeak": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.1.tgz", - "integrity": "sha512-U23pQPDnmYybVkYjObcuYMk43VRlMLLqLI+RdZy8s8WV8WsxO9SnqSroKaluuvcNOdCAlauKszDwd+umbot5Mg==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true - }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", - "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", - "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dev": true, - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-fetch-happen": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", - "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", - "dev": true, - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/make-fetch-happen/node_modules/ssri": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", - "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/marked": { - "version": "9.1.6", - "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", - "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 16" - } - }, - "node_modules/marked-terminal": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.2.0.tgz", - "integrity": "sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==", - "dev": true, - "dependencies": { - "ansi-escapes": "^6.2.0", - "cardinal": "^2.1.1", - "chalk": "^5.3.0", - "cli-table3": "^0.6.3", - "node-emoji": "^2.1.3", - "supports-hyperlinks": "^3.0.0" - }, - "engines": { - "node": ">=16.0.0" - }, - "peerDependencies": { - "marked": ">=1 <12" - } - }, - "node_modules/marked-terminal/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minipass-fetch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", - "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-json-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz", - "integrity": "sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==", - "dev": true, - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.6.0", - "char-regex": "^1.0.2", - "emojilib": "^2.4.0", - "skin-tone": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/node-gyp": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.1.0.tgz", - "integrity": "sha512-B4J5M1cABxPc5PwfjhbV5hoy2DP9p8lFXASnEN6hugXOa61416tnTZ29x9sSwAd0o99XNIcpvDDy1swAExsVKA==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^4.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/node-gyp/node_modules/proc-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", - "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/nopt": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", - "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", - "dev": true, - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm-bundled": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", - "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", - "dev": true, - "dependencies": { - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-install-checks": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", - "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", - "dev": true, - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-package-arg": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-8.1.5.tgz", - "integrity": "sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==", - "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "semver": "^7.3.4", - "validate-npm-package-name": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm-package-arg/node_modules/validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==", - "dev": true, - "dependencies": { - "builtins": "^1.0.3" - } - }, - "node_modules/npm-packlist": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", - "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", - "dev": true, - "dependencies": { - "ignore-walk": "^6.0.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.1.tgz", - "integrity": "sha512-Udm1f0l2nXb3wxDpKjfohwgdFUSV50UVwzEIpDXVsbDMXVIEF81a/i0UhuQbhrPMMmdiq3+YMFLFIRVLs3hxQw==", - "dev": true, - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest/node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/npm-pick-manifest/node_modules/npm-package-arg": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", - "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.2.1.tgz", - "integrity": "sha512-8l+7jxhim55S85fjiDGJ1rZXBWGtRLi1OSb4Z3BPLObPuIaeKRlPRiYMSHU4/81ck3t71Z+UwDDl47gcpmfQQA==", - "dev": true, - "dependencies": { - "@npmcli/redact": "^1.1.0", - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch/node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/npm-registry-fetch/node_modules/npm-package-arg": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", - "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "deprecated": "This package is no longer supported.", - "dev": true, - "optional": true, - "dependencies": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", - "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", - "dev": true - }, - "node_modules/pacote": { - "version": "17.0.7", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.7.tgz", - "integrity": "sha512-sgvnoUMlkv9xHwDUKjKQFXVyUi8dtJGKp3vg6sYy+TxbDic5RjZCHF3ygv0EJgNRZ2GfRONjlKPUfokJ9lDpwQ==", - "dev": true, - "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^4.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.2.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/pacote/node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/pacote/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/pacote/node_modules/npm-package-arg": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", - "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/pacote/node_modules/ssri": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", - "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", - "dev": true, - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/proc-log": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", - "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, - "node_modules/read-package-json": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-7.0.1.tgz", - "integrity": "sha512-8PcDiZ8DXUjLf687Ol4BR8Bpm2umR7vhoZOzNRt+uxD9GpBh/K+CAAALVIiYFknmvlmyg7hM7BSNUXPaCCqd0Q==", - "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", - "dev": true, - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/read-package-json-fast": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", - "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", - "dev": true, - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-package-json/node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", - "dev": true, - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/read-package-json/node_modules/lru-cache": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.0.tgz", - "integrity": "sha512-bfJaPTuEiTYBu+ulDaeQ0F+uLmlfFkMgXj4cbwfuMSjgObGMzb55FMMbDvbRU0fAHZ4sLGkz2mKwcMg8Dvm8Ww==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/read-package-json/node_modules/normalize-package-data": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", - "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", - "dev": true, - "dependencies": { - "hosted-git-info": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/redeyed": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", - "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", - "dev": true, - "dependencies": { - "esprima": "~4.0.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "optional": true - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "optional": true - }, - "node_modules/sigstore": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", - "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^2.3.2", - "@sigstore/tuf": "^2.3.4", - "@sigstore/verify": "^1.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/skin-tone": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", - "dev": true, - "dependencies": { - "unicode-emoji-modifier-base": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "dev": true, - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.18", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", - "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true - }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/ssri/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", - "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=14.18" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", - "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-expose-internals-conditionally": { - "version": "1.0.0-empty.0", - "resolved": "https://registry.npmjs.org/ts-expose-internals-conditionally/-/ts-expose-internals-conditionally-1.0.0-empty.0.tgz", - "integrity": "sha512-F8m9NOF6ZhdOClDVdlM8gj3fDCav4ZIFSs/EI3ksQbAAXVSCN/Jh5OCJDDZWBuBy9psFc6jULGDlPwjMYMhJDw==", - "dev": true - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tuf-js": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", - "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", - "dev": true, - "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true - }, - "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-4.8": { - "name": "typescript", - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typescript-4.9": { - "name": "typescript", - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typescript-5.0": { - "name": "typescript", - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/typescript-5.1": { - "name": "typescript", - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-5.2": { - "name": "typescript", - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-5.3": { - "name": "typescript", - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-5.4": { - "name": "typescript", - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-5.5": { - "name": "typescript", - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-5.6": { - "name": "typescript", - "version": "5.6.0-dev.20240708", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.0-dev.20240708.tgz", - "integrity": "sha512-znYUhYs3kjemvesSDNvtU17+eUiQnX4RNegVbFdWQ54mXzYrg+0nI2isOO/RQCeGHFuO1M6uR/2/bC+mcDnAVQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/unicode-emoji-modifier-base": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dev": true, - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", - "dev": true - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/validate-npm-package-name": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", - "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "optional": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} From 68df0d47e8f621cba5aded05ff8be8775ee300d7 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 21:32:21 -0400 Subject: [PATCH 55/72] Update Object3D --- types/three/src/core/Object3D.d.ts | 47 ++++++++++++------------------ 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index 3356e661a..725c9122e 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -1,4 +1,4 @@ -import { AnimationClip, AnimationClipJSON } from "../animation/AnimationClip.js"; +import { AnimationClip } from "../animation/AnimationClip.js"; import { Camera } from "../cameras/Camera.js"; import { Material } from "../materials/Material.js"; import { Euler } from "../math/Euler.js"; @@ -13,44 +13,35 @@ import { BufferGeometry } from "./BufferGeometry.js"; import { EventDispatcher } from "./EventDispatcher.js"; import { Layers } from "./Layers.js"; import { Intersection, Raycaster } from "./Raycaster.js"; -export interface Meta { - version: Version; - type: Type; - generator: Generator; -} - -export interface Object3DJSON { - readonly metadata: Meta<"Object3D", "Object3D.toJSON">; - - readonly type: Type; - - readonly uuid: string; - - material?: Material["uuid"] | Array; - animations?: Array; - - children: Object3D[]; - - name: string; +export interface Object3DJSONObject { + uuid: string; + type: string; + name?: string; castShadow?: boolean; - receiveShadow?: boolean; - + visible?: boolean; frustumCulled?: boolean; - renderOrder?: number; + userData?: Record; - userData: Record; + layers: number; + matrix: Matrix4Tuple; + up: Vector3Tuple; - layers?: number; + matrixAutoUpdate?: boolean; - matrix: Matrix4Tuple; + material?: string | string[]; - up?: Vector3Tuple; + children?: string[]; - matrixAutoUpdate?: boolean; + animations?: string[]; +} + +export interface Object3DJSON { + metadata?: { version: number; type: string; generator: string }; + object: Object3DJSONObject; } export interface Object3DEventMap { From c8ad9d39485d56615b887f612e3e3010c6bd63dd Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 21:39:41 -0400 Subject: [PATCH 56/72] Animation --- types/three/src/animation/AnimationClip.d.ts | 8 ++------ types/three/src/animation/KeyframeTrack.d.ts | 14 +++++--------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/types/three/src/animation/AnimationClip.d.ts b/types/three/src/animation/AnimationClip.d.ts index 0808125e3..4efc3df72 100644 --- a/types/three/src/animation/AnimationClip.d.ts +++ b/types/three/src/animation/AnimationClip.d.ts @@ -4,15 +4,11 @@ import { Bone } from "../objects/Bone.js"; import { KeyframeTrack, KeyframeTrackJSON } from "./KeyframeTrack.js"; export interface AnimationClipJSON { - readonly uuid: string; - name: string; - duration: number; - - blendMode: number; - tracks: KeyframeTrackJSON[]; + uuid: string; + blendMode: AnimationBlendMode; } export interface MorphTarget { diff --git a/types/three/src/animation/KeyframeTrack.d.ts b/types/three/src/animation/KeyframeTrack.d.ts index 905857343..2a48e2651 100644 --- a/types/three/src/animation/KeyframeTrack.d.ts +++ b/types/three/src/animation/KeyframeTrack.d.ts @@ -4,16 +4,12 @@ import { CubicInterpolant } from "../math/interpolants/CubicInterpolant.js"; import { DiscreteInterpolant } from "../math/interpolants/DiscreteInterpolant.js"; import { LinearInterpolant } from "../math/interpolants/LinearInterpolant.js"; -export interface KeyframeTrackJSON { - type: Type; - +export interface KeyframeTrackJSON { name: string; - - times: ArrayLike; - - valus: ArrayLike; - - interpolation: number; + times: number[]; + values: number[]; + interpolation?: InterpolationModes; + type: string; } export class KeyframeTrack { From b342a58f89096821e626de21d417173c4b760b2e Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 21:52:46 -0400 Subject: [PATCH 57/72] Cameras --- types/three/src/cameras/Camera.d.ts | 6 +---- types/three/src/cameras/CubeCamera.d.ts | 6 +---- .../three/src/cameras/OrthographicCamera.d.ts | 22 ++++++++++++------- .../three/src/cameras/PerspectiveCamera.d.ts | 11 ++++++++-- types/three/src/core/Object3D.d.ts | 13 ++++++++++- 5 files changed, 37 insertions(+), 21 deletions(-) diff --git a/types/three/src/cameras/Camera.d.ts b/types/three/src/cameras/Camera.d.ts index c55e7444d..b49add52e 100644 --- a/types/three/src/cameras/Camera.d.ts +++ b/types/three/src/cameras/Camera.d.ts @@ -1,14 +1,10 @@ import { CoordinateSystem } from "../constants.js"; import { Layers } from "../core/Layers.js"; -import { Object3D, Object3DJSON } from "../core/Object3D.js"; +import { Object3D } from "../core/Object3D.js"; import { Matrix4 } from "../math/Matrix4.js"; import { Vector3 } from "../math/Vector3.js"; import { Vector4 } from "../math/Vector4.js"; -export interface CameraJSON extends Object3DJSON { - readonly type: Type; -} - /** * Abstract base class for cameras * @remarks diff --git a/types/three/src/cameras/CubeCamera.d.ts b/types/three/src/cameras/CubeCamera.d.ts index 9ed6b267b..e6e82fb19 100644 --- a/types/three/src/cameras/CubeCamera.d.ts +++ b/types/three/src/cameras/CubeCamera.d.ts @@ -1,12 +1,8 @@ import { CoordinateSystem } from "../constants.js"; -import { Object3D, Object3DJSON } from "../core/Object3D.js"; +import { Object3D } from "../core/Object3D.js"; import { WebGLCubeRenderTarget } from "../renderers/WebGLCubeRenderTarget.js"; import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; -export interface CubeCameraJSON extends Object3DJSON { - readonly type: Type; -} - /** * Creates **6** {@link THREE.PerspectiveCamera | cameras} that render to a {@link THREE.WebGLCubeRenderTarget | WebGLCubeRenderTarget}. * @remarks The cameras are added to the {@link children} array. diff --git a/types/three/src/cameras/OrthographicCamera.d.ts b/types/three/src/cameras/OrthographicCamera.d.ts index 3915aa479..745d11416 100644 --- a/types/three/src/cameras/OrthographicCamera.d.ts +++ b/types/three/src/cameras/OrthographicCamera.d.ts @@ -1,7 +1,14 @@ -import { Camera, CameraJSON } from "./Camera.js"; +import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { Camera } from "./Camera.js"; -export interface OrthographicCameraJSON extends CameraJSON { +export interface OrthographicCameraJSONObject extends Object3DJSONObject { zoom: number; + left: number; + right: number; + top: number; + bottom: number; + near: number; + far: number; view?: { enabled: boolean; @@ -12,13 +19,10 @@ export interface OrthographicCameraJSON extends CameraJSON { +export interface PerspectiveCameraJSONObject extends Object3DJSONObject { fov: number; zoom: number; @@ -25,6 +26,10 @@ export interface PerspectiveCameraJSON; + materials: Record; + textures: Record; + images: Record; + shapes: Record; + skeletons: Record; + animations: Record; + nodes: Record; +} + export interface Object3DEventMap { /** * Fires when the object has been added to its parent object. @@ -638,7 +649,7 @@ export class Object3D ext * Convert the object to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Object containing metadata such as materials, textures or images for the object. */ - toJSON(meta?: { geometries: any; materials: any; textures: any; images: any }): Object3DJSON; + toJSON(meta?: JSONMeta): Object3DJSON; /** * Returns a clone of `this` object and optionally all descendants. From 913b0d438319bfab66a51c9a31ee1671ecf8dda3 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:04:26 -0400 Subject: [PATCH 58/72] BufferGeometry --- types/three/src/core/BufferAttribute.d.ts | 21 ++++++------------ types/three/src/core/BufferGeometry.d.ts | 26 +++++++++-------------- types/three/src/core/Object3D.d.ts | 4 ++-- 3 files changed, 18 insertions(+), 33 deletions(-) diff --git a/types/three/src/core/BufferAttribute.d.ts b/types/three/src/core/BufferAttribute.d.ts index 928b10285..c0dbba8e0 100644 --- a/types/three/src/core/BufferAttribute.d.ts +++ b/types/three/src/core/BufferAttribute.d.ts @@ -13,23 +13,14 @@ export type TypedArray = | Float32Array | Float64Array; -export interface BufferAttributeJSON { - readonly type: Type; - +export interface BufferAttributeJSON { itemSize: number; - - array: ArrayLike; - + type: string; + array: number[]; normalized: boolean; - name: string; - - usage: number; - - updateRage: { - offset: number; - count: number; - }; + name?: string; + usage?: Usage; } /** @@ -355,7 +346,7 @@ export class BufferAttribute { /** * Convert this object to three.js to the `data.attributes` part of {@link https://github.com/mrdoob/three.js/wiki/JSON-Geometry-format-4 | JSON Geometry format v4}, */ - toJSON(): BufferAttributeJSON; + toJSON(): BufferAttributeJSON; } /** diff --git a/types/three/src/core/BufferGeometry.d.ts b/types/three/src/core/BufferGeometry.d.ts index cdf5a60c7..82cf8ad03 100644 --- a/types/three/src/core/BufferGeometry.d.ts +++ b/types/three/src/core/BufferGeometry.d.ts @@ -8,7 +8,6 @@ import { BufferAttribute, BufferAttributeJSON } from "./BufferAttribute.js"; import { EventDispatcher } from "./EventDispatcher.js"; import { GLBufferAttribute } from "./GLBufferAttribute.js"; import { InterleavedBufferAttribute } from "./InterleavedBufferAttribute.js"; -import { Meta } from "./Object3D.js"; export type NormalBufferAttributes = Record; export type NormalOrGLBufferAttributes = Record< @@ -16,26 +15,21 @@ export type NormalOrGLBufferAttributes = Record< BufferAttribute | InterleavedBufferAttribute | GLBufferAttribute >; -export interface BufferGeometryJSON { - readonly metadata: Meta<"BufferGeometry", "BufferGeometry.toJSON">; +export interface BufferGeometryJSON { + metadata?: { version: number; type: string; generator: string }; - readonly type: Type; - - readonly uuid: string; - - name: string; - - userData: Record; - - parameters: Record; + uuid: string; + type: string; - data: { - attributes: Record>; + name?: string; + userData?: Record; - index?: BufferAttributeJSON; + data?: { + attributes: Record; - morphAttributes?: Record>>; + index?: { type: string; array: number[] }; + morphAttributes?: Record; morphTargetsRelative?: boolean; groups?: GeometryGroup[]; diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index 932d3b92d..bd9c66fda 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -9,7 +9,7 @@ import { Vector3, Vector3Tuple } from "../math/Vector3.js"; import { Group } from "../objects/Group.js"; import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; import { Scene } from "../scenes/Scene.js"; -import { BufferGeometry } from "./BufferGeometry.js"; +import { BufferGeometry, BufferGeometryJSON } from "./BufferGeometry.js"; import { EventDispatcher } from "./EventDispatcher.js"; import { Layers } from "./Layers.js"; import { Intersection, Raycaster } from "./Raycaster.js"; @@ -45,7 +45,7 @@ export interface Object3DJSON { } export interface JSONMeta { - geometries: Record; + geometries: Record; materials: Record; textures: Record; images: Record; From dcfbb8220c6185a06c0bcb55232e995e60cc8a97 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:08:42 -0400 Subject: [PATCH 59/72] Curves --- types/three/src/extras/core/Curve.d.ts | 9 +++------ types/three/src/extras/core/CurvePath.d.ts | 6 ++++-- types/three/src/extras/core/Path.d.ts | 6 +++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/types/three/src/extras/core/Curve.d.ts b/types/three/src/extras/core/Curve.d.ts index 4a7fce312..9e3610903 100644 --- a/types/three/src/extras/core/Curve.d.ts +++ b/types/three/src/extras/core/Curve.d.ts @@ -1,13 +1,10 @@ import { Vector2 } from "../../math/Vector2.js"; import { Vector3 } from "../../math/Vector3.js"; -import { Meta } from "../../Three.js"; - -export class CurveJSON { - readonly metadata: Meta<"Curve", "Curve.toJSON">; - - readonly type: Type; +export interface CurveJSON { + metadata: { version: number; type: string; generator: string }; arcLengthDivisions: number; + type: string; } /** diff --git a/types/three/src/extras/core/CurvePath.d.ts b/types/three/src/extras/core/CurvePath.d.ts index db302cc09..3a8577fd1 100644 --- a/types/three/src/extras/core/CurvePath.d.ts +++ b/types/three/src/extras/core/CurvePath.d.ts @@ -2,9 +2,8 @@ import { Vector2 } from "../../math/Vector2.js"; import { Vector3 } from "../../math/Vector3.js"; import { Curve, CurveJSON } from "./Curve.js"; -export interface CurvePathJSON extends CurveJSON { +export interface CurvePathJSON extends CurveJSON { autoClose: boolean; - curves: CurveJSON[]; } @@ -72,4 +71,7 @@ export class CurvePath extends Curve * @param divisions Number of pieces to divide the curve into. Expects a `Integer`. Default `40` */ override getSpacedPoints(divisions?: number): TVector[]; + + toJSON(): CurvePathJSON; + fromJSON(json: CurvePathJSON): this; } diff --git a/types/three/src/extras/core/Path.d.ts b/types/three/src/extras/core/Path.d.ts index c939fdb84..28be15b9c 100644 --- a/types/three/src/extras/core/Path.d.ts +++ b/types/three/src/extras/core/Path.d.ts @@ -1,6 +1,7 @@ import { Vector2, Vector2Tuple } from "../../math/Vector2.js"; import { CurvePath, CurvePathJSON } from "./CurvePath.js"; -export interface PathJSON extends CurvePathJSON<"Path"> { + +export interface PathJSON extends CurvePathJSON { currentPoint: Vector2Tuple; } @@ -159,4 +160,7 @@ export class Path extends CurvePath { * @param points An array of {@link Vector2 | Vector2's} */ splineThru(pts: Vector2[]): this; + + toJSON(): PathJSON; + fromJSON(json: PathJSON): this; } From 06c62f18cdd5f0b30cca9959dea880699b3b930a Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:16:39 -0400 Subject: [PATCH 60/72] Lights --- types/three/src/lights/AmbientLight.d.ts | 6 +----- types/three/src/lights/DirectionalLight.d.ts | 6 +----- .../three/src/lights/DirectionalLightShadow.d.ts | 6 ++---- types/three/src/lights/HemisphereLight.d.ts | 6 +----- types/three/src/lights/Light.d.ts | 16 +++++++--------- types/three/src/lights/LightShadow.d.ts | 15 +++++---------- types/three/src/lights/PointLight.d.ts | 6 +----- types/three/src/lights/SpotLight.d.ts | 6 +----- 8 files changed, 19 insertions(+), 48 deletions(-) diff --git a/types/three/src/lights/AmbientLight.d.ts b/types/three/src/lights/AmbientLight.d.ts index 377986075..7000a37e7 100644 --- a/types/three/src/lights/AmbientLight.d.ts +++ b/types/three/src/lights/AmbientLight.d.ts @@ -1,9 +1,5 @@ import { ColorRepresentation } from "../math/Color.js"; -import { Light, LightJSON } from "./Light.js"; - -export interface AmbientLightJSON extends LightJSON { - readonly type: Type; -} +import { Light } from "./Light.js"; /** * This light globally illuminates all objects in the scene equally. diff --git a/types/three/src/lights/DirectionalLight.d.ts b/types/three/src/lights/DirectionalLight.d.ts index c191aa252..3d43b7d89 100644 --- a/types/three/src/lights/DirectionalLight.d.ts +++ b/types/three/src/lights/DirectionalLight.d.ts @@ -2,11 +2,7 @@ import { Object3D } from "../core/Object3D.js"; import { ColorRepresentation } from "../math/Color.js"; import { Vector3 } from "../math/Vector3.js"; import { DirectionalLightShadow } from "./DirectionalLightShadow.js"; -import { Light, LightJSON } from "./Light.js"; - -export interface DirectionalLightJSON extends LightJSON { - readonly type: Type; -} +import { Light } from "./Light.js"; /** * A light that gets emitted in a specific direction diff --git a/types/three/src/lights/DirectionalLightShadow.d.ts b/types/three/src/lights/DirectionalLightShadow.d.ts index a34ceb7b8..805e4fa0b 100644 --- a/types/three/src/lights/DirectionalLightShadow.d.ts +++ b/types/three/src/lights/DirectionalLightShadow.d.ts @@ -1,7 +1,5 @@ -import { OrthographicCamera, OrthographicCameraJSON } from "../cameras/OrthographicCamera.js"; -import { LightShadow, LightShadowJSON } from "./LightShadow.js"; - -export type DirectionalLightShadowJSON = LightShadowJSON; +import { OrthographicCamera } from "../cameras/OrthographicCamera.js"; +import { LightShadow } from "./LightShadow.js"; /** * This is used internally by {@link DirectionalLight | DirectionalLights} for calculating shadows. diff --git a/types/three/src/lights/HemisphereLight.d.ts b/types/three/src/lights/HemisphereLight.d.ts index 3ee7bc9c3..1a796dfc8 100644 --- a/types/three/src/lights/HemisphereLight.d.ts +++ b/types/three/src/lights/HemisphereLight.d.ts @@ -1,10 +1,6 @@ import { Color, ColorRepresentation } from "../math/Color.js"; import { Vector3 } from "../math/Vector3.js"; -import { Light, LightJSON } from "./Light.js"; - -export interface HemisphereLightJSON extends LightJSON { - readonly type: Type; -} +import { Light } from "./Light.js"; /** * A light source positioned directly above the scene, with color fading from the sky color to the ground color. diff --git a/types/three/src/lights/Light.d.ts b/types/three/src/lights/Light.d.ts index da81ad82b..3ae757e3b 100644 --- a/types/three/src/lights/Light.d.ts +++ b/types/three/src/lights/Light.d.ts @@ -1,24 +1,20 @@ -import { Object3D, Object3DJSON } from "../core/Object3D.js"; +import { JSONMeta, Object3D, Object3DJSON } from "../core/Object3D.js"; import { Color, ColorRepresentation } from "../math/Color.js"; import { LightShadow, LightShadowJSON } from "./LightShadow.js"; -export interface LightJSON - extends Object3DJSON -{ +export interface LightJSON extends Object3DJSON { color: number; intensity: number; groundColor?: number; distance?: number; - angle?: number; - penumbra?: number; decay?: number; + penumbra?: number; - shadow?: Shadow; - - target?: Object3DJSON["uuid"]; + shadow?: LightShadowJSON; + target?: string; } /** @@ -81,4 +77,6 @@ export abstract class Light = CameraJSON> { +export interface LightShadowJSON { intensity?: number; - bias?: number; - normalBias?: number; - radius?: number; - mapSize?: Vector2Tuple; - camera: { - [P in keyof TCamera]: P extends "matrix" ? undefined : TCamera[P]; - }; + camera: Omit; } /** @@ -143,7 +138,7 @@ export class LightShadow { /** * Serialize this LightShadow. */ - toJSON(): {}; + toJSON(): LightShadowJSON; /** * Gets the shadow cameras frustum diff --git a/types/three/src/lights/PointLight.d.ts b/types/three/src/lights/PointLight.d.ts index dd39d52a7..c13044e12 100644 --- a/types/three/src/lights/PointLight.d.ts +++ b/types/three/src/lights/PointLight.d.ts @@ -1,11 +1,7 @@ import { ColorRepresentation } from "../math/Color.js"; -import { Light, LightJSON } from "./Light.js"; +import { Light } from "./Light.js"; import { PointLightShadow } from "./PointLightShadow.js"; -export interface PointLightJSON extends LightJSON { - readonly type: Type; -} - /** * A light that gets emitted from a single point in all directions * @remarks diff --git a/types/three/src/lights/SpotLight.d.ts b/types/three/src/lights/SpotLight.d.ts index 33ad267d1..7f42488a8 100644 --- a/types/three/src/lights/SpotLight.d.ts +++ b/types/three/src/lights/SpotLight.d.ts @@ -2,13 +2,9 @@ import { Object3D } from "../core/Object3D.js"; import { ColorRepresentation } from "../math/Color.js"; import { Vector3 } from "../math/Vector3.js"; import { Texture } from "../textures/Texture.js"; -import { Light, LightJSON } from "./Light.js"; +import { Light } from "./Light.js"; import { SpotLightShadow } from "./SpotLightShadow.js"; -export interface SpotLightJSON extends LightJSON { - readonly type: Type; -} - /** * This light gets emitted from a single point in one direction, along a cone that increases in size the further from the light it gets. * @example From cbe5d40b35793b58820c5d6320544b8df1ef36cd Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:36:44 -0400 Subject: [PATCH 61/72] Objects --- types/three/src/core/Object3D.d.ts | 7 ++++--- types/three/src/objects/BatchedMesh.d.ts | 6 +----- types/three/src/objects/Bone.d.ts | 6 +----- types/three/src/objects/Group.d.ts | 6 +----- types/three/src/objects/InstancedMesh.d.ts | 18 +++++++++++------- types/three/src/objects/LOD.d.ts | 12 +++++++++--- types/three/src/objects/Line.d.ts | 8 ++------ types/three/src/objects/LineLoop.d.ts | 6 +----- types/three/src/objects/LineSegments.d.ts | 6 +----- types/three/src/objects/Mesh.d.ts | 12 +++++++++--- types/three/src/objects/Points.d.ts | 11 ++--------- types/three/src/objects/Skeleton.d.ts | 9 +++------ types/three/src/objects/SkinnedMesh.d.ts | 16 ++++++++++------ types/three/src/objects/Sprite.d.ts | 8 ++------ 14 files changed, 57 insertions(+), 74 deletions(-) diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index bd9c66fda..78d045e94 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -1,4 +1,4 @@ -import { AnimationClip } from "../animation/AnimationClip.js"; +import { AnimationClip, AnimationClipJSON } from "../animation/AnimationClip.js"; import { Camera } from "../cameras/Camera.js"; import { Material } from "../materials/Material.js"; import { Euler } from "../math/Euler.js"; @@ -7,6 +7,7 @@ import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; import { Quaternion } from "../math/Quaternion.js"; import { Vector3, Vector3Tuple } from "../math/Vector3.js"; import { Group } from "../objects/Group.js"; +import { SkeletonJSON } from "../objects/Skeleton.js"; import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; import { Scene } from "../scenes/Scene.js"; import { BufferGeometry, BufferGeometryJSON } from "./BufferGeometry.js"; @@ -50,8 +51,8 @@ export interface JSONMeta { textures: Record; images: Record; shapes: Record; - skeletons: Record; - animations: Record; + skeletons: Record; + animations: Record; nodes: Record; } diff --git a/types/three/src/objects/BatchedMesh.d.ts b/types/three/src/objects/BatchedMesh.d.ts index f5d57277d..2669b5c08 100644 --- a/types/three/src/objects/BatchedMesh.d.ts +++ b/types/three/src/objects/BatchedMesh.d.ts @@ -5,11 +5,7 @@ import { Box3 } from "../math/Box3.js"; import { Color } from "../math/Color.js"; import { Matrix4 } from "../math/Matrix4.js"; import { Sphere } from "../math/Sphere.js"; -import { Mesh, MeshJSON } from "./Mesh.js"; - -export interface BatchedMeshJSON extends MeshJSON { - readonly type: Type; -} +import { Mesh } from "./Mesh.js"; /** * A special version of {@link Mesh} with multi draw batch rendering support. Use {@link BatchedMesh} if you have to diff --git a/types/three/src/objects/Bone.d.ts b/types/three/src/objects/Bone.d.ts index c874f1189..3400ea1b6 100644 --- a/types/three/src/objects/Bone.d.ts +++ b/types/three/src/objects/Bone.d.ts @@ -1,8 +1,4 @@ -import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; - -export interface BoneJSON extends Object3DJSON { - readonly type: Type; -} +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; /** * A {@link Bone} which is part of a {@link THREE.Skeleton | Skeleton} diff --git a/types/three/src/objects/Group.d.ts b/types/three/src/objects/Group.d.ts index 8203347cd..bceb11e5f 100644 --- a/types/three/src/objects/Group.d.ts +++ b/types/three/src/objects/Group.d.ts @@ -1,8 +1,4 @@ -import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; - -export interface GroupJSON extends Object3DJSON { - readonly type: Type; -} +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; /** * Its purpose is to make working with groups of objects syntactically clearer. diff --git a/types/three/src/objects/InstancedMesh.d.ts b/types/three/src/objects/InstancedMesh.d.ts index cbf824bf0..b239afb7a 100644 --- a/types/three/src/objects/InstancedMesh.d.ts +++ b/types/three/src/objects/InstancedMesh.d.ts @@ -1,21 +1,23 @@ import { BufferAttributeJSON } from "./../core/BufferAttribute.js"; import { BufferGeometry } from "../core/BufferGeometry.js"; import { InstancedBufferAttribute } from "../core/InstancedBufferAttribute.js"; -import { Object3DEventMap } from "../core/Object3D.js"; +import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Box3 } from "../math/Box3.js"; import { Color } from "../math/Color.js"; -import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; +import { Matrix4 } from "../math/Matrix4.js"; import { Sphere } from "../math/Sphere.js"; import { DataTexture } from "../textures/DataTexture.js"; -import { Mesh, MeshJSON } from "./Mesh.js"; +import { Mesh, MeshJSONObject } from "./Mesh.js"; -export interface InstancedMeshJSON extends MeshJSON { +export interface InstancedMeshJSONObject extends MeshJSONObject { count: number; + instanceMatrix: BufferAttributeJSON; + instanceColor?: BufferAttributeJSON; +} - instanceMatrix: Matrix4Tuple; - - instanceColor: BufferAttributeJSON; +export interface InstancedMeshJSON extends MeshJSONObject { + object: InstancedMeshJSONObject; } export interface InstancedMeshEventMap extends Object3DEventMap { @@ -172,4 +174,6 @@ export class InstancedMesh< * Call this method whenever this instance is no longer used in your app. */ dispose(): this; + + toJSON(meta?: JSONMeta): InstancedMeshJSON; } diff --git a/types/three/src/objects/LOD.d.ts b/types/three/src/objects/LOD.d.ts index 0fc4c3c05..ec6657c7f 100644 --- a/types/three/src/objects/LOD.d.ts +++ b/types/three/src/objects/LOD.d.ts @@ -1,16 +1,20 @@ import { Camera } from "../cameras/Camera.js"; -import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; -export interface LODJSON extends Object3DJSON { +export interface LODJSONObject extends Object3DJSONObject { autoUpdate?: boolean; levels: Array<{ - object: Object3DJSON["uuid"]; + object: string; distance: number; hysteresis: number; }>; } +export interface LODJSON extends Object3DJSON { + object: LODJSONObject; +} + /** * Every level is associated with an object, and rendering can be switched between them at the distances specified * @remarks @@ -95,4 +99,6 @@ export class LOD extends * @param camera */ update(camera: Camera): void; + + toJSON(meta?: JSONMeta): LODJSON; } diff --git a/types/three/src/objects/Line.d.ts b/types/three/src/objects/Line.d.ts index 23ed2dfa4..2d76dec69 100644 --- a/types/three/src/objects/Line.d.ts +++ b/types/three/src/objects/Line.d.ts @@ -1,11 +1,7 @@ -import { BufferGeometry, BufferGeometryJSON } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; +import { BufferGeometry } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; -export interface LineJSON extends Object3DJSON { - readonly type: Type; -} - /** * A continuous line. * @remarks diff --git a/types/three/src/objects/LineLoop.d.ts b/types/three/src/objects/LineLoop.d.ts index f5915eb8a..0a070a838 100644 --- a/types/three/src/objects/LineLoop.d.ts +++ b/types/three/src/objects/LineLoop.d.ts @@ -1,11 +1,7 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; import { Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; -import { Line, LineJSON } from "./Line.js"; - -export interface LineLoopJSON extends LineJSON { - readonly type: Type; -} +import { Line } from "./Line.js"; /** * A continuous line that connects back to the start. diff --git a/types/three/src/objects/LineSegments.d.ts b/types/three/src/objects/LineSegments.d.ts index a75fb57dd..9a8199bdc 100644 --- a/types/three/src/objects/LineSegments.d.ts +++ b/types/three/src/objects/LineSegments.d.ts @@ -1,11 +1,7 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; import { Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; -import { Line, LineJSON } from "./Line.js"; - -export interface LineSegmentsJSON extends LineJSON { - readonly type: Type; -} +import { Line } from "./Line.js"; /** * A series of lines drawn between pairs of vertices. diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index 83a5e175b..38dad1c73 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -1,10 +1,14 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Vector3 } from "../math/Vector3.js"; -export interface MeshJSON extends Object3DJSON { - readonly type: Type; +export interface MeshJSONObject extends Object3DJSONObject { + geometry: string; +} + +export interface MeshJSON extends Object3DJSON { + object: MeshJSONObject; } /** @@ -85,4 +89,6 @@ export class Mesh< * @param target */ getVertexPosition(index: number, target: Vector3): Vector3; + + toJSON(meta?: JSONMeta): MeshJSON; } diff --git a/types/three/src/objects/Points.d.ts b/types/three/src/objects/Points.d.ts index 1822f3102..3cba2c74b 100644 --- a/types/three/src/objects/Points.d.ts +++ b/types/three/src/objects/Points.d.ts @@ -1,14 +1,7 @@ -import { BufferAttribute } from "../core/BufferAttribute.js"; -import { BufferGeometry, BufferGeometryJSON, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; -import { GLBufferAttribute } from "../core/GLBufferAttribute.js"; -import { InterleavedBufferAttribute } from "../core/InterleavedBufferAttribute.js"; -import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; +import { BufferGeometry, NormalOrGLBufferAttributes } from "../core/BufferGeometry.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; -export interface PointsJSON extends Object3DJSON { - readonly type: Type; -} - /** * A class for displaying {@link Points} * @remarks diff --git a/types/three/src/objects/Skeleton.d.ts b/types/three/src/objects/Skeleton.d.ts index 5b30fead1..aaeb3198b 100644 --- a/types/three/src/objects/Skeleton.d.ts +++ b/types/three/src/objects/Skeleton.d.ts @@ -1,15 +1,12 @@ import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; import { DataTexture } from "../textures/DataTexture.js"; -import { Meta } from "../Three.js"; import { Bone } from "./Bone.js"; -export interface SkeletonJSON { - readonly metadata: Meta<"Skeleton", "Skeleton.toJSON">; - - readonly uuid: string; +export interface SkeletonJSON { + metadata: { version: number; type: string; generator: string }; bones: string[]; - boneInverses: Matrix4Tuple[]; + uuid: string; } /** diff --git a/types/three/src/objects/SkinnedMesh.d.ts b/types/three/src/objects/SkinnedMesh.d.ts index ca8784665..35149c5d1 100644 --- a/types/three/src/objects/SkinnedMesh.d.ts +++ b/types/three/src/objects/SkinnedMesh.d.ts @@ -1,20 +1,22 @@ import { BindMode } from "../constants.js"; import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3DEventMap } from "../core/Object3D.js"; +import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Box3 } from "../math/Box3.js"; import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; import { Sphere } from "../math/Sphere.js"; import { Vector3 } from "../math/Vector3.js"; -import { Mesh, MeshJSON } from "./Mesh.js"; +import { Mesh, MeshJSON, MeshJSONObject } from "./Mesh.js"; import { Skeleton } from "./Skeleton.js"; -export interface SkinnedMeshJSON extends MeshJSON { - bindMode: string; - +export interface SkinnedMeshJSONObject extends MeshJSONObject { + bindMode: BindMode; bindMatrix: Matrix4Tuple; + skeleton?: string; +} - skeleton?: Skeleton["uuid"]; +export interface SkinnedMeshJSON extends MeshJSON { + object: SkinnedMeshJSONObject; } /** @@ -153,4 +155,6 @@ export class SkinnedMesh< * @param vector */ applyBoneTransform(index: number, vector: Vector3): Vector3; + + toJSON(meta?: JSONMeta): SkinnedMeshJSON; } diff --git a/types/three/src/objects/Sprite.d.ts b/types/three/src/objects/Sprite.d.ts index 34f1988af..427b8b414 100644 --- a/types/three/src/objects/Sprite.d.ts +++ b/types/three/src/objects/Sprite.d.ts @@ -1,11 +1,7 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; -import { Object3D, Object3DEventMap, Object3DJSON } from "../core/Object3D.js"; +import { Object3D, Object3DEventMap } from "../core/Object3D.js"; import { SpriteMaterial } from "../materials/Materials.js"; -import { Vector2, Vector2Tuple } from "../math/Vector2.js"; - -export interface SpriteJSON extends Object3DJSON { - readonly type: Type; -} +import { Vector2 } from "../math/Vector2.js"; /** * A {@link Sprite} is a plane that always faces towards the camera, generally with a partially transparent texture applied. From 7202b9226e0b37e30cd9db4dc7779e0dcc74f04c Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:44:06 -0400 Subject: [PATCH 62/72] Scenes --- types/three/src/scenes/Fog.d.ts | 35 +++-------------------------- types/three/src/scenes/FogExp2.d.ts | 12 +++++++--- types/three/src/scenes/Scene.d.ts | 22 +++++++++--------- 3 files changed, 24 insertions(+), 45 deletions(-) diff --git a/types/three/src/scenes/Fog.d.ts b/types/three/src/scenes/Fog.d.ts index 59010c168..fc0f18019 100644 --- a/types/three/src/scenes/Fog.d.ts +++ b/types/three/src/scenes/Fog.d.ts @@ -1,42 +1,13 @@ import { Color, ColorRepresentation } from "../math/Color.js"; export interface FogJSON { - type: "Fog"; - + type: string; name: string; - color: number; - near: number; - far: number; } -export interface FogBase { - /** - * Optional name of the `Fog` object - * @remarks _(doesn't need to be unique)_. - * @defaultValue `""` - */ - name: string; - - /** - * Fog color. - * @remarks If set to black, far away objects will be rendered black. - */ - color: Color; - - /** - * Returns a new Fog instance with the same parameters as this one. - */ - clone(): FogBase; - - /** - * Return Fog data in JSON format. - */ - toJSON(): any; -} - /** * This class contains the parameters that define linear fog, i.e., that grows linearly denser with the distance. * @example @@ -47,7 +18,7 @@ export interface FogBase { * @see {@link https://threejs.org/docs/index.html#api/en/scenes/Fog | Official Documentation} * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/Fog.js | Source} */ -export class Fog implements FogBase { +export class Fog { /** * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property * @remarks @@ -102,5 +73,5 @@ export class Fog implements FogBase { /** * Return {@link Fog} data in JSON format. */ - toJSON(): any; + toJSON(): FogJSON; } diff --git a/types/three/src/scenes/FogExp2.d.ts b/types/three/src/scenes/FogExp2.d.ts index df60aad31..af00981e6 100644 --- a/types/three/src/scenes/FogExp2.d.ts +++ b/types/three/src/scenes/FogExp2.d.ts @@ -1,5 +1,11 @@ import { Color, ColorRepresentation } from "../math/Color.js"; -import { FogBase } from "./Fog.js"; + +export interface FogExp2JSON { + type: string; + name: string; + color: number; + density: number; +} /** * This class contains the parameters that define exponential squared fog, which gives a clear view near the camera and a faster than exponentially densening fog farther from the camera. @@ -12,7 +18,7 @@ import { FogBase } from "./Fog.js"; * @see {@link https://threejs.org/docs/index.html#api/en/scenes/FogExp2 | Official Documentation} * @see {@link https://github.com/mrdoob/three.js/blob/master/src/scenes/FogExp2.js | Source} */ -export class FogExp2 implements FogBase { +export class FogExp2 { /** * The color parameter is passed to the {@link THREE.Color | Color} constructor to set the color property * @remarks Color can be a hexadecimal integer or a CSS-style string. @@ -56,5 +62,5 @@ export class FogExp2 implements FogBase { /** * Return {@link FogExp2} data in JSON format. */ - toJSON(): any; + toJSON(): FogExp2JSON; } diff --git a/types/three/src/scenes/Scene.d.ts b/types/three/src/scenes/Scene.d.ts index 5de03d9f6..c2f43afd7 100644 --- a/types/three/src/scenes/Scene.d.ts +++ b/types/three/src/scenes/Scene.d.ts @@ -1,23 +1,25 @@ -import { Object3D, Object3DJSON } from "../core/Object3D.js"; +import { JSONMeta, Object3D, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Color } from "../math/Color.js"; import { Euler, EulerTuple } from "../math/Euler.js"; import { CubeTexture } from "../textures/CubeTexture.js"; import { Texture } from "../textures/Texture.js"; -import { FogBase, FogJSON } from "./Fog.js"; +import { Fog, FogJSON } from "./Fog.js"; +import { FogExp2, FogExp2JSON } from "./FogExp2.js"; -export interface SceneJSON extends Object3DJSON { - fog?: FogJSON; // Assuming the fog has a string representation; adjust as needed. +export interface SceneJSONObject extends Object3DJSONObject { + fog?: FogJSON | FogExp2JSON; backgroundBlurriness?: number; - backgroundIntensity?: number; - - backgroundRotation: EulerTuple; // Assuming it's a quaternion + backgroundRotation: EulerTuple; environmentIntensity?: number; + environmentRotation: EulerTuple; +} - environmentRotation: EulerTuple; // Assuming it's a quaternion +export interface SceneJSON extends Object3DJSON { + object: SceneJSONObject; } /** @@ -51,7 +53,7 @@ export class Scene extends Object3D { * A {@link Fog | fog} instance defining the type of fog that affects everything rendered in the scene. * @defaultValue `null` */ - fog: FogBase | null; + fog: Fog | FogExp2 | null; /** * Sets the blurriness of the background. Only influences environment maps assigned to {@link THREE.Scene.background | Scene.background}. @@ -112,5 +114,5 @@ export class Scene extends Object3D { * Convert the {@link Scene} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Object containing metadata such as textures or images for the scene. */ - toJSON(meta?: any): any; + toJSON(meta?: JSONMeta): SceneJSON; } From e780437ca66c519bc222b19d77d20f3eb859f5d6 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:52:44 -0400 Subject: [PATCH 63/72] Textures --- types/three/src/core/Object3D.d.ts | 6 +++-- types/three/src/textures/Source.d.ts | 9 +++---- types/three/src/textures/Texture.d.ts | 38 +++++++++++---------------- 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index 78d045e94..58ecc8b77 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -10,6 +10,8 @@ import { Group } from "../objects/Group.js"; import { SkeletonJSON } from "../objects/Skeleton.js"; import { WebGLRenderer } from "../renderers/WebGLRenderer.js"; import { Scene } from "../scenes/Scene.js"; +import { SourceJSON } from "../textures/Source.js"; +import { TextureJSON } from "../textures/Texture.js"; import { BufferGeometry, BufferGeometryJSON } from "./BufferGeometry.js"; import { EventDispatcher } from "./EventDispatcher.js"; import { Layers } from "./Layers.js"; @@ -48,8 +50,8 @@ export interface Object3DJSON { export interface JSONMeta { geometries: Record; materials: Record; - textures: Record; - images: Record; + textures: Record; + images: Record; shapes: Record; skeletons: Record; animations: Record; diff --git a/types/three/src/textures/Source.d.ts b/types/three/src/textures/Source.d.ts index c43f01d22..404d1d8a1 100644 --- a/types/three/src/textures/Source.d.ts +++ b/types/three/src/textures/Source.d.ts @@ -1,16 +1,15 @@ -export type SourceData = +export type SerializedImage = | string | { data: number[]; width: number; height: number; - type: Type; + type: string; }; export class SourceJSON { - readonly uuid: string; - - url: SourceData | SourceData[]; + uuid: string; + url: SerializedImage | SerializedImage[]; } /** diff --git a/types/three/src/textures/Texture.d.ts b/types/three/src/textures/Texture.d.ts index d0483eb76..48a178966 100644 --- a/types/three/src/textures/Texture.d.ts +++ b/types/three/src/textures/Texture.d.ts @@ -13,52 +13,44 @@ import { import { EventDispatcher } from "../core/EventDispatcher.js"; import { Matrix3 } from "../math/Matrix3.js"; import { Vector2 } from "../math/Vector2.js"; -import { Meta } from "../Three.js"; import { CompressedTextureMipmap } from "./CompressedTexture.js"; import { CubeTexture } from "./CubeTexture.js"; -import { Source, SourceJSON } from "./Source.js"; +import { Source } from "./Source.js"; -export interface TextureJSON { - readonly metadata: Meta<"Texture", "Texture.toJSON">; - - readonly type: Type; - - readonly uuid: string; +export interface TextureJSON { + metadata: { version: number; type: string; generator: string }; + uuid: string; name: string; - userData: Record; + image: string; - image: SourceJSON["uuid"]; - - mapping: number; - cannel: number; + mapping: AnyMapping; + channel: number; repeat: [x: number, y: number]; - offset: [x: number, y: number]; - center: [x: number, y: number]; - rotation: number; wrap: [wrapS: number, wrapT: number]; - format: number; - internalFormat: number; - - encoding: number; + format: AnyPixelFormat; + internalFormat: PixelFormatGPU | null; + type: TextureDataType; + colorSpace: ColorSpace; - minFilter: number; - magFilter: number; + minFilter: MinificationTextureFilter; + magFilter: MagnificationTextureFilter; anisotropy: number; flipY: boolean; generateMipmaps: boolean; premultiplyAlpha: boolean; - unpackAlignment: number; + + userData?: Record; } /** Shim for OffscreenCanvas. */ From e6d91e9a994fc02bbc489bf41ee6fa8798d45195 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:54:53 -0400 Subject: [PATCH 64/72] Add examples --- examples-jsm/examples/nodes/Nodes.ts | 414 +++++ .../nodes/accessors/BufferAttributeNode.ts | 131 ++ .../examples/nodes/accessors/TextureNode.ts | 327 ++++ examples-jsm/examples/nodes/code/CodeNode.ts | 66 + .../examples/nodes/code/FunctionNode.ts | 100 ++ .../examples/nodes/core/ContextNode.ts | 55 + examples-jsm/examples/nodes/core/InputNode.ts | 65 + examples-jsm/examples/nodes/core/Node.ts | 424 ++++++ .../examples/nodes/core/NodeAttribute.ts | 11 + .../examples/nodes/core/NodeBuilder.ts | 1119 ++++++++++++++ examples-jsm/examples/nodes/core/NodeCache.ts | 26 + examples-jsm/examples/nodes/core/NodeCode.ts | 11 + examples-jsm/examples/nodes/core/NodeFrame.ts | 127 ++ .../examples/nodes/core/NodeFunction.ts | 16 + .../examples/nodes/core/NodeKeywords.ts | 58 + .../examples/nodes/core/NodeParser.ts | 7 + .../examples/nodes/core/NodeUniform.ts | 27 + examples-jsm/examples/nodes/core/NodeUtils.ts | 132 ++ examples-jsm/examples/nodes/core/NodeVar.ts | 10 + .../examples/nodes/core/NodeVarying.ts | 13 + examples-jsm/examples/nodes/core/StackNode.ts | 71 + .../examples/nodes/core/StructTypeNode.ts | 18 + .../examples/nodes/core/UniformGroupNode.ts | 30 + .../examples/nodes/core/UniformNode.ts | 90 ++ examples-jsm/examples/nodes/core/constants.ts | 28 + examples-jsm/examples/nodes/fog/FogNode.ts | 38 + .../examples/nodes/gpgpu/ComputeNode.ts | 67 + .../nodes/lighting/EnvironmentNode.ts | 119 ++ .../nodes/lighting/LightingContextNode.ts | 58 + .../examples/nodes/lighting/LightsNode.ts | 170 +++ .../examples/nodes/materials/NodeMaterial.ts | 514 +++++++ .../examples/nodes/shadernode/ShaderNode.ts | 532 +++++++ .../examples/renderers/common/Animation.ts | 38 + .../examples/renderers/common/Attributes.ts | 53 + .../examples/renderers/common/Backend.ts | 165 ++ .../examples/renderers/common/Background.ts | 118 ++ .../examples/renderers/common/BindGroup.ts | 12 + .../examples/renderers/common/Binding.ts | 17 + .../examples/renderers/common/Bindings.ts | 161 ++ .../examples/renderers/common/Buffer.ts | 28 + .../examples/renderers/common/BufferUtils.ts | 23 + .../examples/renderers/common/ChainMap.ts | 43 + .../renderers/common/ClippingContext.ts | 128 ++ .../examples/renderers/common/Color4.ts | 27 + .../renderers/common/ComputePipeline.ts | 13 + .../examples/renderers/common/Constants.ts | 14 + .../renderers/common/CubeRenderTarget.ts | 69 + .../examples/renderers/common/DataMap.ts | 38 + .../examples/renderers/common/Geometries.ts | 182 +++ .../examples/renderers/common/Info.ts | 95 ++ .../examples/renderers/common/Pipeline.ts | 9 + .../examples/renderers/common/Pipelines.ts | 270 ++++ .../renderers/common/ProgrammableStage.ts | 16 + .../examples/renderers/common/RenderBundle.ts | 12 + .../renderers/common/RenderBundles.ts | 28 + .../renderers/common/RenderContext.ts | 39 + .../renderers/common/RenderContexts.ts | 47 + .../examples/renderers/common/RenderList.ts | 145 ++ .../examples/renderers/common/RenderLists.ts | 28 + .../examples/renderers/common/RenderObject.ts | 215 +++ .../renderers/common/RenderObjects.ts | 100 ++ .../renderers/common/RenderPipeline.ts | 12 + .../examples/renderers/common/Renderer.ts | 1347 +++++++++++++++++ .../renderers/common/SampledTexture.ts | 61 + .../examples/renderers/common/Sampler.ts | 14 + .../renderers/common/StorageBuffer.ts | 13 + .../examples/renderers/common/Textures.ts | 288 ++++ .../examples/renderers/common/Uniform.ts | 100 ++ .../renderers/common/UniformBuffer.ts | 11 + .../renderers/common/UniformsGroup.ts | 277 ++++ .../renderers/common/extras/PMREMGenerator.ts | 659 ++++++++ .../common/nodes/NodeBuilderState.ts | 55 + .../renderers/common/nodes/NodeUniform.ts | 103 ++ .../common/nodes/NodeUniformsGroup.ts | 30 + .../examples/renderers/common/nodes/Nodes.ts | 394 +++++ .../examples/renderers/webgl/WebGLBackend.ts | 1268 ++++++++++++++++ .../renderers/webgl/nodes/GLSLNodeBuilder.ts | 747 +++++++++ .../renderers/webgpu/WebGPUBackend.ts | 1205 +++++++++++++++ .../renderers/webgpu/WebGPURenderer.ts | 43 + .../renderers/webgpu/nodes/WGSLNodeBuilder.ts | 1017 +++++++++++++ .../webgpu/nodes/WGSLNodeFunction.ts | 127 ++ .../renderers/webgpu/nodes/WGSLNodeParser.ts | 10 + 82 files changed, 14788 insertions(+) create mode 100644 examples-jsm/examples/nodes/Nodes.ts create mode 100644 examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts create mode 100644 examples-jsm/examples/nodes/accessors/TextureNode.ts create mode 100644 examples-jsm/examples/nodes/code/CodeNode.ts create mode 100644 examples-jsm/examples/nodes/code/FunctionNode.ts create mode 100644 examples-jsm/examples/nodes/core/ContextNode.ts create mode 100644 examples-jsm/examples/nodes/core/InputNode.ts create mode 100644 examples-jsm/examples/nodes/core/Node.ts create mode 100644 examples-jsm/examples/nodes/core/NodeAttribute.ts create mode 100644 examples-jsm/examples/nodes/core/NodeBuilder.ts create mode 100644 examples-jsm/examples/nodes/core/NodeCache.ts create mode 100644 examples-jsm/examples/nodes/core/NodeCode.ts create mode 100644 examples-jsm/examples/nodes/core/NodeFrame.ts create mode 100644 examples-jsm/examples/nodes/core/NodeFunction.ts create mode 100644 examples-jsm/examples/nodes/core/NodeKeywords.ts create mode 100644 examples-jsm/examples/nodes/core/NodeParser.ts create mode 100644 examples-jsm/examples/nodes/core/NodeUniform.ts create mode 100644 examples-jsm/examples/nodes/core/NodeUtils.ts create mode 100644 examples-jsm/examples/nodes/core/NodeVar.ts create mode 100644 examples-jsm/examples/nodes/core/NodeVarying.ts create mode 100644 examples-jsm/examples/nodes/core/StackNode.ts create mode 100644 examples-jsm/examples/nodes/core/StructTypeNode.ts create mode 100644 examples-jsm/examples/nodes/core/UniformGroupNode.ts create mode 100644 examples-jsm/examples/nodes/core/UniformNode.ts create mode 100644 examples-jsm/examples/nodes/core/constants.ts create mode 100644 examples-jsm/examples/nodes/fog/FogNode.ts create mode 100644 examples-jsm/examples/nodes/gpgpu/ComputeNode.ts create mode 100644 examples-jsm/examples/nodes/lighting/EnvironmentNode.ts create mode 100644 examples-jsm/examples/nodes/lighting/LightingContextNode.ts create mode 100644 examples-jsm/examples/nodes/lighting/LightsNode.ts create mode 100644 examples-jsm/examples/nodes/materials/NodeMaterial.ts create mode 100644 examples-jsm/examples/nodes/shadernode/ShaderNode.ts create mode 100644 examples-jsm/examples/renderers/common/Animation.ts create mode 100644 examples-jsm/examples/renderers/common/Attributes.ts create mode 100644 examples-jsm/examples/renderers/common/Backend.ts create mode 100644 examples-jsm/examples/renderers/common/Background.ts create mode 100644 examples-jsm/examples/renderers/common/BindGroup.ts create mode 100644 examples-jsm/examples/renderers/common/Binding.ts create mode 100644 examples-jsm/examples/renderers/common/Bindings.ts create mode 100644 examples-jsm/examples/renderers/common/Buffer.ts create mode 100644 examples-jsm/examples/renderers/common/BufferUtils.ts create mode 100644 examples-jsm/examples/renderers/common/ChainMap.ts create mode 100644 examples-jsm/examples/renderers/common/ClippingContext.ts create mode 100644 examples-jsm/examples/renderers/common/Color4.ts create mode 100644 examples-jsm/examples/renderers/common/ComputePipeline.ts create mode 100644 examples-jsm/examples/renderers/common/Constants.ts create mode 100644 examples-jsm/examples/renderers/common/CubeRenderTarget.ts create mode 100644 examples-jsm/examples/renderers/common/DataMap.ts create mode 100644 examples-jsm/examples/renderers/common/Geometries.ts create mode 100644 examples-jsm/examples/renderers/common/Info.ts create mode 100644 examples-jsm/examples/renderers/common/Pipeline.ts create mode 100644 examples-jsm/examples/renderers/common/Pipelines.ts create mode 100644 examples-jsm/examples/renderers/common/ProgrammableStage.ts create mode 100644 examples-jsm/examples/renderers/common/RenderBundle.ts create mode 100644 examples-jsm/examples/renderers/common/RenderBundles.ts create mode 100644 examples-jsm/examples/renderers/common/RenderContext.ts create mode 100644 examples-jsm/examples/renderers/common/RenderContexts.ts create mode 100644 examples-jsm/examples/renderers/common/RenderList.ts create mode 100644 examples-jsm/examples/renderers/common/RenderLists.ts create mode 100644 examples-jsm/examples/renderers/common/RenderObject.ts create mode 100644 examples-jsm/examples/renderers/common/RenderObjects.ts create mode 100644 examples-jsm/examples/renderers/common/RenderPipeline.ts create mode 100644 examples-jsm/examples/renderers/common/Renderer.ts create mode 100644 examples-jsm/examples/renderers/common/SampledTexture.ts create mode 100644 examples-jsm/examples/renderers/common/Sampler.ts create mode 100644 examples-jsm/examples/renderers/common/StorageBuffer.ts create mode 100644 examples-jsm/examples/renderers/common/Textures.ts create mode 100644 examples-jsm/examples/renderers/common/Uniform.ts create mode 100644 examples-jsm/examples/renderers/common/UniformBuffer.ts create mode 100644 examples-jsm/examples/renderers/common/UniformsGroup.ts create mode 100644 examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts create mode 100644 examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts create mode 100644 examples-jsm/examples/renderers/common/nodes/NodeUniform.ts create mode 100644 examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts create mode 100644 examples-jsm/examples/renderers/common/nodes/Nodes.ts create mode 100644 examples-jsm/examples/renderers/webgl/WebGLBackend.ts create mode 100644 examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts create mode 100644 examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts create mode 100644 examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts create mode 100644 examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts create mode 100644 examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts create mode 100644 examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts diff --git a/examples-jsm/examples/nodes/Nodes.ts b/examples-jsm/examples/nodes/Nodes.ts new file mode 100644 index 000000000..da3779345 --- /dev/null +++ b/examples-jsm/examples/nodes/Nodes.ts @@ -0,0 +1,414 @@ +// @TODO: We can simplify "export { default as SomeNode, other, exports } from '...'" to just "export * from '...'" if we will use only named exports +// this will also solve issues like "import TempNode from '../core/Node.js'" + +// constants +export * from './core/constants.js'; + +// core +export { default as AssignNode, assign } from './core/AssignNode.js'; +export { default as AttributeNode, attribute } from './core/AttributeNode.js'; +export { default as BypassNode, bypass } from './core/BypassNode.js'; +export { default as CacheNode, cache } from './core/CacheNode.js'; +export { default as ConstNode } from './core/ConstNode.js'; +export { default as ContextNode, context, label } from './core/ContextNode.js'; +export { default as IndexNode, vertexIndex, instanceIndex } from './core/IndexNode.js'; +export { default as LightingModel } from './core/LightingModel.js'; +export { default as Node, addNodeClass, createNodeFromType } from './core/Node.js'; +export { default as VarNode, temp } from './core/VarNode.js'; +export { default as NodeAttribute } from './core/NodeAttribute.js'; +export { default as NodeBuilder } from './core/NodeBuilder.js'; +export { default as NodeCache } from './core/NodeCache.js'; +export { default as NodeCode } from './core/NodeCode.js'; +export { default as NodeFrame } from './core/NodeFrame.js'; +export { default as NodeFunctionInput } from './core/NodeFunctionInput.js'; +export { default as NodeKeywords } from './core/NodeKeywords.js'; +export { default as NodeUniform } from './core/NodeUniform.js'; +export { default as NodeVar } from './core/NodeVar.js'; +export { default as NodeVarying } from './core/NodeVarying.js'; +export { default as ParameterNode, parameter } from './core/ParameterNode.js'; +export { + default as PropertyNode, + property, + varyingProperty, + output, + diffuseColor, + roughness, + metalness, + clearcoat, + clearcoatRoughness, + sheen, + sheenRoughness, + iridescence, + iridescenceIOR, + iridescenceThickness, + specularColor, + shininess, + dashSize, + gapSize, + pointWidth, + alphaT, + anisotropy, + anisotropyB, + anisotropyT, +} from './core/PropertyNode.js'; +export { default as StackNode, stack } from './core/StackNode.js'; +export { default as TempNode } from './core/TempNode.js'; +export { + default as UniformGroupNode, + uniformGroup, + objectGroup, + renderGroup, + frameGroup, +} from './core/UniformGroupNode.js'; +export { default as UniformNode, uniform } from './core/UniformNode.js'; +export { default as VaryingNode, varying } from './core/VaryingNode.js'; +export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js'; + +import * as NodeUtils from './core/NodeUtils.js'; +export { NodeUtils }; + +// math +export { + default as MathNode, + PI, + PI2, + EPSILON, + INFINITY, + radians, + degrees, + exp, + exp2, + log, + log2, + sqrt, + inverseSqrt, + floor, + ceil, + normalize, + fract, + sin, + cos, + tan, + asin, + acos, + atan, + abs, + sign, + length, + lengthSq, + negate, + oneMinus, + dFdx, + dFdy, + round, + reciprocal, + trunc, + fwidth, + bitcast, + atan2, + min, + max, + mod, + step, + reflect, + distance, + difference, + dot, + cross, + pow, + pow2, + pow3, + pow4, + transformDirection, + mix, + clamp, + saturate, + refract, + smoothstep, + faceForward, + cbrt, + transpose, + all, + any, + equals, +} from './math/MathNode.js'; + +export { + default as OperatorNode, + add, + sub, + mul, + div, + remainder, + equal, + lessThan, + greaterThan, + lessThanEqual, + greaterThanEqual, + and, + or, + not, + xor, + bitAnd, + bitNot, + bitOr, + bitXor, + shiftLeft, + shiftRight, +} from './math/OperatorNode.js'; +export { default as CondNode, cond } from './math/CondNode.js'; +export { default as HashNode, hash } from './math/HashNode.js'; + +// math utils +export { parabola, gain, pcurve, sinc } from './math/MathUtils.js'; +export { triNoise3D } from './math/TriNoise3D.js'; + +// utils +export { default as ArrayElementNode } from './utils/ArrayElementNode.js'; +export { default as ConvertNode } from './utils/ConvertNode.js'; +export { default as DiscardNode, discard, Return } from './utils/DiscardNode.js'; +export { default as EquirectUVNode, equirectUV } from './utils/EquirectUVNode.js'; +export { default as FunctionOverloadingNode, overloadingFn } from './utils/FunctionOverloadingNode.js'; +export { default as JoinNode } from './utils/JoinNode.js'; +export { default as LoopNode, loop, Continue, Break } from './utils/LoopNode.js'; +export { default as MatcapUVNode, matcapUV } from './utils/MatcapUVNode.js'; +export { default as MaxMipLevelNode, maxMipLevel } from './utils/MaxMipLevelNode.js'; +export { default as OscNode, oscSine, oscSquare, oscTriangle, oscSawtooth } from './utils/OscNode.js'; +export { default as PackingNode, directionToColor, colorToDirection } from './utils/PackingNode.js'; +export { default as RemapNode, remap, remapClamp } from './utils/RemapNode.js'; +export { default as RotateUVNode, rotateUV } from './utils/RotateUVNode.js'; +export { default as RotateNode, rotate } from './utils/RotateNode.js'; +export { default as SetNode } from './utils/SetNode.js'; +export { default as SplitNode } from './utils/SplitNode.js'; +export { default as SpriteSheetUVNode, spritesheetUV } from './utils/SpriteSheetUVNode.js'; +export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js'; +export { default as TimerNode, timerLocal, timerGlobal, timerDelta, frameId } from './utils/TimerNode.js'; +export { + default as TriplanarTexturesNode, + triplanarTextures, + triplanarTexture, +} from './utils/TriplanarTexturesNode.js'; +export { default as ReflectorNode, reflector } from './utils/ReflectorNode.js'; + +// shadernode +export * from './shadernode/ShaderNode.js'; + +// accessors +export { TBNViewMatrix, parallaxDirection, parallaxUV, transformedBentNormalView } from './accessors/AccessorsUtils.js'; +export { default as UniformsNode, uniforms } from './accessors/UniformsNode.js'; +export * from './accessors/BitangentNode.js'; +export { + default as BufferAttributeNode, + bufferAttribute, + dynamicBufferAttribute, + instancedBufferAttribute, + instancedDynamicBufferAttribute, +} from './accessors/BufferAttributeNode.js'; +export { default as BufferNode, buffer } from './accessors/BufferNode.js'; +export * from './accessors/CameraNode.js'; +export { default as VertexColorNode, vertexColor } from './accessors/VertexColorNode.js'; +export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js'; +export { default as InstanceNode, instance } from './accessors/InstanceNode.js'; +export { default as BatchNode, batch } from './accessors/BatchNode.js'; +export { + default as MaterialNode, + materialAlphaTest, + materialColor, + materialShininess, + materialEmissive, + materialOpacity, + materialSpecular, + materialSpecularStrength, + materialReflectivity, + materialRoughness, + materialMetalness, + materialNormal, + materialClearcoat, + materialClearcoatRoughness, + materialClearcoatNormal, + materialRotation, + materialSheen, + materialSheenRoughness, + materialIridescence, + materialIridescenceIOR, + materialIridescenceThickness, + materialLineScale, + materialLineDashSize, + materialLineGapSize, + materialLineWidth, + materialLineDashOffset, + materialPointWidth, + materialAnisotropy, + materialAnisotropyVector, + materialDispersion, +} from './accessors/MaterialNode.js'; +export { default as MaterialReferenceNode, materialReference } from './accessors/MaterialReferenceNode.js'; +export { default as RendererReferenceNode, rendererReference } from './accessors/RendererReferenceNode.js'; +export { default as MorphNode, morphReference } from './accessors/MorphNode.js'; +export { default as TextureBicubicNode, textureBicubic } from './accessors/TextureBicubicNode.js'; +export { + default as ModelNode, + modelDirection, + modelViewMatrix, + modelNormalMatrix, + modelWorldMatrix, + modelPosition, + modelViewPosition, + modelScale, + modelWorldMatrixInverse, +} from './accessors/ModelNode.js'; +export { default as ModelViewProjectionNode, modelViewProjection } from './accessors/ModelViewProjectionNode.js'; +export * from './accessors/NormalNode.js'; +export { + default as Object3DNode, + objectDirection, + objectViewMatrix, + objectNormalMatrix, + objectWorldMatrix, + objectPosition, + objectScale, + objectViewPosition, +} from './accessors/Object3DNode.js'; +export { default as PointUVNode, pointUV } from './accessors/PointUVNode.js'; +export * from './accessors/PositionNode.js'; +export { default as ReferenceNode, reference, referenceBuffer } from './accessors/ReferenceNode.js'; +export * from './accessors/ReflectVectorNode.js'; +export { default as SkinningNode, skinning } from './accessors/SkinningNode.js'; +export { default as SceneNode, backgroundBlurriness, backgroundIntensity } from './accessors/SceneNode.js'; +export { default as StorageBufferNode, storage, storageObject } from './accessors/StorageBufferNode.js'; +export * from './accessors/TangentNode.js'; +export { default as TextureNode, texture, textureLoad, /*textureLevel,*/ sampler } from './accessors/TextureNode.js'; +export { default as StorageTextureNode, storageTexture, textureStore } from './accessors/StorageTextureNode.js'; +export { default as Texture3DNode, texture3D } from './accessors/Texture3DNode.js'; +export * from './accessors/UVNode.js'; +export { default as UserDataNode, userData } from './accessors/UserDataNode.js'; + +// display +export { default as BlendModeNode, burn, dodge, overlay, screen } from './display/BlendModeNode.js'; +export { default as BumpMapNode, bumpMap } from './display/BumpMapNode.js'; +export { + default as ColorAdjustmentNode, + saturation, + vibrance, + hue, + lumaCoeffs, + luminance, + threshold, +} from './display/ColorAdjustmentNode.js'; +export { + default as ColorSpaceNode, + linearToColorSpace, + colorSpaceToLinear, + linearTosRGB, + sRGBToLinear, +} from './display/ColorSpaceNode.js'; +export { default as FrontFacingNode, frontFacing, faceDirection } from './display/FrontFacingNode.js'; +export { default as NormalMapNode, normalMap } from './display/NormalMapNode.js'; +export { default as PosterizeNode, posterize } from './display/PosterizeNode.js'; +export { default as ToneMappingNode, toneMapping } from './display/ToneMappingNode.js'; +export { + default as ViewportNode, + viewport, + viewportCoordinate, + viewportResolution, + viewportTopLeft, + viewportBottomLeft, + viewportTopRight, + viewportBottomRight, +} from './display/ViewportNode.js'; +export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js'; +export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js'; +export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js'; +export { + default as ViewportDepthNode, + viewZToOrthographicDepth, + orthographicDepthToViewZ, + viewZToPerspectiveDepth, + perspectiveDepthToViewZ, + depth, + linearDepth, + viewportLinearDepth, +} from './display/ViewportDepthNode.js'; +export { default as GaussianBlurNode, gaussianBlur } from './display/GaussianBlurNode.js'; +export { default as AfterImageNode, afterImage } from './display/AfterImageNode.js'; +export { default as AnamorphicNode, anamorphic } from './display/AnamorphicNode.js'; +export { default as SobelOperatorNode, sobel } from './display/SobelOperatorNode.js'; +export { default as DepthOfFieldNode, dof } from './display/DepthOfFieldNode.js'; +export { default as DotScreenNode, dotScreen } from './display/DotScreenNode.js'; +export { default as RGBShiftNode, rgbShift } from './display/RGBShiftNode.js'; + +export { default as PassNode, pass, texturePass, depthPass } from './display/PassNode.js'; + +// code +export { default as ExpressionNode, expression } from './code/ExpressionNode.js'; +export { default as CodeNode, code, js, wgsl, glsl } from './code/CodeNode.js'; +export { default as FunctionCallNode, call } from './code/FunctionCallNode.js'; +export { default as FunctionNode, wgslFn, glslFn } from './code/FunctionNode.js'; +export { default as ScriptableNode, scriptable, global } from './code/ScriptableNode.js'; +export { default as ScriptableValueNode, scriptableValue } from './code/ScriptableValueNode.js'; + +// fog +export { default as FogNode, fog } from './fog/FogNode.js'; +export { default as FogRangeNode, rangeFog } from './fog/FogRangeNode.js'; +export { default as FogExp2Node, densityFog } from './fog/FogExp2Node.js'; + +// geometry +export { default as RangeNode, range } from './geometry/RangeNode.js'; + +// gpgpu +export { default as ComputeNode, compute } from './gpgpu/ComputeNode.js'; + +// lighting +export { default as LightNode, lightTargetDirection } from './lighting/LightNode.js'; +export { default as PointLightNode } from './lighting/PointLightNode.js'; +export { default as DirectionalLightNode } from './lighting/DirectionalLightNode.js'; +export { default as RectAreaLightNode } from './lighting/RectAreaLightNode.js'; +export { default as SpotLightNode } from './lighting/SpotLightNode.js'; +export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js'; +export { default as AmbientLightNode } from './lighting/AmbientLightNode.js'; +export { default as LightsNode, lights, lightsNode, addLightNode } from './lighting/LightsNode.js'; +export { default as LightingNode /* @TODO: lighting (abstract), light */ } from './lighting/LightingNode.js'; +export { default as LightingContextNode, lightingContext } from './lighting/LightingContextNode.js'; +export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js'; +export { default as EnvironmentNode } from './lighting/EnvironmentNode.js'; +export { default as IrradianceNode } from './lighting/IrradianceNode.js'; +export { default as AONode } from './lighting/AONode.js'; +export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js'; + +// pmrem +export { default as PMREMNode, pmremTexture } from './pmrem/PMREMNode.js'; +export * as PMREMUtils from './pmrem/PMREMUtils.js'; + +// procedural +export { default as CheckerNode, checker } from './procedural/CheckerNode.js'; + +// loaders +export { default as NodeLoader } from './loaders/NodeLoader.js'; +export { default as NodeObjectLoader } from './loaders/NodeObjectLoader.js'; +export { default as NodeMaterialLoader } from './loaders/NodeMaterialLoader.js'; + +// parsers +export { default as GLSLNodeParser } from './parsers/GLSLNodeParser.js'; // @TODO: Move to jsm/renderers/webgl. + +// materials +export * from './materials/Materials.js'; + +// materialX +export * from './materialx/MaterialXNodes.js'; + +// functions +export { default as BRDF_GGX } from './functions/BSDF/BRDF_GGX.js'; +export { default as BRDF_Lambert } from './functions/BSDF/BRDF_Lambert.js'; +export { default as D_GGX } from './functions/BSDF/D_GGX.js'; +export { default as DFGApprox } from './functions/BSDF/DFGApprox.js'; +export { default as F_Schlick } from './functions/BSDF/F_Schlick.js'; +export { default as Schlick_to_F0 } from './functions/BSDF/Schlick_to_F0.js'; +export { default as V_GGX_SmithCorrelated } from './functions/BSDF/V_GGX_SmithCorrelated.js'; + +export { getDistanceAttenuation } from './lighting/LightUtils.js'; + +export { default as getGeometryRoughness } from './functions/material/getGeometryRoughness.js'; +export { default as getRoughness } from './functions/material/getRoughness.js'; + +export { default as PhongLightingModel } from './functions/PhongLightingModel.js'; +export { default as PhysicalLightingModel } from './functions/PhysicalLightingModel.js'; diff --git a/examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts b/examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts new file mode 100644 index 000000000..cc50dba65 --- /dev/null +++ b/examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts @@ -0,0 +1,131 @@ +import InputNode from '../core/InputNode.js'; +import { addNodeClass } from '../core/Node.js'; +import { varying } from '../core/VaryingNode.js'; +import { nodeObject, addNodeElement } from '../shadernode/ShaderNode.js'; +import { InterleavedBufferAttribute, InterleavedBuffer, StaticDrawUsage, DynamicDrawUsage } from 'three'; + +class BufferAttributeNode extends InputNode { + constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { + super(value, bufferType); + + this.isBufferNode = true; + + this.bufferType = bufferType; + this.bufferStride = bufferStride; + this.bufferOffset = bufferOffset; + + this.usage = StaticDrawUsage; + this.instanced = false; + + this.attribute = null; + + this.global = true; + + if (value && value.isBufferAttribute === true) { + this.attribute = value; + this.usage = value.usage; + this.instanced = value.isInstancedBufferAttribute; + } + } + + getHash(builder) { + if (this.bufferStride === 0 && this.bufferOffset === 0) { + let bufferData = builder.globalCache.getData(this.value); + + if (bufferData === undefined) { + bufferData = { + node: this, + }; + + builder.globalCache.setData(this.value, bufferData); + } + + return bufferData.node.uuid; + } + + return this.uuid; + } + + getNodeType(builder) { + if (this.bufferType === null) { + this.bufferType = builder.getTypeFromAttribute(this.attribute); + } + + return this.bufferType; + } + + setup(builder) { + if (this.attribute !== null) return; + + const type = this.getNodeType(builder); + const array = this.value; + const itemSize = builder.getTypeLength(type); + const stride = this.bufferStride || itemSize; + const offset = this.bufferOffset; + + const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer(array, stride); + const bufferAttribute = new InterleavedBufferAttribute(buffer, itemSize, offset); + + buffer.setUsage(this.usage); + + this.attribute = bufferAttribute; + this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute + } + + generate(builder) { + const nodeType = this.getNodeType(builder); + + const nodeAttribute = builder.getBufferAttributeFromNode(this, nodeType); + const propertyName = builder.getPropertyName(nodeAttribute); + + let output = null; + + if (builder.shaderStage === 'vertex' || builder.shaderStage === 'compute') { + this.name = propertyName; + + output = propertyName; + } else { + const nodeVarying = varying(this); + + output = nodeVarying.build(builder, nodeType); + } + + return output; + } + + getInputType(/*builder*/) { + return 'bufferAttribute'; + } + + setUsage(value) { + this.usage = value; + + if (this.attribute && this.attribute.isBufferAttribute === true) { + this.attribute.usage = value; + } + + return this; + } + + setInstanced(value) { + this.instanced = value; + + return this; + } +} + +export default BufferAttributeNode; + +export const bufferAttribute = (array, type, stride, offset) => + nodeObject(new BufferAttributeNode(array, type, stride, offset)); +export const dynamicBufferAttribute = (array, type, stride, offset) => + bufferAttribute(array, type, stride, offset).setUsage(DynamicDrawUsage); + +export const instancedBufferAttribute = (array, type, stride, offset) => + bufferAttribute(array, type, stride, offset).setInstanced(true); +export const instancedDynamicBufferAttribute = (array, type, stride, offset) => + dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); + +addNodeElement('toAttribute', bufferNode => bufferAttribute(bufferNode.value)); + +addNodeClass('BufferAttributeNode', BufferAttributeNode); diff --git a/examples-jsm/examples/nodes/accessors/TextureNode.ts b/examples-jsm/examples/nodes/accessors/TextureNode.ts new file mode 100644 index 000000000..7852696af --- /dev/null +++ b/examples-jsm/examples/nodes/accessors/TextureNode.ts @@ -0,0 +1,327 @@ +import UniformNode, { uniform } from '../core/UniformNode.js'; +import { uv } from './UVNode.js'; +import { textureSize } from './TextureSizeNode.js'; +import { colorSpaceToLinear } from '../display/ColorSpaceNode.js'; +import { expression } from '../code/ExpressionNode.js'; +import { addNodeClass } from '../core/Node.js'; +import { maxMipLevel } from '../utils/MaxMipLevelNode.js'; +import { addNodeElement, nodeProxy, vec3, nodeObject } from '../shadernode/ShaderNode.js'; +import { NodeUpdateType } from '../core/constants.js'; + +class TextureNode extends UniformNode { + constructor(value, uvNode = null, levelNode = null) { + super(value); + + this.isTextureNode = true; + + this.uvNode = uvNode; + this.levelNode = levelNode; + this.compareNode = null; + this.depthNode = null; + this.gradNode = null; + + this.sampler = true; + this.updateMatrix = false; + this.updateType = NodeUpdateType.NONE; + + this.referenceNode = null; + + this._value = value; + + this.setUpdateMatrix(uvNode === null); + } + + set value(value) { + if (this.referenceNode) { + this.referenceNode.value = value; + } else { + this._value = value; + } + } + + get value() { + return this.referenceNode ? this.referenceNode.value : this._value; + } + + getUniformHash(/*builder*/) { + return this.value.uuid; + } + + getNodeType(/*builder*/) { + if (this.value.isDepthTexture === true) return 'float'; + + return 'vec4'; + } + + getInputType(/*builder*/) { + return 'texture'; + } + + getDefaultUV() { + return uv(this.value.channel); + } + + updateReference(/*state*/) { + return this.value; + } + + getTransformedUV(uvNode) { + const texture = this.value; + + return uniform(texture.matrix).mul(vec3(uvNode, 1)).xy; + } + + setUpdateMatrix(value) { + this.updateMatrix = value; + this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE; + + return this; + } + + setupUV(builder, uvNode) { + const texture = this.value; + + if ( + builder.isFlipY() && + (texture.isRenderTargetTexture === true || + texture.isFramebufferTexture === true || + texture.isDepthTexture === true) + ) { + uvNode = uvNode.setY(uvNode.y.oneMinus()); + } + + return uvNode; + } + + setup(builder) { + const properties = builder.getNodeProperties(this); + + // + + let uvNode = this.uvNode; + + if ((uvNode === null || builder.context.forceUVContext === true) && builder.context.getUV) { + uvNode = builder.context.getUV(this); + } + + if (!uvNode) uvNode = this.getDefaultUV(); + + if (this.updateMatrix === true) { + uvNode = this.getTransformedUV(uvNode); + } + + uvNode = this.setupUV(builder, uvNode); + + // + + let levelNode = this.levelNode; + + if (levelNode === null && builder.context.getTextureLevel) { + levelNode = builder.context.getTextureLevel(this); + } + + // + + properties.uvNode = uvNode; + properties.levelNode = levelNode; + properties.compareNode = this.compareNode; + properties.gradNode = this.gradNode; + properties.depthNode = this.depthNode; + } + + generateUV(builder, uvNode) { + return uvNode.build(builder, this.sampler === true ? 'vec2' : 'ivec2'); + } + + generateSnippet(builder, textureProperty, uvSnippet, levelSnippet, depthSnippet, compareSnippet, gradSnippet) { + const texture = this.value; + + let snippet; + + if (levelSnippet) { + snippet = builder.generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet, depthSnippet); + } else if (gradSnippet) { + snippet = builder.generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet, depthSnippet); + } else if (compareSnippet) { + snippet = builder.generateTextureCompare(texture, textureProperty, uvSnippet, compareSnippet, depthSnippet); + } else if (this.sampler === false) { + snippet = builder.generateTextureLoad(texture, textureProperty, uvSnippet, depthSnippet); + } else { + snippet = builder.generateTexture(texture, textureProperty, uvSnippet, depthSnippet); + } + + return snippet; + } + + generate(builder, output) { + const properties = builder.getNodeProperties(this); + + const texture = this.value; + + if (!texture || texture.isTexture !== true) { + throw new Error('TextureNode: Need a three.js texture.'); + } + + const textureProperty = super.generate(builder, 'property'); + + if (output === 'sampler') { + return textureProperty + '_sampler'; + } else if (builder.isReference(output)) { + return textureProperty; + } else { + const nodeData = builder.getDataFromNode(this); + + let propertyName = nodeData.propertyName; + + if (propertyName === undefined) { + const { uvNode, levelNode, compareNode, depthNode, gradNode } = properties; + + const uvSnippet = this.generateUV(builder, uvNode); + const levelSnippet = levelNode ? levelNode.build(builder, 'float') : null; + const depthSnippet = depthNode ? depthNode.build(builder, 'int') : null; + const compareSnippet = compareNode ? compareNode.build(builder, 'float') : null; + const gradSnippet = gradNode + ? [gradNode[0].build(builder, 'vec2'), gradNode[1].build(builder, 'vec2')] + : null; + + const nodeVar = builder.getVarFromNode(this); + + propertyName = builder.getPropertyName(nodeVar); + + const snippet = this.generateSnippet( + builder, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + compareSnippet, + gradSnippet, + ); + + builder.addLineFlowCode(`${propertyName} = ${snippet}`); + + nodeData.snippet = snippet; + nodeData.propertyName = propertyName; + } + + let snippet = propertyName; + const nodeType = this.getNodeType(builder); + + if (builder.needsColorSpaceToLinear(texture)) { + snippet = colorSpaceToLinear(expression(snippet, nodeType), texture.colorSpace) + .setup(builder) + .build(builder, nodeType); + } + + return builder.format(snippet, nodeType, output); + } + } + + setSampler(value) { + this.sampler = value; + + return this; + } + + getSampler() { + return this.sampler; + } + + // @TODO: Move to TSL + + uv(uvNode) { + const textureNode = this.clone(); + textureNode.uvNode = uvNode; + textureNode.referenceNode = this; + + return nodeObject(textureNode); + } + + blur(levelNode) { + const textureNode = this.clone(); + textureNode.levelNode = levelNode.mul(maxMipLevel(textureNode)); + textureNode.referenceNode = this; + + return nodeObject(textureNode); + } + + level(levelNode) { + const textureNode = this.clone(); + textureNode.levelNode = levelNode; + textureNode.referenceNode = this; + + return textureNode; + } + + size(levelNode) { + return textureSize(this, levelNode); + } + + compare(compareNode) { + const textureNode = this.clone(); + textureNode.compareNode = nodeObject(compareNode); + textureNode.referenceNode = this; + + return nodeObject(textureNode); + } + + grad(gradNodeX, gradNodeY) { + const textureNode = this.clone(); + textureNode.gradNode = [nodeObject(gradNodeX), nodeObject(gradNodeY)]; + + textureNode.referenceNode = this; + + return nodeObject(textureNode); + } + + depth(depthNode) { + const textureNode = this.clone(); + textureNode.depthNode = nodeObject(depthNode); + textureNode.referenceNode = this; + + return nodeObject(textureNode); + } + + // -- + + serialize(data) { + super.serialize(data); + + data.value = this.value.toJSON(data.meta).uuid; + } + + deserialize(data) { + super.deserialize(data); + + this.value = data.meta.textures[data.value]; + } + + update() { + const texture = this.value; + + if (texture.matrixAutoUpdate === true) { + texture.updateMatrix(); + } + } + + clone() { + const newNode = new this.constructor(this.value, this.uvNode, this.levelNode); + newNode.sampler = this.sampler; + + return newNode; + } +} + +export default TextureNode; + +export const texture = nodeProxy(TextureNode); +export const textureLoad = (...params) => texture(...params).setSampler(false); + +//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level ); + +export const sampler = aTexture => (aTexture.isNode === true ? aTexture : texture(aTexture)).convert('sampler'); + +addNodeElement('texture', texture); +//addNodeElement( 'textureLevel', textureLevel ); + +addNodeClass('TextureNode', TextureNode); diff --git a/examples-jsm/examples/nodes/code/CodeNode.ts b/examples-jsm/examples/nodes/code/CodeNode.ts new file mode 100644 index 000000000..063475643 --- /dev/null +++ b/examples-jsm/examples/nodes/code/CodeNode.ts @@ -0,0 +1,66 @@ +import Node, { addNodeClass } from '../core/Node.js'; +import { nodeProxy } from '../shadernode/ShaderNode.js'; + +class CodeNode extends Node { + constructor(code = '', includes = [], language = '') { + super('code'); + + this.isCodeNode = true; + + this.code = code; + this.language = language; + + this.includes = includes; + } + + isGlobal() { + return true; + } + + setIncludes(includes) { + this.includes = includes; + + return this; + } + + getIncludes(/*builder*/) { + return this.includes; + } + + generate(builder) { + const includes = this.getIncludes(builder); + + for (const include of includes) { + include.build(builder); + } + + const nodeCode = builder.getCodeFromNode(this, this.getNodeType(builder)); + nodeCode.code = this.code; + + return nodeCode.code; + } + + serialize(data) { + super.serialize(data); + + data.code = this.code; + data.language = this.language; + } + + deserialize(data) { + super.deserialize(data); + + this.code = data.code; + this.language = data.language; + } +} + +export default CodeNode; + +export const code = nodeProxy(CodeNode); + +export const js = (src, includes) => code(src, includes, 'js'); +export const wgsl = (src, includes) => code(src, includes, 'wgsl'); +export const glsl = (src, includes) => code(src, includes, 'glsl'); + +addNodeClass('CodeNode', CodeNode); diff --git a/examples-jsm/examples/nodes/code/FunctionNode.ts b/examples-jsm/examples/nodes/code/FunctionNode.ts new file mode 100644 index 000000000..feeb5a55c --- /dev/null +++ b/examples-jsm/examples/nodes/code/FunctionNode.ts @@ -0,0 +1,100 @@ +import CodeNode from './CodeNode.js'; +import { addNodeClass } from '../core/Node.js'; +import { nodeObject } from '../shadernode/ShaderNode.js'; + +class FunctionNode extends CodeNode { + constructor(code = '', includes = [], language = '') { + super(code, includes, language); + + this.keywords = {}; + } + + getNodeType(builder) { + return this.getNodeFunction(builder).type; + } + + getInputs(builder) { + return this.getNodeFunction(builder).inputs; + } + + getNodeFunction(builder) { + const nodeData = builder.getDataFromNode(this); + + let nodeFunction = nodeData.nodeFunction; + + if (nodeFunction === undefined) { + nodeFunction = builder.parser.parseFunction(this.code); + + nodeData.nodeFunction = nodeFunction; + } + + return nodeFunction; + } + + generate(builder, output) { + super.generate(builder); + + const nodeFunction = this.getNodeFunction(builder); + + const name = nodeFunction.name; + const type = nodeFunction.type; + + const nodeCode = builder.getCodeFromNode(this, type); + + if (name !== '') { + // use a custom property name + + nodeCode.name = name; + } + + const propertyName = builder.getPropertyName(nodeCode); + + let code = this.getNodeFunction(builder).getCode(propertyName); + + const keywords = this.keywords; + const keywordsProperties = Object.keys(keywords); + + if (keywordsProperties.length > 0) { + for (const property of keywordsProperties) { + const propertyRegExp = new RegExp(`\\b${property}\\b`, 'g'); + const nodeProperty = keywords[property].build(builder, 'property'); + + code = code.replace(propertyRegExp, nodeProperty); + } + } + + nodeCode.code = code + '\n'; + + if (output === 'property') { + return propertyName; + } else { + return builder.format(`${propertyName}()`, type, output); + } + } +} + +export default FunctionNode; + +const nativeFn = (code, includes = [], language = '') => { + for (let i = 0; i < includes.length; i++) { + const include = includes[i]; + + // TSL Function: glslFn, wgslFn + + if (typeof include === 'function') { + includes[i] = include.functionNode; + } + } + + const functionNode = nodeObject(new FunctionNode(code, includes, language)); + + const fn = (...params) => functionNode.call(...params); + fn.functionNode = functionNode; + + return fn; +}; + +export const glslFn = (code, includes) => nativeFn(code, includes, 'glsl'); +export const wgslFn = (code, includes) => nativeFn(code, includes, 'wgsl'); + +addNodeClass('FunctionNode', FunctionNode); diff --git a/examples-jsm/examples/nodes/core/ContextNode.ts b/examples-jsm/examples/nodes/core/ContextNode.ts new file mode 100644 index 000000000..fcd488eba --- /dev/null +++ b/examples-jsm/examples/nodes/core/ContextNode.ts @@ -0,0 +1,55 @@ +import Node, { addNodeClass } from './Node.js'; +import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js'; + +class ContextNode extends Node { + constructor(node, context = {}) { + super(); + + this.isContextNode = true; + + this.node = node; + this.context = context; + } + + getNodeType(builder) { + return this.node.getNodeType(builder); + } + + analyze(builder) { + this.node.build(builder); + } + + setup(builder) { + const previousContext = builder.getContext(); + + builder.setContext({ ...builder.context, ...this.context }); + + const node = this.node.build(builder); + + builder.setContext(previousContext); + + return node; + } + + generate(builder, output) { + const previousContext = builder.getContext(); + + builder.setContext({ ...builder.context, ...this.context }); + + const snippet = this.node.build(builder, output); + + builder.setContext(previousContext); + + return snippet; + } +} + +export default ContextNode; + +export const context = nodeProxy(ContextNode); +export const label = (node, name) => context(node, { label: name }); + +addNodeElement('context', context); +addNodeElement('label', label); + +addNodeClass('ContextNode', ContextNode); diff --git a/examples-jsm/examples/nodes/core/InputNode.ts b/examples-jsm/examples/nodes/core/InputNode.ts new file mode 100644 index 000000000..4d52ec26f --- /dev/null +++ b/examples-jsm/examples/nodes/core/InputNode.ts @@ -0,0 +1,65 @@ +import Node, { addNodeClass } from './Node.js'; +import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js'; + +class InputNode extends Node { + constructor(value, nodeType = null) { + super(nodeType); + + this.isInputNode = true; + + this.value = value; + this.precision = null; + } + + getNodeType(/*builder*/) { + if (this.nodeType === null) { + return getValueType(this.value); + } + + return this.nodeType; + } + + getInputType(builder) { + return this.getNodeType(builder); + } + + setPrecision(precision) { + this.precision = precision; + + return this; + } + + serialize(data) { + super.serialize(data); + + data.value = this.value; + + if (this.value && this.value.toArray) data.value = this.value.toArray(); + + data.valueType = getValueType(this.value); + data.nodeType = this.nodeType; + + if (data.valueType === 'ArrayBuffer') data.value = arrayBufferToBase64(data.value); + + data.precision = this.precision; + } + + deserialize(data) { + super.deserialize(data); + + this.nodeType = data.nodeType; + this.value = Array.isArray(data.value) ? getValueFromType(data.valueType, ...data.value) : data.value; + + this.precision = data.precision || null; + + if (this.value && this.value.fromArray) this.value = this.value.fromArray(data.value); + } + + generate(/*builder, output*/) { + console.warn('Abstract function.'); + } +} + +export default InputNode; + +addNodeClass('InputNode', InputNode); diff --git a/examples-jsm/examples/nodes/core/Node.ts b/examples-jsm/examples/nodes/core/Node.ts new file mode 100644 index 000000000..66444172d --- /dev/null +++ b/examples-jsm/examples/nodes/core/Node.ts @@ -0,0 +1,424 @@ +import { EventDispatcher } from 'three'; +import { NodeUpdateType } from './constants.js'; +import { getNodeChildren, getCacheKey } from './NodeUtils.js'; +import { MathUtils } from 'three'; + +const NodeClasses = new Map(); + +let _nodeId = 0; + +class Node extends EventDispatcher { + constructor(nodeType = null) { + super(); + + this.nodeType = nodeType; + + this.updateType = NodeUpdateType.NONE; + this.updateBeforeType = NodeUpdateType.NONE; + this.updateAfterType = NodeUpdateType.NONE; + + this.uuid = MathUtils.generateUUID(); + + this.version = 0; + + this._cacheKey = null; + this._cacheKeyVersion = 0; + + this.global = false; + + this.isNode = true; + + Object.defineProperty(this, 'id', { value: _nodeId++ }); + } + + set needsUpdate(value) { + if (value === true) { + this.version++; + } + } + + get type() { + return this.constructor.type; + } + + onUpdate(callback, updateType) { + this.updateType = updateType; + this.update = callback.bind(this.getSelf()); + + return this; + } + + onFrameUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.FRAME); + } + + onRenderUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.RENDER); + } + + onObjectUpdate(callback) { + return this.onUpdate(callback, NodeUpdateType.OBJECT); + } + + onReference(callback) { + this.updateReference = callback.bind(this.getSelf()); + + return this; + } + + getSelf() { + // Returns non-node object. + + return this.self || this; + } + + updateReference(/*state*/) { + return this; + } + + isGlobal(/*builder*/) { + return this.global; + } + + *getChildren() { + for (const { childNode } of getNodeChildren(this)) { + yield childNode; + } + } + + dispose() { + this.dispatchEvent({ type: 'dispose' }); + } + + traverse(callback) { + callback(this); + + for (const childNode of this.getChildren()) { + childNode.traverse(callback); + } + } + + getCacheKey(force = false) { + force = force || this.version !== this._cacheKeyVersion; + + if (force === true || this._cacheKey === null) { + this._cacheKey = getCacheKey(this, force); + this._cacheKeyVersion = this.version; + } + + return this._cacheKey; + } + + getHash(/*builder*/) { + return this.uuid; + } + + getUpdateType() { + return this.updateType; + } + + getUpdateBeforeType() { + return this.updateBeforeType; + } + + getUpdateAfterType() { + return this.updateAfterType; + } + + getElementType(builder) { + const type = this.getNodeType(builder); + const elementType = builder.getElementType(type); + + return elementType; + } + + getNodeType(builder) { + const nodeProperties = builder.getNodeProperties(this); + + if (nodeProperties.outputNode) { + return nodeProperties.outputNode.getNodeType(builder); + } + + return this.nodeType; + } + + getShared(builder) { + const hash = this.getHash(builder); + const nodeFromHash = builder.getNodeFromHash(hash); + + return nodeFromHash || this; + } + + setup(builder) { + const nodeProperties = builder.getNodeProperties(this); + + let index = 0; + + for (const childNode of this.getChildren()) { + nodeProperties['node' + index++] = childNode; + } + + // return a outputNode if exists + return null; + } + + construct(builder) { + // @deprecated, r157 + + console.warn('THREE.Node: construct() is deprecated. Use setup() instead.'); + + return this.setup(builder); + } + + increaseUsage(builder) { + const nodeData = builder.getDataFromNode(this); + nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1; + + return nodeData.usageCount; + } + + analyze(builder) { + const usageCount = this.increaseUsage(builder); + + if (usageCount === 1) { + // node flow children + + const nodeProperties = builder.getNodeProperties(this); + + for (const childNode of Object.values(nodeProperties)) { + if (childNode && childNode.isNode === true) { + childNode.build(builder); + } + } + } + } + + generate(builder, output) { + const { outputNode } = builder.getNodeProperties(this); + + if (outputNode && outputNode.isNode === true) { + return outputNode.build(builder, output); + } + } + + updateBefore(/*frame*/) { + console.warn('Abstract function.'); + } + + updateAfter(/*frame*/) { + console.warn('Abstract function.'); + } + + update(/*frame*/) { + console.warn('Abstract function.'); + } + + build(builder, output = null) { + const refNode = this.getShared(builder); + + if (this !== refNode) { + return refNode.build(builder, output); + } + + builder.addNode(this); + builder.addChain(this); + + /* Build stages expected results: + - "setup" -> Node + - "analyze" -> null + - "generate" -> String + */ + let result = null; + + const buildStage = builder.getBuildStage(); + + if (buildStage === 'setup') { + this.updateReference(builder); + + const properties = builder.getNodeProperties(this); + + if (properties.initialized !== true) { + const stackNodesBeforeSetup = builder.stack.nodes.length; + + properties.initialized = true; + properties.outputNode = this.setup(builder); + + if (properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup) { + properties.outputNode = builder.stack; + } + + for (const childNode of Object.values(properties)) { + if (childNode && childNode.isNode === true) { + childNode.build(builder); + } + } + } + } else if (buildStage === 'analyze') { + this.analyze(builder); + } else if (buildStage === 'generate') { + const isGenerateOnce = this.generate.length === 1; + + if (isGenerateOnce) { + const type = this.getNodeType(builder); + const nodeData = builder.getDataFromNode(this); + + result = nodeData.snippet; + + if (result === undefined) { + result = this.generate(builder) || ''; + + nodeData.snippet = result; + } + + result = builder.format(result, type, output); + } else { + result = this.generate(builder, output) || ''; + } + } + + builder.removeChain(this); + + return result; + } + + getSerializeChildren() { + return getNodeChildren(this); + } + + serialize(json) { + const nodeChildren = this.getSerializeChildren(); + + const inputNodes = {}; + + for (const { property, index, childNode } of nodeChildren) { + if (index !== undefined) { + if (inputNodes[property] === undefined) { + inputNodes[property] = Number.isInteger(index) ? [] : {}; + } + + inputNodes[property][index] = childNode.toJSON(json.meta).uuid; + } else { + inputNodes[property] = childNode.toJSON(json.meta).uuid; + } + } + + if (Object.keys(inputNodes).length > 0) { + json.inputNodes = inputNodes; + } + } + + deserialize(json) { + if (json.inputNodes !== undefined) { + const nodes = json.meta.nodes; + + for (const property in json.inputNodes) { + if (Array.isArray(json.inputNodes[property])) { + const inputArray = []; + + for (const uuid of json.inputNodes[property]) { + inputArray.push(nodes[uuid]); + } + + this[property] = inputArray; + } else if (typeof json.inputNodes[property] === 'object') { + const inputObject = {}; + + for (const subProperty in json.inputNodes[property]) { + const uuid = json.inputNodes[property][subProperty]; + + inputObject[subProperty] = nodes[uuid]; + } + + this[property] = inputObject; + } else { + const uuid = json.inputNodes[property]; + + this[property] = nodes[uuid]; + } + } + } + } + + toJSON(meta) { + const { uuid, type } = this; + const isRoot = meta === undefined || typeof meta === 'string'; + + if (isRoot) { + meta = { + textures: {}, + images: {}, + nodes: {}, + }; + } + + // serialize + + let data = meta.nodes[uuid]; + + if (data === undefined) { + data = { + uuid, + type, + meta, + metadata: { + version: 4.6, + type: 'Node', + generator: 'Node.toJSON', + }, + }; + + if (isRoot !== true) meta.nodes[data.uuid] = data; + + this.serialize(data); + + delete data.meta; + } + + // TODO: Copied from Object3D.toJSON + + function extractFromCache(cache) { + const values = []; + + for (const key in cache) { + const data = cache[key]; + delete data.metadata; + values.push(data); + } + + return values; + } + + if (isRoot) { + const textures = extractFromCache(meta.textures); + const images = extractFromCache(meta.images); + const nodes = extractFromCache(meta.nodes); + + if (textures.length > 0) data.textures = textures; + if (images.length > 0) data.images = images; + if (nodes.length > 0) data.nodes = nodes; + } + + return data; + } +} + +export default Node; + +export function addNodeClass(type, nodeClass) { + if (typeof nodeClass !== 'function' || !type) throw new Error(`Node class ${type} is not a class`); + if (NodeClasses.has(type)) { + console.warn(`Redefinition of node class ${type}`); + return; + } + + NodeClasses.set(type, nodeClass); + nodeClass.type = type; +} + +export function createNodeFromType(type) { + const Class = NodeClasses.get(type); + + if (Class !== undefined) { + return new Class(); + } +} diff --git a/examples-jsm/examples/nodes/core/NodeAttribute.ts b/examples-jsm/examples/nodes/core/NodeAttribute.ts new file mode 100644 index 000000000..190fe8c51 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeAttribute.ts @@ -0,0 +1,11 @@ +class NodeAttribute { + constructor(name, type, node = null) { + this.isNodeAttribute = true; + + this.name = name; + this.type = type; + this.node = node; + } +} + +export default NodeAttribute; diff --git a/examples-jsm/examples/nodes/core/NodeBuilder.ts b/examples-jsm/examples/nodes/core/NodeBuilder.ts new file mode 100644 index 000000000..2559a675f --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeBuilder.ts @@ -0,0 +1,1119 @@ +import NodeUniform from './NodeUniform.js'; +import NodeAttribute from './NodeAttribute.js'; +import NodeVarying from './NodeVarying.js'; +import NodeVar from './NodeVar.js'; +import NodeCode from './NodeCode.js'; +import NodeKeywords from './NodeKeywords.js'; +import NodeCache from './NodeCache.js'; +import ParameterNode from './ParameterNode.js'; +import FunctionNode from '../code/FunctionNode.js'; +import { createNodeMaterialFromType, default as NodeMaterial } from '../materials/NodeMaterial.js'; +import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js'; + +import { + NumberNodeUniform, + Vector2NodeUniform, + Vector3NodeUniform, + Vector4NodeUniform, + ColorNodeUniform, + Matrix3NodeUniform, + Matrix4NodeUniform, +} from '../../renderers/common/nodes/NodeUniform.js'; + +import BindGroup from '../../renderers/common/BindGroup.js'; + +import { + REVISION, + RenderTarget, + Color, + Vector2, + Vector3, + Vector4, + IntType, + UnsignedIntType, + Float16BufferAttribute, + LinearFilter, + LinearMipmapNearestFilter, + NearestMipmapLinearFilter, + LinearMipmapLinearFilter, +} from 'three'; + +import { stack } from './StackNode.js'; +import { getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js'; + +import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; +import ChainMap from '../../renderers/common/ChainMap.js'; + +import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js'; + +const rendererCache = new WeakMap(); + +const typeFromLength = new Map([ + [2, 'vec2'], + [3, 'vec3'], + [4, 'vec4'], + [9, 'mat3'], + [16, 'mat4'], +]); + +const typeFromArray = new Map([ + [Int8Array, 'int'], + [Int16Array, 'int'], + [Int32Array, 'int'], + [Uint8Array, 'uint'], + [Uint16Array, 'uint'], + [Uint32Array, 'uint'], + [Float32Array, 'float'], +]); + +const toFloat = value => { + value = Number(value); + + return value + (value % 1 ? '' : '.0'); +}; + +class NodeBuilder { + constructor(object, renderer, parser) { + this.object = object; + this.material = (object && object.material) || null; + this.geometry = (object && object.geometry) || null; + this.renderer = renderer; + this.parser = parser; + this.scene = null; + this.camera = null; + + this.nodes = []; + this.updateNodes = []; + this.updateBeforeNodes = []; + this.updateAfterNodes = []; + this.hashNodes = {}; + + this.lightsNode = null; + this.environmentNode = null; + this.fogNode = null; + + this.clippingContext = null; + + this.vertexShader = null; + this.fragmentShader = null; + this.computeShader = null; + + this.flowNodes = { vertex: [], fragment: [], compute: [] }; + this.flowCode = { vertex: '', fragment: '', compute: '' }; + this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }; + this.structs = { vertex: [], fragment: [], compute: [], index: 0 }; + this.bindings = { vertex: {}, fragment: {}, compute: {} }; + this.bindingsIndexes = {}; + this.bindGroups = null; + this.attributes = []; + this.bufferAttributes = []; + this.varyings = []; + this.codes = {}; + this.vars = {}; + this.flow = { code: '' }; + this.chaining = []; + this.stack = stack(); + this.stacks = []; + this.tab = '\t'; + + this.instanceBindGroups = true; + + this.currentFunctionNode = null; + + this.context = { + keywords: new NodeKeywords(), + material: this.material, + }; + + this.cache = new NodeCache(); + this.globalCache = this.cache; + + this.flowsData = new WeakMap(); + + this.shaderStage = null; + this.buildStage = null; + } + + getBingGroupsCache() { + let bindGroupsCache = rendererCache.get(this.renderer); + + if (bindGroupsCache === undefined) { + bindGroupsCache = new ChainMap(); + + rendererCache.set(this.renderer, bindGroupsCache); + } + + return bindGroupsCache; + } + + createRenderTarget(width, height, options) { + return new RenderTarget(width, height, options); + } + + createCubeRenderTarget(size, options) { + return new CubeRenderTarget(size, options); + } + + createPMREMGenerator() { + // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support + + return new PMREMGenerator(this.renderer); + } + + includes(node) { + return this.nodes.includes(node); + } + + _getBindGroup(groupName, bindings) { + const bindGroupsCache = this.getBingGroupsCache(); + + // cache individual uniforms group + + const bindingsArray = []; + + let sharedGroup = true; + + for (const binding of bindings) { + if (binding.groupNode.shared === true) { + // nodes is the chainmap key + const nodes = binding.getNodes(); + + let sharedBinding = bindGroupsCache.get(nodes); + + if (sharedBinding === undefined) { + bindGroupsCache.set(nodes, binding); + + sharedBinding = binding; + } + + bindingsArray.push(sharedBinding); + } else { + bindingsArray.push(binding); + + sharedGroup = false; + } + } + + // + + let bindGroup; + + if (sharedGroup) { + bindGroup = bindGroupsCache.get(bindingsArray); + + if (bindGroup === undefined) { + bindGroup = new BindGroup(groupName, bindingsArray); + bindGroupsCache.set(bindingsArray, bindGroup); + } + } else { + bindGroup = new BindGroup(groupName, bindingsArray); + } + + return bindGroup; + } + + getBindGroupArray(groupName, shaderStage) { + const bindings = this.bindings[shaderStage]; + + let bindGroup = bindings[groupName]; + + if (bindGroup === undefined) { + if (this.bindingsIndexes[groupName] === undefined) { + this.bindingsIndexes[groupName] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }; + } + + bindings[groupName] = bindGroup = []; + } + + return bindGroup; + } + + getBindings() { + let bindingsGroups = this.bindGroups; + + if (bindingsGroups === null) { + const groups = {}; + const bindings = this.bindings; + + for (const shaderStage of shaderStages) { + for (const groupName in bindings[shaderStage]) { + const uniforms = bindings[shaderStage][groupName]; + + const groupUniforms = groups[groupName] || (groups[groupName] = []); + groupUniforms.push(...uniforms); + } + } + + bindingsGroups = []; + + for (const groupName in groups) { + const group = groups[groupName]; + + const bindingsGroup = this._getBindGroup(groupName, group); + + bindingsGroups.push(bindingsGroup); + } + + this.bindGroups = bindingsGroups; + } + + return bindingsGroups; + } + + setHashNode(node, hash) { + this.hashNodes[hash] = node; + } + + addNode(node) { + if (this.nodes.includes(node) === false) { + this.nodes.push(node); + + this.setHashNode(node, node.getHash(this)); + } + } + + buildUpdateNodes() { + for (const node of this.nodes) { + const updateType = node.getUpdateType(); + const updateBeforeType = node.getUpdateBeforeType(); + const updateAfterType = node.getUpdateAfterType(); + + if (updateType !== NodeUpdateType.NONE) { + this.updateNodes.push(node.getSelf()); + } + + if (updateBeforeType !== NodeUpdateType.NONE) { + this.updateBeforeNodes.push(node); + } + + if (updateAfterType !== NodeUpdateType.NONE) { + this.updateAfterNodes.push(node); + } + } + } + + get currentNode() { + return this.chaining[this.chaining.length - 1]; + } + + isFilteredTexture(texture) { + return ( + texture.magFilter === LinearFilter || + texture.magFilter === LinearMipmapNearestFilter || + texture.magFilter === NearestMipmapLinearFilter || + texture.magFilter === LinearMipmapLinearFilter || + texture.minFilter === LinearFilter || + texture.minFilter === LinearMipmapNearestFilter || + texture.minFilter === NearestMipmapLinearFilter || + texture.minFilter === LinearMipmapLinearFilter + ); + } + + addChain(node) { + /* + if ( this.chaining.indexOf( node ) !== - 1 ) { + + console.warn( 'Recursive node: ', node ); + + } + */ + + this.chaining.push(node); + } + + removeChain(node) { + const lastChain = this.chaining.pop(); + + if (lastChain !== node) { + throw new Error('NodeBuilder: Invalid node chaining!'); + } + } + + getMethod(method) { + return method; + } + + getNodeFromHash(hash) { + return this.hashNodes[hash]; + } + + addFlow(shaderStage, node) { + this.flowNodes[shaderStage].push(node); + + return node; + } + + setContext(context) { + this.context = context; + } + + getContext() { + return this.context; + } + + setCache(cache) { + this.cache = cache; + } + + getCache() { + return this.cache; + } + + getCacheFromNode(node, parent = true) { + const data = this.getDataFromNode(node); + if (data.cache === undefined) data.cache = new NodeCache(parent ? this.getCache() : null); + + return data.cache; + } + + isAvailable(/*name*/) { + return false; + } + + getVertexIndex() { + console.warn('Abstract function.'); + } + + getInstanceIndex() { + console.warn('Abstract function.'); + } + + getFrontFacing() { + console.warn('Abstract function.'); + } + + getFragCoord() { + console.warn('Abstract function.'); + } + + isFlipY() { + return false; + } + + generateTexture(/* texture, textureProperty, uvSnippet */) { + console.warn('Abstract function.'); + } + + generateTextureLod(/* texture, textureProperty, uvSnippet, levelSnippet */) { + console.warn('Abstract function.'); + } + + generateConst(type, value = null) { + if (value === null) { + if (type === 'float' || type === 'int' || type === 'uint') value = 0; + else if (type === 'bool') value = false; + else if (type === 'color') value = new Color(); + else if (type === 'vec2') value = new Vector2(); + else if (type === 'vec3') value = new Vector3(); + else if (type === 'vec4') value = new Vector4(); + } + + if (type === 'float') return toFloat(value); + if (type === 'int') return `${Math.round(value)}`; + if (type === 'uint') return value >= 0 ? `${Math.round(value)}u` : '0u'; + if (type === 'bool') return value ? 'true' : 'false'; + if (type === 'color') + return `${this.getType('vec3')}( ${toFloat(value.r)}, ${toFloat(value.g)}, ${toFloat(value.b)} )`; + + const typeLength = this.getTypeLength(type); + + const componentType = this.getComponentType(type); + + const generateConst = value => this.generateConst(componentType, value); + + if (typeLength === 2) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)} )`; + } else if (typeLength === 3) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)} )`; + } else if (typeLength === 4) { + return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)}, ${generateConst(value.w)} )`; + } else if (typeLength > 4 && value && (value.isMatrix3 || value.isMatrix4)) { + return `${this.getType(type)}( ${value.elements.map(generateConst).join(', ')} )`; + } else if (typeLength > 4) { + return `${this.getType(type)}()`; + } + + throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); + } + + getType(type) { + if (type === 'color') return 'vec3'; + + return type; + } + + hasGeometryAttribute(name) { + return this.geometry && this.geometry.getAttribute(name) !== undefined; + } + + getAttribute(name, type) { + const attributes = this.attributes; + + // find attribute + + for (const attribute of attributes) { + if (attribute.name === name) { + return attribute; + } + } + + // create a new if no exist + + const attribute = new NodeAttribute(name, type); + + attributes.push(attribute); + + return attribute; + } + + getPropertyName(node /*, shaderStage*/) { + return node.name; + } + + isVector(type) { + return /vec\d/.test(type); + } + + isMatrix(type) { + return /mat\d/.test(type); + } + + isReference(type) { + return ( + type === 'void' || + type === 'property' || + type === 'sampler' || + type === 'texture' || + type === 'cubeTexture' || + type === 'storageTexture' || + type === 'depthTexture' || + type === 'texture3D' + ); + } + + needsColorSpaceToLinear(/*texture*/) { + return false; + } + + getComponentTypeFromTexture(texture) { + const type = texture.type; + + if (texture.isDataTexture) { + if (type === IntType) return 'int'; + if (type === UnsignedIntType) return 'uint'; + } + + return 'float'; + } + + getElementType(type) { + if (type === 'mat2') return 'vec2'; + if (type === 'mat3') return 'vec3'; + if (type === 'mat4') return 'vec4'; + + return this.getComponentType(type); + } + + getComponentType(type) { + type = this.getVectorType(type); + + if (type === 'float' || type === 'bool' || type === 'int' || type === 'uint') return type; + + const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec(type); + + if (componentType === null) return null; + + if (componentType[1] === 'b') return 'bool'; + if (componentType[1] === 'i') return 'int'; + if (componentType[1] === 'u') return 'uint'; + + return 'float'; + } + + getVectorType(type) { + if (type === 'color') return 'vec3'; + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') + return 'vec4'; + + return type; + } + + getTypeFromLength(length, componentType = 'float') { + if (length === 1) return componentType; + + const baseType = typeFromLength.get(length); + const prefix = componentType === 'float' ? '' : componentType[0]; + + return prefix + baseType; + } + + getTypeFromArray(array) { + return typeFromArray.get(array.constructor); + } + + getTypeFromAttribute(attribute) { + let dataAttribute = attribute; + + if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; + + const array = dataAttribute.array; + const itemSize = attribute.itemSize; + const normalized = attribute.normalized; + + let arrayType; + + if (!(attribute instanceof Float16BufferAttribute) && normalized !== true) { + arrayType = this.getTypeFromArray(array); + } + + return this.getTypeFromLength(itemSize, arrayType); + } + + getTypeLength(type) { + const vecType = this.getVectorType(type); + const vecNum = /vec([2-4])/.exec(vecType); + + if (vecNum !== null) return Number(vecNum[1]); + if (vecType === 'float' || vecType === 'bool' || vecType === 'int' || vecType === 'uint') return 1; + if (/mat2/.test(type) === true) return 4; + if (/mat3/.test(type) === true) return 9; + if (/mat4/.test(type) === true) return 16; + + return 0; + } + + getVectorFromMatrix(type) { + return type.replace('mat', 'vec'); + } + + changeComponentType(type, newComponentType) { + return this.getTypeFromLength(this.getTypeLength(type), newComponentType); + } + + getIntegerType(type) { + const componentType = this.getComponentType(type); + + if (componentType === 'int' || componentType === 'uint') return type; + + return this.changeComponentType(type, 'int'); + } + + addStack() { + this.stack = stack(this.stack); + + this.stacks.push(getCurrentStack() || this.stack); + setCurrentStack(this.stack); + + return this.stack; + } + + removeStack() { + const lastStack = this.stack; + this.stack = lastStack.parent; + + setCurrentStack(this.stacks.pop()); + + return lastStack; + } + + getDataFromNode(node, shaderStage = this.shaderStage, cache = null) { + cache = cache === null ? (node.isGlobal(this) ? this.globalCache : this.cache) : cache; + + let nodeData = cache.getData(node); + + if (nodeData === undefined) { + nodeData = {}; + + cache.setData(node, nodeData); + } + + if (nodeData[shaderStage] === undefined) nodeData[shaderStage] = {}; + + return nodeData[shaderStage]; + } + + getNodeProperties(node, shaderStage = 'any') { + const nodeData = this.getDataFromNode(node, shaderStage); + + return nodeData.properties || (nodeData.properties = { outputNode: null }); + } + + getBufferAttributeFromNode(node, type) { + const nodeData = this.getDataFromNode(node); + + let bufferAttribute = nodeData.bufferAttribute; + + if (bufferAttribute === undefined) { + const index = this.uniforms.index++; + + bufferAttribute = new NodeAttribute('nodeAttribute' + index, type, node); + + this.bufferAttributes.push(bufferAttribute); + + nodeData.bufferAttribute = bufferAttribute; + } + + return bufferAttribute; + } + + getStructTypeFromNode(node, shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node, shaderStage); + + if (nodeData.structType === undefined) { + const index = this.structs.index++; + + node.name = `StructType${index}`; + this.structs[shaderStage].push(node); + + nodeData.structType = node; + } + + return node; + } + + getUniformFromNode(node, type, shaderStage = this.shaderStage, name = null) { + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + let nodeUniform = nodeData.uniform; + + if (nodeUniform === undefined) { + const index = this.uniforms.index++; + + nodeUniform = new NodeUniform(name || 'nodeUniform' + index, type, node); + + this.uniforms[shaderStage].push(nodeUniform); + + nodeData.uniform = nodeUniform; + } + + return nodeUniform; + } + + getVarFromNode(node, name = null, type = node.getNodeType(this), shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node, shaderStage); + + let nodeVar = nodeData.variable; + + if (nodeVar === undefined) { + const vars = this.vars[shaderStage] || (this.vars[shaderStage] = []); + + if (name === null) name = 'nodeVar' + vars.length; + + nodeVar = new NodeVar(name, type); + + vars.push(nodeVar); + + nodeData.variable = nodeVar; + } + + return nodeVar; + } + + getVaryingFromNode(node, name = null, type = node.getNodeType(this)) { + const nodeData = this.getDataFromNode(node, 'any'); + + let nodeVarying = nodeData.varying; + + if (nodeVarying === undefined) { + const varyings = this.varyings; + const index = varyings.length; + + if (name === null) name = 'nodeVarying' + index; + + nodeVarying = new NodeVarying(name, type); + + varyings.push(nodeVarying); + + nodeData.varying = nodeVarying; + } + + return nodeVarying; + } + + getCodeFromNode(node, type, shaderStage = this.shaderStage) { + const nodeData = this.getDataFromNode(node); + + let nodeCode = nodeData.code; + + if (nodeCode === undefined) { + const codes = this.codes[shaderStage] || (this.codes[shaderStage] = []); + const index = codes.length; + + nodeCode = new NodeCode('nodeCode' + index, type); + + codes.push(nodeCode); + + nodeData.code = nodeCode; + } + + return nodeCode; + } + + addLineFlowCode(code) { + if (code === '') return this; + + code = this.tab + code; + + if (!/;\s*$/.test(code)) { + code = code + ';\n'; + } + + this.flow.code += code; + + return this; + } + + addFlowCode(code) { + this.flow.code += code; + + return this; + } + + addFlowTab() { + this.tab += '\t'; + + return this; + } + + removeFlowTab() { + this.tab = this.tab.slice(0, -1); + + return this; + } + + getFlowData(node /*, shaderStage*/) { + return this.flowsData.get(node); + } + + flowNode(node) { + const output = node.getNodeType(this); + + const flowData = this.flowChildNode(node, output); + + this.flowsData.set(node, flowData); + + return flowData; + } + + buildFunctionNode(shaderNode) { + const fn = new FunctionNode(); + + const previous = this.currentFunctionNode; + + this.currentFunctionNode = fn; + + fn.code = this.buildFunctionCode(shaderNode); + + this.currentFunctionNode = previous; + + return fn; + } + + flowShaderNode(shaderNode) { + const layout = shaderNode.layout; + + let inputs; + + if (shaderNode.isArrayInput) { + inputs = []; + + for (const input of layout.inputs) { + inputs.push(new ParameterNode(input.type, input.name)); + } + } else { + inputs = {}; + + for (const input of layout.inputs) { + inputs[input.name] = new ParameterNode(input.type, input.name); + } + } + + // + + shaderNode.layout = null; + + const callNode = shaderNode.call(inputs); + const flowData = this.flowStagesNode(callNode, layout.type); + + shaderNode.layout = layout; + + return flowData; + } + + flowStagesNode(node, output = null) { + const previousFlow = this.flow; + const previousVars = this.vars; + const previousCache = this.cache; + const previousBuildStage = this.buildStage; + const previousStack = this.stack; + + const flow = { + code: '', + }; + + this.flow = flow; + this.vars = {}; + this.cache = new NodeCache(); + this.stack = stack(); + + for (const buildStage of defaultBuildStages) { + this.setBuildStage(buildStage); + + flow.result = node.build(this, output); + } + + flow.vars = this.getVars(this.shaderStage); + + this.flow = previousFlow; + this.vars = previousVars; + this.cache = previousCache; + this.stack = previousStack; + + this.setBuildStage(previousBuildStage); + + return flow; + } + + getFunctionOperator() { + return null; + } + + flowChildNode(node, output = null) { + const previousFlow = this.flow; + + const flow = { + code: '', + }; + + this.flow = flow; + + flow.result = node.build(this, output); + + this.flow = previousFlow; + + return flow; + } + + flowNodeFromShaderStage(shaderStage, node, output = null, propertyName = null) { + const previousShaderStage = this.shaderStage; + + this.setShaderStage(shaderStage); + + const flowData = this.flowChildNode(node, output); + + if (propertyName !== null) { + flowData.code += `${this.tab + propertyName} = ${flowData.result};\n`; + } + + this.flowCode[shaderStage] = this.flowCode[shaderStage] + flowData.code; + + this.setShaderStage(previousShaderStage); + + return flowData; + } + + getAttributesArray() { + return this.attributes.concat(this.bufferAttributes); + } + + getAttributes(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getVaryings(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getVar(type, name) { + return `${this.getType(type)} ${name}`; + } + + getVars(shaderStage) { + let snippet = ''; + + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippet += `${this.getVar(variable.type, variable.name)}; `; + } + } + + return snippet; + } + + getUniforms(/*shaderStage*/) { + console.warn('Abstract function.'); + } + + getCodes(shaderStage) { + const codes = this.codes[shaderStage]; + + let code = ''; + + if (codes !== undefined) { + for (const nodeCode of codes) { + code += nodeCode.code + '\n'; + } + } + + return code; + } + + getHash() { + return this.vertexShader + this.fragmentShader + this.computeShader; + } + + setShaderStage(shaderStage) { + this.shaderStage = shaderStage; + } + + getShaderStage() { + return this.shaderStage; + } + + setBuildStage(buildStage) { + this.buildStage = buildStage; + } + + getBuildStage() { + return this.buildStage; + } + + buildCode() { + console.warn('Abstract function.'); + } + + build() { + const { object, material } = this; + + if (material !== null) { + NodeMaterial.fromMaterial(material).build(this); + } else { + this.addFlow('compute', object); + } + + // setup() -> stage 1: create possible new nodes and returns an output reference node + // analyze() -> stage 2: analyze nodes to possible optimization and validation + // generate() -> stage 3: generate shader + + for (const buildStage of defaultBuildStages) { + this.setBuildStage(buildStage); + + if (this.context.vertex && this.context.vertex.isNode) { + this.flowNodeFromShaderStage('vertex', this.context.vertex); + } + + for (const shaderStage of shaderStages) { + this.setShaderStage(shaderStage); + + const flowNodes = this.flowNodes[shaderStage]; + + for (const node of flowNodes) { + if (buildStage === 'generate') { + this.flowNode(node); + } else { + node.build(this); + } + } + } + } + + this.setBuildStage(null); + this.setShaderStage(null); + + // stage 4: build code for a specific output + + this.buildCode(); + this.buildUpdateNodes(); + + return this; + } + + getNodeUniform(uniformNode, type) { + if (type === 'float' || type === 'int' || type === 'uint') return new NumberNodeUniform(uniformNode); + if (type === 'vec2' || type === 'ivec2' || type === 'uvec2') return new Vector2NodeUniform(uniformNode); + if (type === 'vec3' || type === 'ivec3' || type === 'uvec3') return new Vector3NodeUniform(uniformNode); + if (type === 'vec4' || type === 'ivec4' || type === 'uvec4') return new Vector4NodeUniform(uniformNode); + if (type === 'color') return new ColorNodeUniform(uniformNode); + if (type === 'mat3') return new Matrix3NodeUniform(uniformNode); + if (type === 'mat4') return new Matrix4NodeUniform(uniformNode); + + throw new Error(`Uniform "${type}" not declared.`); + } + + createNodeMaterial(type = 'NodeMaterial') { + // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support + + return createNodeMaterialFromType(type); + } + + format(snippet, fromType, toType) { + fromType = this.getVectorType(fromType); + toType = this.getVectorType(toType); + + if (fromType === toType || toType === null || this.isReference(toType)) { + return snippet; + } + + const fromTypeLength = this.getTypeLength(fromType); + const toTypeLength = this.getTypeLength(toType); + + if (fromTypeLength > 4) { + // fromType is matrix-like + + // @TODO: ignore for now + + return snippet; + } + + if (toTypeLength > 4 || toTypeLength === 0) { + // toType is matrix-like or unknown + + // @TODO: ignore for now + + return snippet; + } + + if (fromTypeLength === toTypeLength) { + return `${this.getType(toType)}( ${snippet} )`; + } + + if (fromTypeLength > toTypeLength) { + return this.format( + `${snippet}.${'xyz'.slice(0, toTypeLength)}`, + this.getTypeFromLength(toTypeLength, this.getComponentType(fromType)), + toType, + ); + } + + if (toTypeLength === 4 && fromTypeLength > 1) { + // toType is vec4-like + + return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec3')}, 1.0 )`; + } + + if (fromTypeLength === 2) { + // fromType is vec2-like and toType is vec3-like + + return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec2')}, 0.0 )`; + } + + if (fromTypeLength === 1 && toTypeLength > 1 && fromType !== this.getComponentType(toType)) { + // fromType is float-like + + // convert a number value to vector type, e.g: + // vec3( 1u ) -> vec3( float( 1u ) ) + + snippet = `${this.getType(this.getComponentType(toType))}( ${snippet} )`; + } + + return `${this.getType(toType)}( ${snippet} )`; // fromType is float-like + } + + getSignature() { + return `// Three.js r${REVISION} - Node System\n`; + } +} + +export default NodeBuilder; diff --git a/examples-jsm/examples/nodes/core/NodeCache.ts b/examples-jsm/examples/nodes/core/NodeCache.ts new file mode 100644 index 000000000..ad72d50c5 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeCache.ts @@ -0,0 +1,26 @@ +let id = 0; + +class NodeCache { + constructor(parent = null) { + this.id = id++; + this.nodesData = new WeakMap(); + + this.parent = parent; + } + + getData(node) { + let data = this.nodesData.get(node); + + if (data === undefined && this.parent !== null) { + data = this.parent.getData(node); + } + + return data; + } + + setData(node, data) { + this.nodesData.set(node, data); + } +} + +export default NodeCache; diff --git a/examples-jsm/examples/nodes/core/NodeCode.ts b/examples-jsm/examples/nodes/core/NodeCode.ts new file mode 100644 index 000000000..2ee509037 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeCode.ts @@ -0,0 +1,11 @@ +class NodeCode { + constructor(name, type, code = '') { + this.name = name; + this.type = type; + this.code = code; + + Object.defineProperty(this, 'isNodeCode', { value: true }); + } +} + +export default NodeCode; diff --git a/examples-jsm/examples/nodes/core/NodeFrame.ts b/examples-jsm/examples/nodes/core/NodeFrame.ts new file mode 100644 index 000000000..ee64620ca --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeFrame.ts @@ -0,0 +1,127 @@ +import { NodeUpdateType } from './constants.js'; + +class NodeFrame { + constructor() { + this.time = 0; + this.deltaTime = 0; + + this.frameId = 0; + this.renderId = 0; + + this.startTime = null; + + this.updateMap = new WeakMap(); + this.updateBeforeMap = new WeakMap(); + this.updateAfterMap = new WeakMap(); + + this.renderer = null; + this.material = null; + this.camera = null; + this.object = null; + this.scene = null; + } + + _getMaps(referenceMap, nodeRef) { + let maps = referenceMap.get(nodeRef); + + if (maps === undefined) { + maps = { + renderMap: new WeakMap(), + frameMap: new WeakMap(), + }; + + referenceMap.set(nodeRef, maps); + } + + return maps; + } + + updateBeforeNode(node) { + const updateType = node.getUpdateBeforeType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateBeforeMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.updateBefore(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateBeforeMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.updateBefore(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.updateBefore(this); + } + } + + updateAfterNode(node) { + const updateType = node.getUpdateAfterType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateAfterMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.updateAfter(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateAfterMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.updateAfter(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.updateAfter(this); + } + } + + updateNode(node) { + const updateType = node.getUpdateType(); + const reference = node.updateReference(this); + + if (updateType === NodeUpdateType.FRAME) { + const { frameMap } = this._getMaps(this.updateMap, reference); + + if (frameMap.get(reference) !== this.frameId) { + if (node.update(this) !== false) { + frameMap.set(reference, this.frameId); + } + } + } else if (updateType === NodeUpdateType.RENDER) { + const { renderMap } = this._getMaps(this.updateMap, reference); + + if (renderMap.get(reference) !== this.renderId) { + if (node.update(this) !== false) { + renderMap.set(reference, this.renderId); + } + } + } else if (updateType === NodeUpdateType.OBJECT) { + node.update(this); + } + } + + update() { + this.frameId++; + + if (this.lastTime === undefined) this.lastTime = performance.now(); + + this.deltaTime = (performance.now() - this.lastTime) / 1000; + + this.lastTime = performance.now(); + + this.time += this.deltaTime; + } +} + +export default NodeFrame; diff --git a/examples-jsm/examples/nodes/core/NodeFunction.ts b/examples-jsm/examples/nodes/core/NodeFunction.ts new file mode 100644 index 000000000..d05afb5e6 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeFunction.ts @@ -0,0 +1,16 @@ +class NodeFunction { + constructor(type, inputs, name = '', precision = '') { + this.type = type; + this.inputs = inputs; + this.name = name; + this.precision = precision; + } + + getCode(/*name = this.name*/) { + console.warn('Abstract function.'); + } +} + +NodeFunction.isNodeFunction = true; + +export default NodeFunction; diff --git a/examples-jsm/examples/nodes/core/NodeKeywords.ts b/examples-jsm/examples/nodes/core/NodeKeywords.ts new file mode 100644 index 000000000..1f468321b --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeKeywords.ts @@ -0,0 +1,58 @@ +class NodeKeywords { + constructor() { + this.keywords = []; + this.nodes = {}; + this.keywordsCallback = {}; + } + + getNode(name) { + let node = this.nodes[name]; + + if (node === undefined && this.keywordsCallback[name] !== undefined) { + node = this.keywordsCallback[name](name); + + this.nodes[name] = node; + } + + return node; + } + + addKeyword(name, callback) { + this.keywords.push(name); + this.keywordsCallback[name] = callback; + + return this; + } + + parse(code) { + const keywordNames = this.keywords; + + const regExp = new RegExp(`\\b${keywordNames.join('\\b|\\b')}\\b`, 'g'); + + const codeKeywords = code.match(regExp); + + const keywordNodes = []; + + if (codeKeywords !== null) { + for (const keyword of codeKeywords) { + const node = this.getNode(keyword); + + if (node !== undefined && keywordNodes.indexOf(node) === -1) { + keywordNodes.push(node); + } + } + } + + return keywordNodes; + } + + include(builder, code) { + const keywordNodes = this.parse(code); + + for (const keywordNode of keywordNodes) { + keywordNode.build(builder); + } + } +} + +export default NodeKeywords; diff --git a/examples-jsm/examples/nodes/core/NodeParser.ts b/examples-jsm/examples/nodes/core/NodeParser.ts new file mode 100644 index 000000000..9849452f1 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeParser.ts @@ -0,0 +1,7 @@ +class NodeParser { + parseFunction(/*source*/) { + console.warn('Abstract function.'); + } +} + +export default NodeParser; diff --git a/examples-jsm/examples/nodes/core/NodeUniform.ts b/examples-jsm/examples/nodes/core/NodeUniform.ts new file mode 100644 index 000000000..ca43958fc --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeUniform.ts @@ -0,0 +1,27 @@ +class NodeUniform { + constructor(name, type, node) { + this.isNodeUniform = true; + + this.name = name; + this.type = type; + this.node = node.getSelf(); + } + + get value() { + return this.node.value; + } + + set value(val) { + this.node.value = val; + } + + get id() { + return this.node.id; + } + + get groupNode() { + return this.node.groupNode; + } +} + +export default NodeUniform; diff --git a/examples-jsm/examples/nodes/core/NodeUtils.ts b/examples-jsm/examples/nodes/core/NodeUtils.ts new file mode 100644 index 000000000..16a5f3246 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeUtils.ts @@ -0,0 +1,132 @@ +import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three'; + +export function getCacheKey(object, force = false) { + let cacheKey = '{'; + + if (object.isNode === true) { + cacheKey += object.id; + } + + for (const { property, childNode } of getNodeChildren(object)) { + cacheKey += ',' + property.slice(0, -4) + ':' + childNode.getCacheKey(force); + } + + cacheKey += '}'; + + return cacheKey; +} + +export function* getNodeChildren(node, toJSON = false) { + for (const property in node) { + // Ignore private properties. + if (property.startsWith('_') === true) continue; + + const object = node[property]; + + if (Array.isArray(object) === true) { + for (let i = 0; i < object.length; i++) { + const child = object[i]; + + if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { + yield { property, index: i, childNode: child }; + } + } + } else if (object && object.isNode === true) { + yield { property, childNode: object }; + } else if (typeof object === 'object') { + for (const subProperty in object) { + const child = object[subProperty]; + + if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { + yield { property, index: subProperty, childNode: child }; + } + } + } + } +} + +export function getValueType(value) { + if (value === undefined || value === null) return null; + + const typeOf = typeof value; + + if (value.isNode === true) { + return 'node'; + } else if (typeOf === 'number') { + return 'float'; + } else if (typeOf === 'boolean') { + return 'bool'; + } else if (typeOf === 'string') { + return 'string'; + } else if (typeOf === 'function') { + return 'shader'; + } else if (value.isVector2 === true) { + return 'vec2'; + } else if (value.isVector3 === true) { + return 'vec3'; + } else if (value.isVector4 === true) { + return 'vec4'; + } else if (value.isMatrix3 === true) { + return 'mat3'; + } else if (value.isMatrix4 === true) { + return 'mat4'; + } else if (value.isColor === true) { + return 'color'; + } else if (value instanceof ArrayBuffer) { + return 'ArrayBuffer'; + } + + return null; +} + +export function getValueFromType(type, ...params) { + const last4 = type ? type.slice(-4) : undefined; + + if (params.length === 1) { + // ensure same behaviour as in NodeBuilder.format() + + if (last4 === 'vec2') params = [params[0], params[0]]; + else if (last4 === 'vec3') params = [params[0], params[0], params[0]]; + else if (last4 === 'vec4') params = [params[0], params[0], params[0], params[0]]; + } + + if (type === 'color') { + return new Color(...params); + } else if (last4 === 'vec2') { + return new Vector2(...params); + } else if (last4 === 'vec3') { + return new Vector3(...params); + } else if (last4 === 'vec4') { + return new Vector4(...params); + } else if (last4 === 'mat3') { + return new Matrix3(...params); + } else if (last4 === 'mat4') { + return new Matrix4(...params); + } else if (type === 'bool') { + return params[0] || false; + } else if (type === 'float' || type === 'int' || type === 'uint') { + return params[0] || 0; + } else if (type === 'string') { + return params[0] || ''; + } else if (type === 'ArrayBuffer') { + return base64ToArrayBuffer(params[0]); + } + + return null; +} + +export function arrayBufferToBase64(arrayBuffer) { + let chars = ''; + + const array = new Uint8Array(arrayBuffer); + + for (let i = 0; i < array.length; i++) { + chars += String.fromCharCode(array[i]); + } + + return btoa(chars); +} + +export function base64ToArrayBuffer(base64) { + return Uint8Array.from(atob(base64), c => c.charCodeAt(0)).buffer; +} diff --git a/examples-jsm/examples/nodes/core/NodeVar.ts b/examples-jsm/examples/nodes/core/NodeVar.ts new file mode 100644 index 000000000..e6e935b31 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeVar.ts @@ -0,0 +1,10 @@ +class NodeVar { + constructor(name, type) { + this.isNodeVar = true; + + this.name = name; + this.type = type; + } +} + +export default NodeVar; diff --git a/examples-jsm/examples/nodes/core/NodeVarying.ts b/examples-jsm/examples/nodes/core/NodeVarying.ts new file mode 100644 index 000000000..a14823628 --- /dev/null +++ b/examples-jsm/examples/nodes/core/NodeVarying.ts @@ -0,0 +1,13 @@ +import NodeVar from './NodeVar.js'; + +class NodeVarying extends NodeVar { + constructor(name, type) { + super(name, type); + + this.needsInterpolation = false; + + this.isNodeVarying = true; + } +} + +export default NodeVarying; diff --git a/examples-jsm/examples/nodes/core/StackNode.ts b/examples-jsm/examples/nodes/core/StackNode.ts new file mode 100644 index 000000000..d93226072 --- /dev/null +++ b/examples-jsm/examples/nodes/core/StackNode.ts @@ -0,0 +1,71 @@ +import Node, { addNodeClass } from './Node.js'; +import { cond } from '../math/CondNode.js'; +import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js'; + +class StackNode extends Node { + constructor(parent = null) { + super(); + + this.nodes = []; + this.outputNode = null; + + this.parent = parent; + + this._currentCond = null; + + this.isStackNode = true; + } + + getNodeType(builder) { + return this.outputNode ? this.outputNode.getNodeType(builder) : 'void'; + } + + add(node) { + this.nodes.push(node); + + return this; + } + + if(boolNode, method) { + const methodNode = new ShaderNode(method); + this._currentCond = cond(boolNode, methodNode); + + return this.add(this._currentCond); + } + + elseif(boolNode, method) { + const methodNode = new ShaderNode(method); + const ifNode = cond(boolNode, methodNode); + + this._currentCond.elseNode = ifNode; + this._currentCond = ifNode; + + return this; + } + + else(method) { + this._currentCond.elseNode = new ShaderNode(method); + + return this; + } + + build(builder, ...params) { + const previousStack = getCurrentStack(); + + setCurrentStack(this); + + for (const node of this.nodes) { + node.build(builder, 'void'); + } + + setCurrentStack(previousStack); + + return this.outputNode ? this.outputNode.build(builder, ...params) : super.build(builder, ...params); + } +} + +export default StackNode; + +export const stack = nodeProxy(StackNode); + +addNodeClass('StackNode', StackNode); diff --git a/examples-jsm/examples/nodes/core/StructTypeNode.ts b/examples-jsm/examples/nodes/core/StructTypeNode.ts new file mode 100644 index 000000000..697187999 --- /dev/null +++ b/examples-jsm/examples/nodes/core/StructTypeNode.ts @@ -0,0 +1,18 @@ +import Node, { addNodeClass } from './Node.js'; + +class StructTypeNode extends Node { + constructor(types) { + super(); + + this.types = types; + this.isStructTypeNode = true; + } + + getMemberTypes() { + return this.types; + } +} + +export default StructTypeNode; + +addNodeClass('StructTypeNode', StructTypeNode); diff --git a/examples-jsm/examples/nodes/core/UniformGroupNode.ts b/examples-jsm/examples/nodes/core/UniformGroupNode.ts new file mode 100644 index 000000000..f8bb2b37d --- /dev/null +++ b/examples-jsm/examples/nodes/core/UniformGroupNode.ts @@ -0,0 +1,30 @@ +import Node from './Node.js'; +import { addNodeClass } from './Node.js'; + +class UniformGroupNode extends Node { + constructor(name, shared = false) { + super('string'); + + this.name = name; + this.version = 0; + + this.shared = shared; + + this.isUniformGroup = true; + } + + set needsUpdate(value) { + if (value === true) this.version++; + } +} + +export const uniformGroup = name => new UniformGroupNode(name); +export const sharedUniformGroup = name => new UniformGroupNode(name, true); + +export const frameGroup = sharedUniformGroup('frame'); +export const renderGroup = sharedUniformGroup('render'); +export const objectGroup = uniformGroup('object'); + +export default UniformGroupNode; + +addNodeClass('UniformGroupNode', UniformGroupNode); diff --git a/examples-jsm/examples/nodes/core/UniformNode.ts b/examples-jsm/examples/nodes/core/UniformNode.ts new file mode 100644 index 000000000..41e523c4f --- /dev/null +++ b/examples-jsm/examples/nodes/core/UniformNode.ts @@ -0,0 +1,90 @@ +import InputNode from './InputNode.js'; +import { objectGroup } from './UniformGroupNode.js'; +import { addNodeClass } from './Node.js'; +import { nodeObject, getConstNodeType } from '../shadernode/ShaderNode.js'; + +class UniformNode extends InputNode { + constructor(value, nodeType = null) { + super(value, nodeType); + + this.isUniformNode = true; + + this.name = ''; + this.groupNode = objectGroup; + } + + label(name) { + this.name = name; + + return this; + } + + setGroup(group) { + this.groupNode = group; + + return this; + } + + getGroup() { + return this.groupNode; + } + + getUniformHash(builder) { + return this.getHash(builder); + } + + onUpdate(callback, updateType) { + const self = this.getSelf(); + + callback = callback.bind(self); + + return super.onUpdate(frame => { + const value = callback(frame, self); + + if (value !== undefined) { + this.value = value; + } + }, updateType); + } + + generate(builder, output) { + const type = this.getNodeType(builder); + + const hash = this.getUniformHash(builder); + + let sharedNode = builder.getNodeFromHash(hash); + + if (sharedNode === undefined) { + builder.setHashNode(this, hash); + + sharedNode = this; + } + + const sharedNodeType = sharedNode.getInputType(builder); + + const nodeUniform = builder.getUniformFromNode( + sharedNode, + sharedNodeType, + builder.shaderStage, + this.name || builder.context.label, + ); + const propertyName = builder.getPropertyName(nodeUniform); + + if (builder.context.label !== undefined) delete builder.context.label; + + return builder.format(propertyName, type, output); + } +} + +export default UniformNode; + +export const uniform = (arg1, arg2) => { + const nodeType = getConstNodeType(arg2 || arg1); + + // @TODO: get ConstNode from .traverse() in the future + const value = arg1 && arg1.isNode === true ? (arg1.node && arg1.node.value) || arg1.value : arg1; + + return nodeObject(new UniformNode(value, nodeType)); +}; + +addNodeClass('UniformNode', UniformNode); diff --git a/examples-jsm/examples/nodes/core/constants.ts b/examples-jsm/examples/nodes/core/constants.ts new file mode 100644 index 000000000..3b01a9a6d --- /dev/null +++ b/examples-jsm/examples/nodes/core/constants.ts @@ -0,0 +1,28 @@ +export const NodeShaderStage = { + VERTEX: 'vertex', + FRAGMENT: 'fragment', +}; + +export const NodeUpdateType = { + NONE: 'none', + FRAME: 'frame', + RENDER: 'render', + OBJECT: 'object', +}; + +export const NodeType = { + BOOLEAN: 'bool', + INTEGER: 'int', + FLOAT: 'float', + VECTOR2: 'vec2', + VECTOR3: 'vec3', + VECTOR4: 'vec4', + MATRIX2: 'mat2', + MATRIX3: 'mat3', + MATRIX4: 'mat4', +}; + +export const defaultShaderStages = ['fragment', 'vertex']; +export const defaultBuildStages = ['setup', 'analyze', 'generate']; +export const shaderStages = [...defaultShaderStages, 'compute']; +export const vectorComponents = ['x', 'y', 'z', 'w']; diff --git a/examples-jsm/examples/nodes/fog/FogNode.ts b/examples-jsm/examples/nodes/fog/FogNode.ts new file mode 100644 index 000000000..9417df5a5 --- /dev/null +++ b/examples-jsm/examples/nodes/fog/FogNode.ts @@ -0,0 +1,38 @@ +import Node, { addNodeClass } from '../core/Node.js'; +import { positionView } from '../accessors/PositionNode.js'; +import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js'; + +class FogNode extends Node { + constructor(colorNode, factorNode) { + super('float'); + + this.isFogNode = true; + + this.colorNode = colorNode; + this.factorNode = factorNode; + } + + getViewZNode(builder) { + let viewZ; + + const getViewZ = builder.context.getViewZ; + + if (getViewZ !== undefined) { + viewZ = getViewZ(this); + } + + return (viewZ || positionView.z).negate(); + } + + setup() { + return this.factorNode; + } +} + +export default FogNode; + +export const fog = nodeProxy(FogNode); + +addNodeElement('fog', fog); + +addNodeClass('FogNode', FogNode); diff --git a/examples-jsm/examples/nodes/gpgpu/ComputeNode.ts b/examples-jsm/examples/nodes/gpgpu/ComputeNode.ts new file mode 100644 index 000000000..ab2925a55 --- /dev/null +++ b/examples-jsm/examples/nodes/gpgpu/ComputeNode.ts @@ -0,0 +1,67 @@ +import Node, { addNodeClass } from '../core/Node.js'; +import { NodeUpdateType } from '../core/constants.js'; +import { addNodeElement, nodeObject } from '../shadernode/ShaderNode.js'; + +class ComputeNode extends Node { + constructor(computeNode, count, workgroupSize = [64]) { + super('void'); + + this.isComputeNode = true; + + this.computeNode = computeNode; + + this.count = count; + this.workgroupSize = workgroupSize; + this.dispatchCount = 0; + + this.version = 1; + this.updateBeforeType = NodeUpdateType.OBJECT; + + this.updateDispatchCount(); + } + + dispose() { + this.dispatchEvent({ type: 'dispose' }); + } + + set needsUpdate(value) { + if (value === true) this.version++; + } + + updateDispatchCount() { + const { count, workgroupSize } = this; + + let size = workgroupSize[0]; + + for (let i = 1; i < workgroupSize.length; i++) size *= workgroupSize[i]; + + this.dispatchCount = Math.ceil(count / size); + } + + onInit() {} + + updateBefore({ renderer }) { + renderer.compute(this); + } + + generate(builder) { + const { shaderStage } = builder; + + if (shaderStage === 'compute') { + const snippet = this.computeNode.build(builder, 'void'); + + if (snippet !== '') { + builder.addLineFlowCode(snippet); + } + } + } +} + +export default ComputeNode; + +export const compute = (node, count, workgroupSize) => + nodeObject(new ComputeNode(nodeObject(node), count, workgroupSize)); + +addNodeElement('compute', compute); + +addNodeClass('ComputeNode', ComputeNode); diff --git a/examples-jsm/examples/nodes/lighting/EnvironmentNode.ts b/examples-jsm/examples/nodes/lighting/EnvironmentNode.ts new file mode 100644 index 000000000..31ddc8b09 --- /dev/null +++ b/examples-jsm/examples/nodes/lighting/EnvironmentNode.ts @@ -0,0 +1,119 @@ +import LightingNode from './LightingNode.js'; +import { cache } from '../core/CacheNode.js'; +import { context } from '../core/ContextNode.js'; +import { roughness, clearcoatRoughness } from '../core/PropertyNode.js'; +import { cameraViewMatrix } from '../accessors/CameraNode.js'; +import { + transformedClearcoatNormalView, + transformedNormalView, + transformedNormalWorld, +} from '../accessors/NormalNode.js'; +import { positionViewDirection } from '../accessors/PositionNode.js'; +import { addNodeClass } from '../core/Node.js'; +import { float } from '../shadernode/ShaderNode.js'; +import { reference } from '../accessors/ReferenceNode.js'; +import { transformedBentNormalView } from '../accessors/AccessorsUtils.js'; +import { pmremTexture } from '../pmrem/PMREMNode.js'; + +const envNodeCache = new WeakMap(); + +class EnvironmentNode extends LightingNode { + constructor(envNode = null) { + super(); + + this.envNode = envNode; + } + + setup(builder) { + let envNode = this.envNode; + + if (envNode.isTextureNode) { + let cacheEnvNode = envNodeCache.get(envNode.value); + + if (cacheEnvNode === undefined) { + cacheEnvNode = pmremTexture(envNode.value); + + envNodeCache.set(envNode.value, cacheEnvNode); + } + + envNode = cacheEnvNode; + } + + // + + const { material } = builder; + + const envMap = material.envMap; + const intensity = envMap + ? reference('envMapIntensity', 'float', builder.material) + : reference('environmentIntensity', 'float', builder.scene); // @TODO: Add materialEnvIntensity in MaterialNode + + const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0; + const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView; + + const radiance = context(envNode, createRadianceContext(roughness, radianceNormalView)).mul(intensity); + const irradiance = context(envNode, createIrradianceContext(transformedNormalWorld)) + .mul(Math.PI) + .mul(intensity); + + const isolateRadiance = cache(radiance); + const isolateIrradiance = cache(irradiance); + + // + + builder.context.radiance.addAssign(isolateRadiance); + + builder.context.iblIrradiance.addAssign(isolateIrradiance); + + // + + const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance; + + if (clearcoatRadiance) { + const clearcoatRadianceContext = context( + envNode, + createRadianceContext(clearcoatRoughness, transformedClearcoatNormalView), + ).mul(intensity); + const isolateClearcoatRadiance = cache(clearcoatRadianceContext); + + clearcoatRadiance.addAssign(isolateClearcoatRadiance); + } + } +} + +const createRadianceContext = (roughnessNode, normalViewNode) => { + let reflectVec = null; + + return { + getUV: () => { + if (reflectVec === null) { + reflectVec = positionViewDirection.negate().reflect(normalViewNode); + + // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. + reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize(); + + reflectVec = reflectVec.transformDirection(cameraViewMatrix); + } + + return reflectVec; + }, + getTextureLevel: () => { + return roughnessNode; + }, + }; +}; + +const createIrradianceContext = normalWorldNode => { + return { + getUV: () => { + return normalWorldNode; + }, + getTextureLevel: () => { + return float(1.0); + }, + }; +}; + +export default EnvironmentNode; + +addNodeClass('EnvironmentNode', EnvironmentNode); diff --git a/examples-jsm/examples/nodes/lighting/LightingContextNode.ts b/examples-jsm/examples/nodes/lighting/LightingContextNode.ts new file mode 100644 index 000000000..02a8b51f8 --- /dev/null +++ b/examples-jsm/examples/nodes/lighting/LightingContextNode.ts @@ -0,0 +1,58 @@ +import ContextNode from '../core/ContextNode.js'; +import { addNodeClass } from '../core/Node.js'; +import { addNodeElement, nodeProxy, float, vec3 } from '../shadernode/ShaderNode.js'; + +class LightingContextNode extends ContextNode { + constructor(node, lightingModel = null, backdropNode = null, backdropAlphaNode = null) { + super(node); + + this.lightingModel = lightingModel; + this.backdropNode = backdropNode; + this.backdropAlphaNode = backdropAlphaNode; + + this._context = null; + } + + getContext() { + const { backdropNode, backdropAlphaNode } = this; + + const directDiffuse = vec3().temp('directDiffuse'), + directSpecular = vec3().temp('directSpecular'), + indirectDiffuse = vec3().temp('indirectDiffuse'), + indirectSpecular = vec3().temp('indirectSpecular'); + + const reflectedLight = { + directDiffuse, + directSpecular, + indirectDiffuse, + indirectSpecular, + }; + + const context = { + radiance: vec3().temp('radiance'), + irradiance: vec3().temp('irradiance'), + iblIrradiance: vec3().temp('iblIrradiance'), + ambientOcclusion: float(1).temp('ambientOcclusion'), + reflectedLight, + backdrop: backdropNode, + backdropAlpha: backdropAlphaNode, + }; + + return context; + } + + setup(builder) { + this.context = this._context || (this._context = this.getContext()); + this.context.lightingModel = this.lightingModel || builder.context.lightingModel; + + return super.setup(builder); + } +} + +export default LightingContextNode; + +export const lightingContext = nodeProxy(LightingContextNode); + +addNodeElement('lightingContext', lightingContext); + +addNodeClass('LightingContextNode', LightingContextNode); diff --git a/examples-jsm/examples/nodes/lighting/LightsNode.ts b/examples-jsm/examples/nodes/lighting/LightsNode.ts new file mode 100644 index 000000000..96e5c60ab --- /dev/null +++ b/examples-jsm/examples/nodes/lighting/LightsNode.ts @@ -0,0 +1,170 @@ +import Node from '../core/Node.js'; +import AnalyticLightNode from './AnalyticLightNode.js'; +import { nodeObject, nodeProxy, vec3 } from '../shadernode/ShaderNode.js'; + +const LightNodes = new WeakMap(); + +const sortLights = lights => { + return lights.sort((a, b) => a.id - b.id); +}; + +class LightsNode extends Node { + constructor(lightNodes = []) { + super('vec3'); + + this.totalDiffuseNode = vec3().temp('totalDiffuse'); + this.totalSpecularNode = vec3().temp('totalSpecular'); + + this.outgoingLightNode = vec3().temp('outgoingLight'); + + this.lightNodes = lightNodes; + + this._hash = null; + } + + get hasLight() { + return this.lightNodes.length > 0; + } + + getHash() { + if (this._hash === null) { + const hash = []; + + for (const lightNode of this.lightNodes) { + hash.push(lightNode.getHash()); + } + + this._hash = 'lights-' + hash.join(','); + } + + return this._hash; + } + + analyze(builder) { + const properties = builder.getDataFromNode(this); + + for (const node of properties.nodes) { + node.build(builder); + } + } + + setup(builder) { + const context = builder.context; + const lightingModel = context.lightingModel; + + let outgoingLightNode = this.outgoingLightNode; + + if (lightingModel) { + const { lightNodes, totalDiffuseNode, totalSpecularNode } = this; + + context.outgoingLight = outgoingLightNode; + + const stack = builder.addStack(); + + // + + const properties = builder.getDataFromNode(this); + properties.nodes = stack.nodes; + + // + + lightingModel.start(context, stack, builder); + + // lights + + for (const lightNode of lightNodes) { + lightNode.build(builder); + } + + // + + lightingModel.indirectDiffuse(context, stack, builder); + lightingModel.indirectSpecular(context, stack, builder); + lightingModel.ambientOcclusion(context, stack, builder); + + // + + const { backdrop, backdropAlpha } = context; + const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context.reflectedLight; + + let totalDiffuse = directDiffuse.add(indirectDiffuse); + + if (backdrop !== null) { + if (backdropAlpha !== null) { + totalDiffuse = vec3(backdropAlpha.mix(totalDiffuse, backdrop)); + } else { + totalDiffuse = vec3(backdrop); + } + + context.material.transparent = true; + } + + totalDiffuseNode.assign(totalDiffuse); + totalSpecularNode.assign(directSpecular.add(indirectSpecular)); + + outgoingLightNode.assign(totalDiffuseNode.add(totalSpecularNode)); + + // + + lightingModel.finish(context, stack, builder); + + // + + outgoingLightNode = outgoingLightNode.bypass(builder.removeStack()); + } + + return outgoingLightNode; + } + + _getLightNodeById(id) { + for (const lightNode of this.lightNodes) { + if (lightNode.isAnalyticLightNode && lightNode.light.id === id) { + return lightNode; + } + } + + return null; + } + + fromLights(lights = []) { + const lightNodes = []; + + lights = sortLights(lights); + + for (const light of lights) { + let lightNode = this._getLightNodeById(light.id); + + if (lightNode === null) { + const lightClass = light.constructor; + const lightNodeClass = LightNodes.has(lightClass) ? LightNodes.get(lightClass) : AnalyticLightNode; + + lightNode = nodeObject(new lightNodeClass(light)); + } + + lightNodes.push(lightNode); + } + + this.lightNodes = lightNodes; + this._hash = null; + + return this; + } +} + +export default LightsNode; + +export const lights = lights => nodeObject(new LightsNode().fromLights(lights)); +export const lightsNode = nodeProxy(LightsNode); + +export function addLightNode(lightClass, lightNodeClass) { + if (LightNodes.has(lightClass)) { + console.warn(`Redefinition of light node ${lightNodeClass.type}`); + return; + } + + if (typeof lightClass !== 'function') throw new Error(`Light ${lightClass.name} is not a class`); + if (typeof lightNodeClass !== 'function' || !lightNodeClass.type) + throw new Error(`Light node ${lightNodeClass.type} is not a class`); + + LightNodes.set(lightClass, lightNodeClass); +} diff --git a/examples-jsm/examples/nodes/materials/NodeMaterial.ts b/examples-jsm/examples/nodes/materials/NodeMaterial.ts new file mode 100644 index 000000000..d0c7c6cd9 --- /dev/null +++ b/examples-jsm/examples/nodes/materials/NodeMaterial.ts @@ -0,0 +1,514 @@ +import { Material, NormalBlending } from 'three'; +import { getNodeChildren, getCacheKey } from '../core/NodeUtils.js'; +import { attribute } from '../core/AttributeNode.js'; +import { output, diffuseColor, varyingProperty } from '../core/PropertyNode.js'; +import { + materialAlphaTest, + materialColor, + materialOpacity, + materialEmissive, + materialNormal, +} from '../accessors/MaterialNode.js'; +import { modelViewProjection } from '../accessors/ModelViewProjectionNode.js'; +import { transformedNormalView, normalLocal } from '../accessors/NormalNode.js'; +import { instance } from '../accessors/InstanceNode.js'; +import { batch } from '../accessors/BatchNode.js'; +import { materialReference } from '../accessors/MaterialReferenceNode.js'; +import { positionLocal, positionView } from '../accessors/PositionNode.js'; +import { skinningReference } from '../accessors/SkinningNode.js'; +import { morphReference } from '../accessors/MorphNode.js'; +import { texture } from '../accessors/TextureNode.js'; +import { cubeTexture } from '../accessors/CubeTextureNode.js'; +import { lightsNode } from '../lighting/LightsNode.js'; +import { mix } from '../math/MathNode.js'; +import { float, vec3, vec4 } from '../shadernode/ShaderNode.js'; +import AONode from '../lighting/AONode.js'; +import { lightingContext } from '../lighting/LightingContextNode.js'; +import EnvironmentNode from '../lighting/EnvironmentNode.js'; +import IrradianceNode from '../lighting/IrradianceNode.js'; +import { depth } from '../display/ViewportDepthNode.js'; +import { cameraLogDepth } from '../accessors/CameraNode.js'; +import { clipping, clippingAlpha } from '../accessors/ClippingNode.js'; +import { faceDirection } from '../display/FrontFacingNode.js'; + +const NodeMaterials = new Map(); + +class NodeMaterial extends Material { + constructor() { + super(); + + this.isNodeMaterial = true; + + this.type = this.constructor.type; + + this.forceSinglePass = false; + + this.fog = true; + this.lights = true; + this.normals = true; + + this.lightsNode = null; + this.envNode = null; + this.aoNode = null; + + this.colorNode = null; + this.normalNode = null; + this.opacityNode = null; + this.backdropNode = null; + this.backdropAlphaNode = null; + this.alphaTestNode = null; + + this.positionNode = null; + + this.depthNode = null; + this.shadowNode = null; + this.shadowPositionNode = null; + + this.outputNode = null; + + this.fragmentNode = null; + this.vertexNode = null; + } + + customProgramCacheKey() { + return this.type + getCacheKey(this); + } + + build(builder) { + this.setup(builder); + } + + setup(builder) { + // < VERTEX STAGE > + + builder.addStack(); + + builder.stack.outputNode = this.vertexNode || this.setupPosition(builder); + + builder.addFlow('vertex', builder.removeStack()); + + // < FRAGMENT STAGE > + + builder.addStack(); + + let resultNode; + + const clippingNode = this.setupClipping(builder); + + if (this.depthWrite === true) this.setupDepth(builder); + + if (this.fragmentNode === null) { + if (this.normals === true) this.setupNormal(builder); + + this.setupDiffuseColor(builder); + this.setupVariants(builder); + + const outgoingLightNode = this.setupLighting(builder); + + if (clippingNode !== null) builder.stack.add(clippingNode); + + // force unsigned floats - useful for RenderTargets + + const basicOutput = vec4(outgoingLightNode, diffuseColor.a).max(0); + + resultNode = this.setupOutput(builder, basicOutput); + + // OUTPUT NODE + + output.assign(resultNode); + + // + + if (this.outputNode !== null) resultNode = this.outputNode; + } else { + let fragmentNode = this.fragmentNode; + + if (fragmentNode.isOutputStructNode !== true) { + fragmentNode = vec4(fragmentNode); + } + + resultNode = this.setupOutput(builder, fragmentNode); + } + + builder.stack.outputNode = resultNode; + + builder.addFlow('fragment', builder.removeStack()); + } + + setupClipping(builder) { + if (builder.clippingContext === null) return null; + + const { globalClippingCount, localClippingCount } = builder.clippingContext; + + let result = null; + + if (globalClippingCount || localClippingCount) { + if (this.alphaToCoverage) { + // to be added to flow when the color/alpha value has been determined + result = clippingAlpha(); + } else { + builder.stack.add(clipping()); + } + } + + return result; + } + + setupDepth(builder) { + const { renderer } = builder; + + // Depth + + let depthNode = this.depthNode; + + if (depthNode === null && renderer.logarithmicDepthBuffer === true) { + const fragDepth = modelViewProjection().w.add(1); + + depthNode = fragDepth.log2().mul(cameraLogDepth).mul(0.5); + } + + if (depthNode !== null) { + depth.assign(depthNode).append(); + } + } + + setupPosition(builder) { + const { object } = builder; + const geometry = object.geometry; + + builder.addStack(); + + // Vertex + + if (geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color) { + morphReference(object).append(); + } + + if (object.isSkinnedMesh === true) { + skinningReference(object).append(); + } + + if (this.displacementMap) { + const displacementMap = materialReference('displacementMap', 'texture'); + const displacementScale = materialReference('displacementScale', 'float'); + const displacementBias = materialReference('displacementBias', 'float'); + + positionLocal.addAssign( + normalLocal.normalize().mul(displacementMap.x.mul(displacementScale).add(displacementBias)), + ); + } + + if (object.isBatchedMesh) { + batch(object).append(); + } + + if (object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true) { + instance(object).append(); + } + + if (this.positionNode !== null) { + positionLocal.assign(this.positionNode); + } + + const mvp = modelViewProjection(); + + builder.context.vertex = builder.removeStack(); + builder.context.mvp = mvp; + + return mvp; + } + + setupDiffuseColor({ object, geometry }) { + let colorNode = this.colorNode ? vec4(this.colorNode) : materialColor; + + // VERTEX COLORS + + if (this.vertexColors === true && geometry.hasAttribute('color')) { + colorNode = vec4(colorNode.xyz.mul(attribute('color', 'vec3')), colorNode.a); + } + + // Instanced colors + + if (object.instanceColor) { + const instanceColor = varyingProperty('vec3', 'vInstanceColor'); + + colorNode = instanceColor.mul(colorNode); + } + + // COLOR + + diffuseColor.assign(colorNode); + + // OPACITY + + const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; + diffuseColor.a.assign(diffuseColor.a.mul(opacityNode)); + + // ALPHA TEST + + if (this.alphaTestNode !== null || this.alphaTest > 0) { + const alphaTestNode = this.alphaTestNode !== null ? float(this.alphaTestNode) : materialAlphaTest; + + diffuseColor.a.lessThanEqual(alphaTestNode).discard(); + } + + if (this.transparent === false && this.blending === NormalBlending && this.alphaToCoverage === false) { + diffuseColor.a.assign(1.0); + } + } + + setupVariants(/*builder*/) { + // Interface function. + } + + setupNormal() { + // NORMAL VIEW + + if (this.flatShading === true) { + const normalNode = positionView.dFdx().cross(positionView.dFdy()).normalize(); + + transformedNormalView.assign(normalNode.mul(faceDirection)); + } else { + const normalNode = this.normalNode ? vec3(this.normalNode) : materialNormal; + + transformedNormalView.assign(normalNode.mul(faceDirection)); + } + } + + getEnvNode(builder) { + let node = null; + + if (this.envNode) { + node = this.envNode; + } else if (this.envMap) { + node = this.envMap.isCubeTexture ? cubeTexture(this.envMap) : texture(this.envMap); + } else if (builder.environmentNode) { + node = builder.environmentNode; + } + + return node; + } + + setupLights(builder) { + const envNode = this.getEnvNode(builder); + + // + + const materialLightsNode = []; + + if (envNode) { + materialLightsNode.push(new EnvironmentNode(envNode)); + } + + if (builder.material.lightMap) { + materialLightsNode.push(new IrradianceNode(materialReference('lightMap', 'texture'))); + } + + if (this.aoNode !== null || builder.material.aoMap) { + const aoNode = this.aoNode !== null ? this.aoNode : texture(builder.material.aoMap); + + materialLightsNode.push(new AONode(aoNode)); + } + + let lightsN = this.lightsNode || builder.lightsNode; + + if (materialLightsNode.length > 0) { + lightsN = lightsNode([...lightsN.lightNodes, ...materialLightsNode]); + } + + return lightsN; + } + + setupLightingModel(/*builder*/) { + // Interface function. + } + + setupLighting(builder) { + const { material } = builder; + const { backdropNode, backdropAlphaNode, emissiveNode } = this; + + // OUTGOING LIGHT + + const lights = this.lights === true || this.lightsNode !== null; + + const lightsNode = lights ? this.setupLights(builder) : null; + + let outgoingLightNode = diffuseColor.rgb; + + if (lightsNode && lightsNode.hasLight !== false) { + const lightingModel = this.setupLightingModel(builder); + + outgoingLightNode = lightingContext(lightsNode, lightingModel, backdropNode, backdropAlphaNode); + } else if (backdropNode !== null) { + outgoingLightNode = vec3( + backdropAlphaNode !== null ? mix(outgoingLightNode, backdropNode, backdropAlphaNode) : backdropNode, + ); + } + + // EMISSIVE + + if ( + (emissiveNode && emissiveNode.isNode === true) || + (material.emissive && material.emissive.isColor === true) + ) { + outgoingLightNode = outgoingLightNode.add(vec3(emissiveNode ? emissiveNode : materialEmissive)); + } + + return outgoingLightNode; + } + + setupOutput(builder, outputNode) { + // FOG + + if (this.fog === true) { + const fogNode = builder.fogNode; + + if (fogNode) outputNode = vec4(fogNode.mix(outputNode.rgb, fogNode.colorNode), outputNode.a); + } + + return outputNode; + } + + setDefaultValues(material) { + // This approach is to reuse the native refreshUniforms* + // and turn available the use of features like transmission and environment in core + + for (const property in material) { + const value = material[property]; + + if (this[property] === undefined) { + this[property] = value; + + if (value && value.clone) this[property] = value.clone(); + } + } + + const descriptors = Object.getOwnPropertyDescriptors(material.constructor.prototype); + + for (const key in descriptors) { + if ( + Object.getOwnPropertyDescriptor(this.constructor.prototype, key) === undefined && + descriptors[key].get !== undefined + ) { + Object.defineProperty(this.constructor.prototype, key, descriptors[key]); + } + } + } + + toJSON(meta) { + const isRoot = meta === undefined || typeof meta === 'string'; + + if (isRoot) { + meta = { + textures: {}, + images: {}, + nodes: {}, + }; + } + + const data = Material.prototype.toJSON.call(this, meta); + const nodeChildren = getNodeChildren(this); + + data.inputNodes = {}; + + for (const { property, childNode } of nodeChildren) { + data.inputNodes[property] = childNode.toJSON(meta).uuid; + } + + // TODO: Copied from Object3D.toJSON + + function extractFromCache(cache) { + const values = []; + + for (const key in cache) { + const data = cache[key]; + delete data.metadata; + values.push(data); + } + + return values; + } + + if (isRoot) { + const textures = extractFromCache(meta.textures); + const images = extractFromCache(meta.images); + const nodes = extractFromCache(meta.nodes); + + if (textures.length > 0) data.textures = textures; + if (images.length > 0) data.images = images; + if (nodes.length > 0) data.nodes = nodes; + } + + return data; + } + + copy(source) { + this.lightsNode = source.lightsNode; + this.envNode = source.envNode; + + this.colorNode = source.colorNode; + this.normalNode = source.normalNode; + this.opacityNode = source.opacityNode; + this.backdropNode = source.backdropNode; + this.backdropAlphaNode = source.backdropAlphaNode; + this.alphaTestNode = source.alphaTestNode; + + this.positionNode = source.positionNode; + + this.depthNode = source.depthNode; + this.shadowNode = source.shadowNode; + this.shadowPositionNode = source.shadowPositionNode; + + this.outputNode = source.outputNode; + + this.fragmentNode = source.fragmentNode; + this.vertexNode = source.vertexNode; + + return super.copy(source); + } + + static fromMaterial(material) { + if (material.isNodeMaterial === true) { + // is already a node material + + return material; + } + + const type = material.type.replace('Material', 'NodeMaterial'); + + const nodeMaterial = createNodeMaterialFromType(type); + + if (nodeMaterial === undefined) { + throw new Error(`NodeMaterial: Material "${material.type}" is not compatible.`); + } + + for (const key in material) { + nodeMaterial[key] = material[key]; + } + + return nodeMaterial; + } +} + +export default NodeMaterial; + +export function addNodeMaterial(type, nodeMaterial) { + if (typeof nodeMaterial !== 'function' || !type) throw new Error(`Node material ${type} is not a class`); + if (NodeMaterials.has(type)) { + console.warn(`Redefinition of node material ${type}`); + return; + } + + NodeMaterials.set(type, nodeMaterial); + nodeMaterial.type = type; +} + +export function createNodeMaterialFromType(type) { + const Material = NodeMaterials.get(type); + + if (Material !== undefined) { + return new Material(); + } +} + +addNodeMaterial('NodeMaterial', NodeMaterial); diff --git a/examples-jsm/examples/nodes/shadernode/ShaderNode.ts b/examples-jsm/examples/nodes/shadernode/ShaderNode.ts new file mode 100644 index 000000000..288ffa3d8 --- /dev/null +++ b/examples-jsm/examples/nodes/shadernode/ShaderNode.ts @@ -0,0 +1,532 @@ +import Node, { addNodeClass } from '../core/Node.js'; +import ArrayElementNode from '../utils/ArrayElementNode.js'; +import ConvertNode from '../utils/ConvertNode.js'; +import JoinNode from '../utils/JoinNode.js'; +import SplitNode from '../utils/SplitNode.js'; +import SetNode from '../utils/SetNode.js'; +import ConstNode from '../core/ConstNode.js'; +import { getValueFromType, getValueType } from '../core/NodeUtils.js'; + +// + +let currentStack = null; + +const NodeElements = new Map(); // @TODO: Currently only a few nodes are added, probably also add others + +export function addNodeElement(name, nodeElement) { + if (NodeElements.has(name)) { + console.warn(`Redefinition of node element ${name}`); + return; + } + + if (typeof nodeElement !== 'function') throw new Error(`Node element ${name} is not a function`); + + NodeElements.set(name, nodeElement); +} + +const parseSwizzle = props => props.replace(/r|s/g, 'x').replace(/g|t/g, 'y').replace(/b|p/g, 'z').replace(/a|q/g, 'w'); + +const shaderNodeHandler = { + setup(NodeClosure, params) { + const inputs = params.shift(); + + return NodeClosure(nodeObjects(inputs), ...params); + }, + + get(node, prop, nodeObj) { + if (typeof prop === 'string' && node[prop] === undefined) { + if (node.isStackNode !== true && prop === 'assign') { + return (...params) => { + currentStack.assign(nodeObj, ...params); + + return nodeObj; + }; + } else if (NodeElements.has(prop)) { + const nodeElement = NodeElements.get(prop); + + return node.isStackNode + ? (...params) => nodeObj.add(nodeElement(...params)) + : (...params) => nodeElement(nodeObj, ...params); + } else if (prop === 'self') { + return node; + } else if (prop.endsWith('Assign') && NodeElements.has(prop.slice(0, prop.length - 'Assign'.length))) { + const nodeElement = NodeElements.get(prop.slice(0, prop.length - 'Assign'.length)); + + return node.isStackNode + ? (...params) => nodeObj.assign(params[0], nodeElement(...params)) + : (...params) => nodeObj.assign(nodeElement(nodeObj, ...params)); + } else if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true) { + // accessing properties ( swizzle ) + + prop = parseSwizzle(prop); + + return nodeObject(new SplitNode(nodeObj, prop)); + } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { + // set properties ( swizzle ) + + prop = parseSwizzle(prop.slice(3).toLowerCase()); + + // sort to xyzw sequence + + prop = prop.split('').sort().join(''); + + return value => nodeObject(new SetNode(node, prop, value)); + } else if (prop === 'width' || prop === 'height' || prop === 'depth') { + // accessing property + + if (prop === 'width') prop = 'x'; + else if (prop === 'height') prop = 'y'; + else if (prop === 'depth') prop = 'z'; + + return nodeObject(new SplitNode(node, prop)); + } else if (/^\d+$/.test(prop) === true) { + // accessing array + + return nodeObject(new ArrayElementNode(nodeObj, new ConstNode(Number(prop), 'uint'))); + } + } + + return Reflect.get(node, prop, nodeObj); + }, + + set(node, prop, value, nodeObj) { + if (typeof prop === 'string' && node[prop] === undefined) { + // setting properties + + if ( + /^[xyzwrgbastpq]{1,4}$/.test(prop) === true || + prop === 'width' || + prop === 'height' || + prop === 'depth' || + /^\d+$/.test(prop) === true + ) { + nodeObj[prop].assign(value); + + return true; + } + } + + return Reflect.set(node, prop, value, nodeObj); + }, +}; + +const nodeObjectsCacheMap = new WeakMap(); +const nodeBuilderFunctionsCacheMap = new WeakMap(); + +const ShaderNodeObject = function (obj, altType = null) { + const type = getValueType(obj); + + if (type === 'node') { + let nodeObject = nodeObjectsCacheMap.get(obj); + + if (nodeObject === undefined) { + nodeObject = new Proxy(obj, shaderNodeHandler); + + nodeObjectsCacheMap.set(obj, nodeObject); + nodeObjectsCacheMap.set(nodeObject, nodeObject); + } + + return nodeObject; + } else if ( + (altType === null && (type === 'float' || type === 'boolean')) || + (type && type !== 'shader' && type !== 'string') + ) { + return nodeObject(getConstNode(obj, altType)); + } else if (type === 'shader') { + return tslFn(obj); + } + + return obj; +}; + +const ShaderNodeObjects = function (objects, altType = null) { + for (const name in objects) { + objects[name] = nodeObject(objects[name], altType); + } + + return objects; +}; + +const ShaderNodeArray = function (array, altType = null) { + const len = array.length; + + for (let i = 0; i < len; i++) { + array[i] = nodeObject(array[i], altType); + } + + return array; +}; + +const ShaderNodeProxy = function (NodeClass, scope = null, factor = null, settings = null) { + const assignNode = node => nodeObject(settings !== null ? Object.assign(node, settings) : node); + + if (scope === null) { + return (...params) => { + return assignNode(new NodeClass(...nodeArray(params))); + }; + } else if (factor !== null) { + factor = nodeObject(factor); + + return (...params) => { + return assignNode(new NodeClass(scope, ...nodeArray(params), factor)); + }; + } else { + return (...params) => { + return assignNode(new NodeClass(scope, ...nodeArray(params))); + }; + } +}; + +const ShaderNodeImmutable = function (NodeClass, ...params) { + return nodeObject(new NodeClass(...nodeArray(params))); +}; + +class ShaderCallNodeInternal extends Node { + constructor(shaderNode, inputNodes) { + super(); + + this.shaderNode = shaderNode; + this.inputNodes = inputNodes; + } + + getNodeType(builder) { + const properties = builder.getNodeProperties(this); + + if (properties.outputNode === null) { + properties.outputNode = this.setupOutput(builder); + } + + return properties.outputNode.getNodeType(builder); + } + + call(builder) { + const { shaderNode, inputNodes } = this; + + if (shaderNode.layout) { + let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get(builder.constructor); + + if (functionNodesCacheMap === undefined) { + functionNodesCacheMap = new WeakMap(); + + nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); + } + + let functionNode = functionNodesCacheMap.get(shaderNode); + + if (functionNode === undefined) { + functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); + + functionNodesCacheMap.set(shaderNode, functionNode); + } + + if (builder.currentFunctionNode !== null) { + builder.currentFunctionNode.includes.push(functionNode); + } + + return nodeObject(functionNode.call(inputNodes)); + } + + const jsFunc = shaderNode.jsFunc; + const outputNode = + inputNodes !== null ? jsFunc(inputNodes, builder.stack, builder) : jsFunc(builder.stack, builder); + + return nodeObject(outputNode); + } + + setup(builder) { + const { outputNode } = builder.getNodeProperties(this); + + return outputNode || this.setupOutput(builder); + } + + setupOutput(builder) { + builder.addStack(); + + builder.stack.outputNode = this.call(builder); + + return builder.removeStack(); + } + + generate(builder, output) { + const { outputNode } = builder.getNodeProperties(this); + + if (outputNode === null) { + // TSL: It's recommended to use `tslFn` in setup() pass. + + return this.call(builder).build(builder, output); + } + + return super.generate(builder, output); + } +} + +class ShaderNodeInternal extends Node { + constructor(jsFunc) { + super(); + + this.jsFunc = jsFunc; + this.layout = null; + + this.global = true; + } + + get isArrayInput() { + return /^\((\s+)?\[/.test(this.jsFunc.toString()); + } + + setLayout(layout) { + this.layout = layout; + + return this; + } + + call(inputs = null) { + nodeObjects(inputs); + + return nodeObject(new ShaderCallNodeInternal(this, inputs)); + } + + setup() { + return this.call(); + } +} + +const bools = [false, true]; +const uints = [0, 1, 2, 3]; +const ints = [-1, -2]; +const floats = [ + 0.5, + 1.5, + 1 / 3, + 1e-6, + 1e6, + Math.PI, + Math.PI * 2, + 1 / Math.PI, + 2 / Math.PI, + 1 / (Math.PI * 2), + Math.PI / 2, +]; + +const boolsCacheMap = new Map(); +for (const bool of bools) boolsCacheMap.set(bool, new ConstNode(bool)); + +const uintsCacheMap = new Map(); +for (const uint of uints) uintsCacheMap.set(uint, new ConstNode(uint, 'uint')); + +const intsCacheMap = new Map([...uintsCacheMap].map(el => new ConstNode(el.value, 'int'))); +for (const int of ints) intsCacheMap.set(int, new ConstNode(int, 'int')); + +const floatsCacheMap = new Map([...intsCacheMap].map(el => new ConstNode(el.value))); +for (const float of floats) floatsCacheMap.set(float, new ConstNode(float)); +for (const float of floats) floatsCacheMap.set(-float, new ConstNode(-float)); + +const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; + +const constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); + +const getConstNode = (value, type) => { + if (constNodesCacheMap.has(value)) { + return constNodesCacheMap.get(value); + } else if (value.isNode === true) { + return value; + } else { + return new ConstNode(value, type); + } +}; + +const safeGetNodeType = node => { + try { + return node.getNodeType(); + } catch (_) { + return undefined; + } +}; + +const ConvertType = function (type, cacheMap = null) { + return (...params) => { + if ( + params.length === 0 || + (!['bool', 'float', 'int', 'uint'].includes(type) && params.every(param => typeof param !== 'object')) + ) { + params = [getValueFromType(type, ...params)]; + } + + if (params.length === 1 && cacheMap !== null && cacheMap.has(params[0])) { + return nodeObject(cacheMap.get(params[0])); + } + + if (params.length === 1) { + const node = getConstNode(params[0], type); + if (safeGetNodeType(node) === type) return nodeObject(node); + return nodeObject(new ConvertNode(node, type)); + } + + const nodes = params.map(param => getConstNode(param)); + return nodeObject(new JoinNode(nodes, type)); + }; +}; + +// exports + +export const defined = value => value && value.value; + +// utils + +export const getConstNodeType = value => + value !== undefined && value !== null + ? value.nodeType || value.convertTo || (typeof value === 'string' ? value : null) + : null; + +// shader node base + +export function ShaderNode(jsFunc) { + return new Proxy(new ShaderNodeInternal(jsFunc), shaderNodeHandler); +} + +export const nodeObject = (val, altType = null) => /* new */ ShaderNodeObject(val, altType); +export const nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); +export const nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); +export const nodeProxy = (...params) => new ShaderNodeProxy(...params); +export const nodeImmutable = (...params) => new ShaderNodeImmutable(...params); + +export const tslFn = jsFunc => { + const shaderNode = new ShaderNode(jsFunc); + + const fn = (...params) => { + let inputs; + + nodeObjects(params); + + if (params[0] && params[0].isNode) { + inputs = [...params]; + } else { + inputs = params[0]; + } + + return shaderNode.call(inputs); + }; + + fn.shaderNode = shaderNode; + fn.setLayout = layout => { + shaderNode.setLayout(layout); + + return fn; + }; + + return fn; +}; + +addNodeClass('ShaderNode', ShaderNode); + +// + +addNodeElement('toGlobal', node => { + node.global = true; + + return node; +}); + +// + +export const setCurrentStack = stack => { + if (currentStack === stack) { + //throw new Error( 'Stack already defined.' ); + } + + currentStack = stack; +}; + +export const getCurrentStack = () => currentStack; + +export const If = (...params) => currentStack.if(...params); + +export function append(node) { + if (currentStack) currentStack.add(node); + + return node; +} + +addNodeElement('append', append); + +// types +// @TODO: Maybe export from ConstNode.js? + +export const color = new ConvertType('color'); + +export const float = new ConvertType('float', cacheMaps.float); +export const int = new ConvertType('int', cacheMaps.ints); +export const uint = new ConvertType('uint', cacheMaps.uint); +export const bool = new ConvertType('bool', cacheMaps.bool); + +export const vec2 = new ConvertType('vec2'); +export const ivec2 = new ConvertType('ivec2'); +export const uvec2 = new ConvertType('uvec2'); +export const bvec2 = new ConvertType('bvec2'); + +export const vec3 = new ConvertType('vec3'); +export const ivec3 = new ConvertType('ivec3'); +export const uvec3 = new ConvertType('uvec3'); +export const bvec3 = new ConvertType('bvec3'); + +export const vec4 = new ConvertType('vec4'); +export const ivec4 = new ConvertType('ivec4'); +export const uvec4 = new ConvertType('uvec4'); +export const bvec4 = new ConvertType('bvec4'); + +export const mat2 = new ConvertType('mat2'); +export const imat2 = new ConvertType('imat2'); +export const umat2 = new ConvertType('umat2'); +export const bmat2 = new ConvertType('bmat2'); + +export const mat3 = new ConvertType('mat3'); +export const imat3 = new ConvertType('imat3'); +export const umat3 = new ConvertType('umat3'); +export const bmat3 = new ConvertType('bmat3'); + +export const mat4 = new ConvertType('mat4'); +export const imat4 = new ConvertType('imat4'); +export const umat4 = new ConvertType('umat4'); +export const bmat4 = new ConvertType('bmat4'); + +export const string = (value = '') => nodeObject(new ConstNode(value, 'string')); +export const arrayBuffer = value => nodeObject(new ConstNode(value, 'ArrayBuffer')); + +addNodeElement('toColor', color); +addNodeElement('toFloat', float); +addNodeElement('toInt', int); +addNodeElement('toUint', uint); +addNodeElement('toBool', bool); +addNodeElement('toVec2', vec2); +addNodeElement('toIvec2', ivec2); +addNodeElement('toUvec2', uvec2); +addNodeElement('toBvec2', bvec2); +addNodeElement('toVec3', vec3); +addNodeElement('toIvec3', ivec3); +addNodeElement('toUvec3', uvec3); +addNodeElement('toBvec3', bvec3); +addNodeElement('toVec4', vec4); +addNodeElement('toIvec4', ivec4); +addNodeElement('toUvec4', uvec4); +addNodeElement('toBvec4', bvec4); +addNodeElement('toMat2', mat2); +addNodeElement('toImat2', imat2); +addNodeElement('toUmat2', umat2); +addNodeElement('toBmat2', bmat2); +addNodeElement('toMat3', mat3); +addNodeElement('toImat3', imat3); +addNodeElement('toUmat3', umat3); +addNodeElement('toBmat3', bmat3); +addNodeElement('toMat4', mat4); +addNodeElement('toImat4', imat4); +addNodeElement('toUmat4', umat4); +addNodeElement('toBmat4', bmat4); + +// basic nodes +// HACK - we cannot export them from the corresponding files because of the cyclic dependency +export const element = nodeProxy(ArrayElementNode); +export const convert = (node, types) => nodeObject(new ConvertNode(nodeObject(node), types)); +export const split = (node, channels) => nodeObject(new SplitNode(nodeObject(node), channels)); + +addNodeElement('element', element); +addNodeElement('convert', convert); diff --git a/examples-jsm/examples/renderers/common/Animation.ts b/examples-jsm/examples/renderers/common/Animation.ts new file mode 100644 index 000000000..0b00319a1 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Animation.ts @@ -0,0 +1,38 @@ +class Animation { + constructor(nodes, info) { + this.nodes = nodes; + this.info = info; + + this.animationLoop = null; + this.requestId = null; + + this._init(); + } + + _init() { + const update = (time, frame) => { + this.requestId = self.requestAnimationFrame(update); + + if (this.info.autoReset === true) this.info.reset(); + + this.nodes.nodeFrame.update(); + + this.info.frame = this.nodes.nodeFrame.frameId; + + if (this.animationLoop !== null) this.animationLoop(time, frame); + }; + + update(); + } + + dispose() { + self.cancelAnimationFrame(this.requestId); + this.requestId = null; + } + + setAnimationLoop(callback) { + this.animationLoop = callback; + } +} + +export default Animation; diff --git a/examples-jsm/examples/renderers/common/Attributes.ts b/examples-jsm/examples/renderers/common/Attributes.ts new file mode 100644 index 000000000..295535406 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Attributes.ts @@ -0,0 +1,53 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; +import { DynamicDrawUsage } from 'three'; + +class Attributes extends DataMap { + constructor(backend) { + super(); + + this.backend = backend; + } + + delete(attribute) { + const attributeData = super.delete(attribute); + + if (attributeData !== undefined) { + this.backend.destroyAttribute(attribute); + } + + return attributeData; + } + + update(attribute, type) { + const data = this.get(attribute); + + if (data.version === undefined) { + if (type === AttributeType.VERTEX) { + this.backend.createAttribute(attribute); + } else if (type === AttributeType.INDEX) { + this.backend.createIndexAttribute(attribute); + } else if (type === AttributeType.STORAGE) { + this.backend.createStorageAttribute(attribute); + } + + data.version = this._getBufferAttribute(attribute).version; + } else { + const bufferAttribute = this._getBufferAttribute(attribute); + + if (data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage) { + this.backend.updateAttribute(attribute); + + data.version = bufferAttribute.version; + } + } + } + + _getBufferAttribute(attribute) { + if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; + + return attribute; + } +} + +export default Attributes; diff --git a/examples-jsm/examples/renderers/common/Backend.ts b/examples-jsm/examples/renderers/common/Backend.ts new file mode 100644 index 000000000..efa5649d5 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Backend.ts @@ -0,0 +1,165 @@ +let vector2 = null; +let vector4 = null; +let color4 = null; + +import Color4 from './Color4.js'; +import { Vector2, Vector4, REVISION, createCanvasElement } from 'three'; + +class Backend { + constructor(parameters = {}) { + this.parameters = Object.assign({}, parameters); + this.data = new WeakMap(); + this.renderer = null; + this.domElement = null; + } + + async init(renderer) { + this.renderer = renderer; + } + + // render context + + begin(renderContext) {} + + finish(renderContext) {} + + // render object + + draw(renderObject, info) {} + + // program + + createProgram(program) {} + + destroyProgram(program) {} + + // bindings + + createBindings(renderObject) {} + + // pipeline + + createRenderPipeline(renderObject) {} + + createComputePipeline(computeNode, pipeline) {} + + destroyPipeline(pipeline) {} + + // cache key + + needsRenderUpdate(renderObject) {} // return Boolean ( fast test ) + + getRenderCacheKey(renderObject) {} // return String + + // node builder + + createNodeBuilder(renderObject) {} // return NodeBuilder (ADD IT) + + // textures + + createSampler(texture) {} + + createDefaultTexture(texture) {} + + createTexture(texture) {} + + copyTextureToBuffer(texture, x, y, width, height) {} + + // attributes + + createAttribute(attribute) {} + + createIndexAttribute(attribute) {} + + updateAttribute(attribute) {} + + destroyAttribute(attribute) {} + + // canvas + + getContext() {} + + updateSize() {} + + // utils + + resolveTimestampAsync(renderContext, type) {} + + hasFeatureAsync(name) {} // return Boolean + + hasFeature(name) {} // return Boolean + + getInstanceCount(renderObject) { + const { object, geometry } = renderObject; + + return geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; + } + + getDrawingBufferSize() { + vector2 = vector2 || new Vector2(); + + return this.renderer.getDrawingBufferSize(vector2); + } + + getScissor() { + vector4 = vector4 || new Vector4(); + + return this.renderer.getScissor(vector4); + } + + setScissorTest(boolean) {} + + getClearColor() { + const renderer = this.renderer; + + color4 = color4 || new Color4(); + + renderer.getClearColor(color4); + + color4.getRGB(color4, this.renderer.currentColorSpace); + + return color4; + } + + getDomElement() { + let domElement = this.domElement; + + if (domElement === null) { + domElement = this.parameters.canvas !== undefined ? this.parameters.canvas : createCanvasElement(); + + // OffscreenCanvas does not have setAttribute, see #22811 + if ('setAttribute' in domElement) domElement.setAttribute('data-engine', `three.js r${REVISION} webgpu`); + + this.domElement = domElement; + } + + return domElement; + } + + // resource properties + + set(object, value) { + this.data.set(object, value); + } + + get(object) { + let map = this.data.get(object); + + if (map === undefined) { + map = {}; + this.data.set(object, map); + } + + return map; + } + + has(object) { + return this.data.has(object); + } + + delete(object) { + this.data.delete(object); + } +} + +export default Backend; diff --git a/examples-jsm/examples/renderers/common/Background.ts b/examples-jsm/examples/renderers/common/Background.ts new file mode 100644 index 000000000..b7902dd40 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Background.ts @@ -0,0 +1,118 @@ +import DataMap from './DataMap.js'; +import Color4 from './Color4.js'; +import { Mesh, SphereGeometry, BackSide, LinearSRGBColorSpace } from 'three'; +import { + vec4, + context, + normalWorld, + backgroundBlurriness, + backgroundIntensity, + NodeMaterial, + modelViewProjection, +} from '../../nodes/Nodes.js'; + +const _clearColor = new Color4(); + +class Background extends DataMap { + constructor(renderer, nodes) { + super(); + + this.renderer = renderer; + this.nodes = nodes; + } + + update(scene, renderList, renderContext) { + const renderer = this.renderer; + const background = this.nodes.getBackgroundNode(scene) || scene.background; + + let forceClear = false; + + if (background === null) { + // no background settings, use clear color configuration from the renderer + + renderer._clearColor.getRGB(_clearColor, LinearSRGBColorSpace); + _clearColor.a = renderer._clearColor.a; + } else if (background.isColor === true) { + // background is an opaque color + + background.getRGB(_clearColor, LinearSRGBColorSpace); + _clearColor.a = 1; + + forceClear = true; + } else if (background.isNode === true) { + const sceneData = this.get(scene); + const backgroundNode = background; + + _clearColor.copy(renderer._clearColor); + + let backgroundMesh = sceneData.backgroundMesh; + + if (backgroundMesh === undefined) { + const backgroundMeshNode = context(vec4(backgroundNode).mul(backgroundIntensity), { + // @TODO: Add Texture2D support using node context + getUV: () => normalWorld, + getTextureLevel: () => backgroundBlurriness, + }); + + let viewProj = modelViewProjection(); + viewProj = viewProj.setZ(viewProj.w); + + const nodeMaterial = new NodeMaterial(); + nodeMaterial.side = BackSide; + nodeMaterial.depthTest = false; + nodeMaterial.depthWrite = false; + nodeMaterial.fog = false; + nodeMaterial.vertexNode = viewProj; + nodeMaterial.fragmentNode = backgroundMeshNode; + + sceneData.backgroundMeshNode = backgroundMeshNode; + sceneData.backgroundMesh = backgroundMesh = new Mesh(new SphereGeometry(1, 32, 32), nodeMaterial); + backgroundMesh.frustumCulled = false; + + backgroundMesh.onBeforeRender = function (renderer, scene, camera) { + this.matrixWorld.copyPosition(camera.matrixWorld); + }; + } + + const backgroundCacheKey = backgroundNode.getCacheKey(); + + if (sceneData.backgroundCacheKey !== backgroundCacheKey) { + sceneData.backgroundMeshNode.node = vec4(backgroundNode).mul(backgroundIntensity); + + backgroundMesh.material.needsUpdate = true; + + sceneData.backgroundCacheKey = backgroundCacheKey; + } + + renderList.unshift(backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null); + } else { + console.error('THREE.Renderer: Unsupported background configuration.', background); + } + + // + + if (renderer.autoClear === true || forceClear === true) { + _clearColor.multiplyScalar(_clearColor.a); + + const clearColorValue = renderContext.clearColorValue; + + clearColorValue.r = _clearColor.r; + clearColorValue.g = _clearColor.g; + clearColorValue.b = _clearColor.b; + clearColorValue.a = _clearColor.a; + + renderContext.depthClearValue = renderer._clearDepth; + renderContext.stencilClearValue = renderer._clearStencil; + + renderContext.clearColor = renderer.autoClearColor === true; + renderContext.clearDepth = renderer.autoClearDepth === true; + renderContext.clearStencil = renderer.autoClearStencil === true; + } else { + renderContext.clearColor = false; + renderContext.clearDepth = false; + renderContext.clearStencil = false; + } + } +} + +export default Background; diff --git a/examples-jsm/examples/renderers/common/BindGroup.ts b/examples-jsm/examples/renderers/common/BindGroup.ts new file mode 100644 index 000000000..6b7ffa217 --- /dev/null +++ b/examples-jsm/examples/renderers/common/BindGroup.ts @@ -0,0 +1,12 @@ +let _id = 0; + +class BindGroup { + constructor(name = '', bindings = []) { + this.name = name; + this.bindings = bindings; + + this.id = _id++; + } +} + +export default BindGroup; diff --git a/examples-jsm/examples/renderers/common/Binding.ts b/examples-jsm/examples/renderers/common/Binding.ts new file mode 100644 index 000000000..a12f3563b --- /dev/null +++ b/examples-jsm/examples/renderers/common/Binding.ts @@ -0,0 +1,17 @@ +class Binding { + constructor(name = '') { + this.name = name; + + this.visibility = 0; + } + + setVisibility(visibility) { + this.visibility |= visibility; + } + + clone() { + return Object.assign(new this.constructor(), this); + } +} + +export default Binding; diff --git a/examples-jsm/examples/renderers/common/Bindings.ts b/examples-jsm/examples/renderers/common/Bindings.ts new file mode 100644 index 000000000..51aa31f0d --- /dev/null +++ b/examples-jsm/examples/renderers/common/Bindings.ts @@ -0,0 +1,161 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; + +class Bindings extends DataMap { + constructor(backend, nodes, textures, attributes, pipelines, info) { + super(); + + this.backend = backend; + this.textures = textures; + this.pipelines = pipelines; + this.attributes = attributes; + this.nodes = nodes; + this.info = info; + + this.pipelines.bindings = this; // assign bindings to pipelines + } + + getForRender(renderObject) { + const bindings = renderObject.getBindings(); + + for (const bindGroup of bindings) { + const groupData = this.get(bindGroup); + + if (groupData.bindGroup === undefined) { + // each object defines an array of bindings (ubos, textures, samplers etc.) + + this._init(bindGroup); + + this.backend.createBindings(bindGroup, bindings); + + groupData.bindGroup = bindGroup; + } + } + + return bindings; + } + + getForCompute(computeNode) { + const bindings = this.nodes.getForCompute(computeNode).bindings; + + for (const bindGroup of bindings) { + const groupData = this.get(bindGroup); + + if (groupData.bindGroup === undefined) { + this._init(bindGroup); + + this.backend.createBindings(bindGroup, bindings); + + groupData.bindGroup = bindGroup; + } + } + + return bindings; + } + + updateForCompute(computeNode) { + this._updateBindings(computeNode, this.getForCompute(computeNode)); + } + + updateForRender(renderObject) { + this._updateBindings(renderObject, this.getForRender(renderObject)); + } + + _updateBindings(object, bindings) { + for (const bindGroup of bindings) { + this._update(object, bindGroup, bindings); + } + } + + _init(bindGroup) { + for (const binding of bindGroup.bindings) { + if (binding.isSampledTexture) { + this.textures.updateTexture(binding.texture); + } else if (binding.isStorageBuffer) { + const attribute = binding.attribute; + + this.attributes.update(attribute, AttributeType.STORAGE); + } + } + } + + _update(object, bindGroup, bindings) { + const { backend } = this; + + let needsBindingsUpdate = false; + + // iterate over all bindings and check if buffer updates or a new binding group is required + + for (const binding of bindGroup.bindings) { + if (binding.isNodeUniformsGroup) { + const updated = this.nodes.updateGroup(binding); + + if (!updated) continue; + } + + if (binding.isUniformBuffer) { + const updated = binding.update(); + + if (updated) { + backend.updateBinding(binding); + } + } else if (binding.isSampler) { + binding.update(); + } else if (binding.isSampledTexture) { + const texture = binding.texture; + + if (binding.needsBindingsUpdate) needsBindingsUpdate = true; + + const updated = binding.update(); + + if (updated) { + this.textures.updateTexture(binding.texture); + } + + const textureData = backend.get(binding.texture); + + if ( + backend.isWebGPUBackend === true && + textureData.texture === undefined && + textureData.externalTexture === undefined + ) { + // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend + console.error( + 'Bindings._update: binding should be available:', + binding, + updated, + binding.texture, + binding.textureNode.value, + ); + + this.textures.updateTexture(binding.texture); + needsBindingsUpdate = true; + } + + if (texture.isStorageTexture === true) { + const textureData = this.get(texture); + + if (binding.store === true) { + textureData.needsMipmap = true; + } else if ( + texture.generateMipmaps === true && + this.textures.needsMipmaps(texture) && + textureData.needsMipmap === true + ) { + this.backend.generateMipmaps(texture); + + textureData.needsMipmap = false; + } + } + } + } + + if (needsBindingsUpdate === true) { + const pipeline = this.pipelines.getForRender(object); + + this.backend.updateBindings(bindGroup, bindings, pipeline); + } + } +} + +export default Bindings; diff --git a/examples-jsm/examples/renderers/common/Buffer.ts b/examples-jsm/examples/renderers/common/Buffer.ts new file mode 100644 index 000000000..17013c6dc --- /dev/null +++ b/examples-jsm/examples/renderers/common/Buffer.ts @@ -0,0 +1,28 @@ +import Binding from './Binding.js'; +import { getFloatLength } from './BufferUtils.js'; + +class Buffer extends Binding { + constructor(name, buffer = null) { + super(name); + + this.isBuffer = true; + + this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT; + + this._buffer = buffer; + } + + get byteLength() { + return getFloatLength(this._buffer.byteLength); + } + + get buffer() { + return this._buffer; + } + + update() { + return true; + } +} + +export default Buffer; diff --git a/examples-jsm/examples/renderers/common/BufferUtils.ts b/examples-jsm/examples/renderers/common/BufferUtils.ts new file mode 100644 index 000000000..99ddcb48b --- /dev/null +++ b/examples-jsm/examples/renderers/common/BufferUtils.ts @@ -0,0 +1,23 @@ +import { GPU_CHUNK_BYTES } from './Constants.js'; + +function getFloatLength(floatLength) { + // ensure chunk size alignment (STD140 layout) + + return floatLength + ((GPU_CHUNK_BYTES - (floatLength % GPU_CHUNK_BYTES)) % GPU_CHUNK_BYTES); +} + +function getVectorLength(count, vectorLength = 4) { + const strideLength = getStrideLength(vectorLength); + + const floatLength = strideLength * count; + + return getFloatLength(floatLength); +} + +function getStrideLength(vectorLength) { + const strideLength = 4; + + return vectorLength + ((strideLength - (vectorLength % strideLength)) % strideLength); +} + +export { getFloatLength, getVectorLength, getStrideLength }; diff --git a/examples-jsm/examples/renderers/common/ChainMap.ts b/examples-jsm/examples/renderers/common/ChainMap.ts new file mode 100644 index 000000000..b17e7080f --- /dev/null +++ b/examples-jsm/examples/renderers/common/ChainMap.ts @@ -0,0 +1,43 @@ +export default class ChainMap { + constructor() { + this.weakMap = new WeakMap(); + } + + get(keys) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + map = map.get(keys[i]); + + if (map === undefined) return undefined; + } + + return map.get(keys[keys.length - 1]); + } + + set(keys, value) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + + if (map.has(key) === false) map.set(key, new WeakMap()); + + map = map.get(key); + } + + return map.set(keys[keys.length - 1], value); + } + + delete(keys) { + let map = this.weakMap; + + for (let i = 0; i < keys.length; i++) { + map = map.get(keys[i]); + + if (map === undefined) return false; + } + + return map.delete(keys[keys.length - 1]); + } +} diff --git a/examples-jsm/examples/renderers/common/ClippingContext.ts b/examples-jsm/examples/renderers/common/ClippingContext.ts new file mode 100644 index 000000000..312e0b779 --- /dev/null +++ b/examples-jsm/examples/renderers/common/ClippingContext.ts @@ -0,0 +1,128 @@ +import { Matrix3, Plane, Vector4 } from 'three'; + +const _plane = new Plane(); + +let _clippingContextVersion = 0; + +class ClippingContext { + constructor() { + this.version = ++_clippingContextVersion; + + this.globalClippingCount = 0; + + this.localClippingCount = 0; + this.localClippingEnabled = false; + this.localClipIntersection = false; + + this.planes = []; + + this.parentVersion = 0; + this.viewNormalMatrix = new Matrix3(); + } + + projectPlanes(source, offset) { + const l = source.length; + const planes = this.planes; + + for (let i = 0; i < l; i++) { + _plane.copy(source[i]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix); + + const v = planes[offset + i]; + const normal = _plane.normal; + + v.x = -normal.x; + v.y = -normal.y; + v.z = -normal.z; + v.w = _plane.constant; + } + } + + updateGlobal(renderer, camera) { + const rendererClippingPlanes = renderer.clippingPlanes; + this.viewMatrix = camera.matrixWorldInverse; + + this.viewNormalMatrix.getNormalMatrix(this.viewMatrix); + + let update = false; + + if (Array.isArray(rendererClippingPlanes) && rendererClippingPlanes.length !== 0) { + const l = rendererClippingPlanes.length; + + if (l !== this.globalClippingCount) { + const planes = []; + + for (let i = 0; i < l; i++) { + planes.push(new Vector4()); + } + + this.globalClippingCount = l; + this.planes = planes; + + update = true; + } + + this.projectPlanes(rendererClippingPlanes, 0); + } else if (this.globalClippingCount !== 0) { + this.globalClippingCount = 0; + this.planes = []; + update = true; + } + + if (renderer.localClippingEnabled !== this.localClippingEnabled) { + this.localClippingEnabled = renderer.localClippingEnabled; + update = true; + } + + if (update) this.version = _clippingContextVersion++; + } + + update(parent, material) { + let update = false; + + if (this !== parent && parent.version !== this.parentVersion) { + this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; + this.localClippingEnabled = parent.localClippingEnabled; + this.planes = Array.from(parent.planes); + this.parentVersion = parent.version; + this.viewMatrix = parent.viewMatrix; + this.viewNormalMatrix = parent.viewNormalMatrix; + + update = true; + } + + if (this.localClippingEnabled) { + const localClippingPlanes = material.clippingPlanes; + + if (Array.isArray(localClippingPlanes) && localClippingPlanes.length !== 0) { + const l = localClippingPlanes.length; + const planes = this.planes; + const offset = this.globalClippingCount; + + if (update || l !== this.localClippingCount) { + planes.length = offset + l; + + for (let i = 0; i < l; i++) { + planes[offset + i] = new Vector4(); + } + + this.localClippingCount = l; + update = true; + } + + this.projectPlanes(localClippingPlanes, offset); + } else if (this.localClippingCount !== 0) { + this.localClippingCount = 0; + update = true; + } + + if (this.localClipIntersection !== material.clipIntersection) { + this.localClipIntersection = material.clipIntersection; + update = true; + } + } + + if (update) this.version = _clippingContextVersion++; + } +} + +export default ClippingContext; diff --git a/examples-jsm/examples/renderers/common/Color4.ts b/examples-jsm/examples/renderers/common/Color4.ts new file mode 100644 index 000000000..c681cc908 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Color4.ts @@ -0,0 +1,27 @@ +import { Color } from 'three'; + +class Color4 extends Color { + constructor(r, g, b, a = 1) { + super(r, g, b); + + this.a = a; + } + + set(r, g, b, a = 1) { + this.a = a; + + return super.set(r, g, b); + } + + copy(color) { + if (color.a !== undefined) this.a = color.a; + + return super.copy(color); + } + + clone() { + return new this.constructor(this.r, this.g, this.b, this.a); + } +} + +export default Color4; diff --git a/examples-jsm/examples/renderers/common/ComputePipeline.ts b/examples-jsm/examples/renderers/common/ComputePipeline.ts new file mode 100644 index 000000000..0fd3ca531 --- /dev/null +++ b/examples-jsm/examples/renderers/common/ComputePipeline.ts @@ -0,0 +1,13 @@ +import Pipeline from './Pipeline.js'; + +class ComputePipeline extends Pipeline { + constructor(cacheKey, computeProgram) { + super(cacheKey); + + this.computeProgram = computeProgram; + + this.isComputePipeline = true; + } +} + +export default ComputePipeline; diff --git a/examples-jsm/examples/renderers/common/Constants.ts b/examples-jsm/examples/renderers/common/Constants.ts new file mode 100644 index 000000000..0d0c35a25 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Constants.ts @@ -0,0 +1,14 @@ +export const AttributeType = { + VERTEX: 1, + INDEX: 2, + STORAGE: 4, +}; + +// size of a chunk in bytes (STD140 layout) + +export const GPU_CHUNK_BYTES = 16; + +// @TODO: Move to src/constants.js + +export const BlendColorFactor = 211; +export const OneMinusBlendColorFactor = 212; diff --git a/examples-jsm/examples/renderers/common/CubeRenderTarget.ts b/examples-jsm/examples/renderers/common/CubeRenderTarget.ts new file mode 100644 index 000000000..74d04912b --- /dev/null +++ b/examples-jsm/examples/renderers/common/CubeRenderTarget.ts @@ -0,0 +1,69 @@ +import { + WebGLCubeRenderTarget, + Scene, + CubeCamera, + BoxGeometry, + Mesh, + BackSide, + NoBlending, + LinearFilter, + LinearMipmapLinearFilter, +} from 'three'; +import { equirectUV } from '../../nodes/utils/EquirectUVNode.js'; +import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js'; +import { positionWorldDirection } from '../../nodes/accessors/PositionNode.js'; +import { createNodeMaterialFromType } from '../../nodes/materials/NodeMaterial.js'; + +// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget + +class CubeRenderTarget extends WebGLCubeRenderTarget { + constructor(size = 1, options = {}) { + super(size, options); + + this.isCubeRenderTarget = true; + } + + fromEquirectangularTexture(renderer, texture) { + const currentMinFilter = texture.minFilter; + const currentGenerateMipmaps = texture.generateMipmaps; + + texture.generateMipmaps = true; + + this.texture.type = texture.type; + this.texture.colorSpace = texture.colorSpace; + + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + + const geometry = new BoxGeometry(5, 5, 5); + + const uvNode = equirectUV(positionWorldDirection); + + const material = createNodeMaterialFromType('MeshBasicNodeMaterial'); + material.colorNode = TSL_Texture(texture, uvNode, 0); + material.side = BackSide; + material.blending = NoBlending; + + const mesh = new Mesh(geometry, material); + + const scene = new Scene(); + scene.add(mesh); + + // Avoid blurred poles + if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; + + const camera = new CubeCamera(1, 10, this); + camera.update(renderer, scene); + + texture.minFilter = currentMinFilter; + texture.currentGenerateMipmaps = currentGenerateMipmaps; + + mesh.geometry.dispose(); + mesh.material.dispose(); + + return this; + } +} + +export default CubeRenderTarget; diff --git a/examples-jsm/examples/renderers/common/DataMap.ts b/examples-jsm/examples/renderers/common/DataMap.ts new file mode 100644 index 000000000..006bc2950 --- /dev/null +++ b/examples-jsm/examples/renderers/common/DataMap.ts @@ -0,0 +1,38 @@ +class DataMap { + constructor() { + this.data = new WeakMap(); + } + + get(object) { + let map = this.data.get(object); + + if (map === undefined) { + map = {}; + this.data.set(object, map); + } + + return map; + } + + delete(object) { + let map; + + if (this.data.has(object)) { + map = this.data.get(object); + + this.data.delete(object); + } + + return map; + } + + has(object) { + return this.data.has(object); + } + + dispose() { + this.data = new WeakMap(); + } +} + +export default DataMap; diff --git a/examples-jsm/examples/renderers/common/Geometries.ts b/examples-jsm/examples/renderers/common/Geometries.ts new file mode 100644 index 000000000..ca0cd225d --- /dev/null +++ b/examples-jsm/examples/renderers/common/Geometries.ts @@ -0,0 +1,182 @@ +import DataMap from './DataMap.js'; +import { AttributeType } from './Constants.js'; +import { Uint32BufferAttribute, Uint16BufferAttribute } from 'three'; + +function arrayNeedsUint32(array) { + // assumes larger values usually on last + + for (let i = array.length - 1; i >= 0; --i) { + if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 + } + + return false; +} + +function getWireframeVersion(geometry) { + return geometry.index !== null ? geometry.index.version : geometry.attributes.position.version; +} + +function getWireframeIndex(geometry) { + const indices = []; + + const geometryIndex = geometry.index; + const geometryPosition = geometry.attributes.position; + + if (geometryIndex !== null) { + const array = geometryIndex.array; + + for (let i = 0, l = array.length; i < l; i += 3) { + const a = array[i + 0]; + const b = array[i + 1]; + const c = array[i + 2]; + + indices.push(a, b, b, c, c, a); + } + } else { + const array = geometryPosition.array; + + for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { + const a = i + 0; + const b = i + 1; + const c = i + 2; + + indices.push(a, b, b, c, c, a); + } + } + + const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); + attribute.version = getWireframeVersion(geometry); + + return attribute; +} + +class Geometries extends DataMap { + constructor(attributes, info) { + super(); + + this.attributes = attributes; + this.info = info; + + this.wireframes = new WeakMap(); + + this.attributeCall = new WeakMap(); + } + + has(renderObject) { + const geometry = renderObject.geometry; + + return super.has(geometry) && this.get(geometry).initialized === true; + } + + updateForRender(renderObject) { + if (this.has(renderObject) === false) this.initGeometry(renderObject); + + this.updateAttributes(renderObject); + } + + initGeometry(renderObject) { + const geometry = renderObject.geometry; + const geometryData = this.get(geometry); + + geometryData.initialized = true; + + this.info.memory.geometries++; + + const onDispose = () => { + this.info.memory.geometries--; + + const index = geometry.index; + const geometryAttributes = renderObject.getAttributes(); + + if (index !== null) { + this.attributes.delete(index); + } + + for (const geometryAttribute of geometryAttributes) { + this.attributes.delete(geometryAttribute); + } + + const wireframeAttribute = this.wireframes.get(geometry); + + if (wireframeAttribute !== undefined) { + this.attributes.delete(wireframeAttribute); + } + + geometry.removeEventListener('dispose', onDispose); + }; + + geometry.addEventListener('dispose', onDispose); + } + + updateAttributes(renderObject) { + const attributes = renderObject.getAttributes(); + + for (const attribute of attributes) { + if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) { + this.updateAttribute(attribute, AttributeType.STORAGE); + } else { + this.updateAttribute(attribute, AttributeType.VERTEX); + } + } + + const index = this.getIndex(renderObject); + + if (index !== null) { + this.updateAttribute(index, AttributeType.INDEX); + } + } + + updateAttribute(attribute, type) { + const callId = this.info.render.calls; + + if (!attribute.isInterleavedBufferAttribute) { + if (this.attributeCall.get(attribute) !== callId) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute, callId); + } + } else { + if (this.attributeCall.get(attribute) === undefined) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute, callId); + } else if (this.attributeCall.get(attribute.data) !== callId) { + this.attributes.update(attribute, type); + + this.attributeCall.set(attribute.data, callId); + + this.attributeCall.set(attribute, callId); + } + } + } + + getIndex(renderObject) { + const { geometry, material } = renderObject; + + let index = geometry.index; + + if (material.wireframe === true) { + const wireframes = this.wireframes; + + let wireframeAttribute = wireframes.get(geometry); + + if (wireframeAttribute === undefined) { + wireframeAttribute = getWireframeIndex(geometry); + + wireframes.set(geometry, wireframeAttribute); + } else if (wireframeAttribute.version !== getWireframeVersion(geometry)) { + this.attributes.delete(wireframeAttribute); + + wireframeAttribute = getWireframeIndex(geometry); + + wireframes.set(geometry, wireframeAttribute); + } + + index = wireframeAttribute; + } + + return index; + } +} + +export default Geometries; diff --git a/examples-jsm/examples/renderers/common/Info.ts b/examples-jsm/examples/renderers/common/Info.ts new file mode 100644 index 000000000..4ede75de7 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Info.ts @@ -0,0 +1,95 @@ +class Info { + constructor() { + this.autoReset = true; + + this.frame = 0; + this.calls = 0; + + this.render = { + calls: 0, + frameCalls: 0, + drawCalls: 0, + triangles: 0, + points: 0, + lines: 0, + timestamp: 0, + previousFrameCalls: 0, + timestampCalls: 0, + }; + + this.compute = { + calls: 0, + frameCalls: 0, + timestamp: 0, + previousFrameCalls: 0, + timestampCalls: 0, + }; + + this.memory = { + geometries: 0, + textures: 0, + }; + } + + update(object, count, instanceCount) { + this.render.drawCalls++; + + if (object.isMesh || object.isSprite) { + this.render.triangles += instanceCount * (count / 3); + } else if (object.isPoints) { + this.render.points += instanceCount * count; + } else if (object.isLineSegments) { + this.render.lines += instanceCount * (count / 2); + } else if (object.isLine) { + this.render.lines += instanceCount * (count - 1); + } else { + console.error('THREE.WebGPUInfo: Unknown object type.'); + } + } + + updateTimestamp(type, time) { + if (this[type].timestampCalls === 0) { + this[type].timestamp = 0; + } + + this[type].timestamp += time; + + this[type].timestampCalls++; + + if (this[type].timestampCalls >= this[type].previousFrameCalls) { + this[type].timestampCalls = 0; + } + } + + reset() { + const previousRenderFrameCalls = this.render.frameCalls; + this.render.previousFrameCalls = previousRenderFrameCalls; + + const previousComputeFrameCalls = this.compute.frameCalls; + this.compute.previousFrameCalls = previousComputeFrameCalls; + + this.render.drawCalls = 0; + this.render.frameCalls = 0; + this.compute.frameCalls = 0; + + this.render.triangles = 0; + this.render.points = 0; + this.render.lines = 0; + } + + dispose() { + this.reset(); + + this.calls = 0; + + this.render.calls = 0; + this.compute.calls = 0; + + this.render.timestamp = 0; + this.compute.timestamp = 0; + this.memory.geometries = 0; + this.memory.textures = 0; + } +} + +export default Info; diff --git a/examples-jsm/examples/renderers/common/Pipeline.ts b/examples-jsm/examples/renderers/common/Pipeline.ts new file mode 100644 index 000000000..16017455a --- /dev/null +++ b/examples-jsm/examples/renderers/common/Pipeline.ts @@ -0,0 +1,9 @@ +class Pipeline { + constructor(cacheKey) { + this.cacheKey = cacheKey; + + this.usedTimes = 0; + } +} + +export default Pipeline; diff --git a/examples-jsm/examples/renderers/common/Pipelines.ts b/examples-jsm/examples/renderers/common/Pipelines.ts new file mode 100644 index 000000000..68c8f223c --- /dev/null +++ b/examples-jsm/examples/renderers/common/Pipelines.ts @@ -0,0 +1,270 @@ +import DataMap from './DataMap.js'; +import RenderPipeline from './RenderPipeline.js'; +import ComputePipeline from './ComputePipeline.js'; +import ProgrammableStage from './ProgrammableStage.js'; + +class Pipelines extends DataMap { + constructor(backend, nodes) { + super(); + + this.backend = backend; + this.nodes = nodes; + + this.bindings = null; // set by the bindings + + this.caches = new Map(); + this.programs = { + vertex: new Map(), + fragment: new Map(), + compute: new Map(), + }; + } + + getForCompute(computeNode, bindings) { + const { backend } = this; + + const data = this.get(computeNode); + + if (this._needsComputeUpdate(computeNode)) { + const previousPipeline = data.pipeline; + + if (previousPipeline) { + previousPipeline.usedTimes--; + previousPipeline.computeProgram.usedTimes--; + } + + // get shader + + const nodeBuilderState = this.nodes.getForCompute(computeNode); + + // programmable stage + + let stageCompute = this.programs.compute.get(nodeBuilderState.computeShader); + + if (stageCompute === undefined) { + if (previousPipeline && previousPipeline.computeProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.computeProgram); + + stageCompute = new ProgrammableStage( + nodeBuilderState.computeShader, + 'compute', + nodeBuilderState.transforms, + nodeBuilderState.nodeAttributes, + ); + this.programs.compute.set(nodeBuilderState.computeShader, stageCompute); + + backend.createProgram(stageCompute); + } + + // determine compute pipeline + + const cacheKey = this._getComputeCacheKey(computeNode, stageCompute); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); + + pipeline = this._getComputePipeline(computeNode, stageCompute, cacheKey, bindings); + } + + // keep track of all used times + + pipeline.usedTimes++; + stageCompute.usedTimes++; + + // + + data.version = computeNode.version; + data.pipeline = pipeline; + } + + return data.pipeline; + } + + getForRender(renderObject, promises = null) { + const { backend } = this; + + const data = this.get(renderObject); + + if (this._needsRenderUpdate(renderObject)) { + const previousPipeline = data.pipeline; + + if (previousPipeline) { + previousPipeline.usedTimes--; + previousPipeline.vertexProgram.usedTimes--; + previousPipeline.fragmentProgram.usedTimes--; + } + + // get shader + + const nodeBuilderState = renderObject.getNodeBuilderState(); + + // programmable stages + + let stageVertex = this.programs.vertex.get(nodeBuilderState.vertexShader); + + if (stageVertex === undefined) { + if (previousPipeline && previousPipeline.vertexProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.vertexProgram); + + stageVertex = new ProgrammableStage(nodeBuilderState.vertexShader, 'vertex'); + this.programs.vertex.set(nodeBuilderState.vertexShader, stageVertex); + + backend.createProgram(stageVertex); + } + + let stageFragment = this.programs.fragment.get(nodeBuilderState.fragmentShader); + + if (stageFragment === undefined) { + if (previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0) + this._releaseProgram(previousPipeline.fragmentProgram); + + stageFragment = new ProgrammableStage(nodeBuilderState.fragmentShader, 'fragment'); + this.programs.fragment.set(nodeBuilderState.fragmentShader, stageFragment); + + backend.createProgram(stageFragment); + } + + // determine render pipeline + + const cacheKey = this._getRenderCacheKey(renderObject, stageVertex, stageFragment); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); + + pipeline = this._getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises); + } else { + renderObject.pipeline = pipeline; + } + + // keep track of all used times + + pipeline.usedTimes++; + stageVertex.usedTimes++; + stageFragment.usedTimes++; + + // + + data.pipeline = pipeline; + } + + return data.pipeline; + } + + delete(object) { + const pipeline = this.get(object).pipeline; + + if (pipeline) { + // pipeline + + pipeline.usedTimes--; + + if (pipeline.usedTimes === 0) this._releasePipeline(pipeline); + + // programs + + if (pipeline.isComputePipeline) { + pipeline.computeProgram.usedTimes--; + + if (pipeline.computeProgram.usedTimes === 0) this._releaseProgram(pipeline.computeProgram); + } else { + pipeline.fragmentProgram.usedTimes--; + pipeline.vertexProgram.usedTimes--; + + if (pipeline.vertexProgram.usedTimes === 0) this._releaseProgram(pipeline.vertexProgram); + if (pipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(pipeline.fragmentProgram); + } + } + + return super.delete(object); + } + + dispose() { + super.dispose(); + + this.caches = new Map(); + this.programs = { + vertex: new Map(), + fragment: new Map(), + compute: new Map(), + }; + } + + updateForRender(renderObject) { + this.getForRender(renderObject); + } + + _getComputePipeline(computeNode, stageCompute, cacheKey, bindings) { + // check for existing pipeline + + cacheKey = cacheKey || this._getComputeCacheKey(computeNode, stageCompute); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + pipeline = new ComputePipeline(cacheKey, stageCompute); + + this.caches.set(cacheKey, pipeline); + + this.backend.createComputePipeline(pipeline, bindings); + } + + return pipeline; + } + + _getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises) { + // check for existing pipeline + + cacheKey = cacheKey || this._getRenderCacheKey(renderObject, stageVertex, stageFragment); + + let pipeline = this.caches.get(cacheKey); + + if (pipeline === undefined) { + pipeline = new RenderPipeline(cacheKey, stageVertex, stageFragment); + + this.caches.set(cacheKey, pipeline); + + renderObject.pipeline = pipeline; + + this.backend.createRenderPipeline(renderObject, promises); + } + + return pipeline; + } + + _getComputeCacheKey(computeNode, stageCompute) { + return computeNode.id + ',' + stageCompute.id; + } + + _getRenderCacheKey(renderObject, stageVertex, stageFragment) { + return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey(renderObject); + } + + _releasePipeline(pipeline) { + this.caches.delete(pipeline.cacheKey); + } + + _releaseProgram(program) { + const code = program.code; + const stage = program.stage; + + this.programs[stage].delete(code); + } + + _needsComputeUpdate(computeNode) { + const data = this.get(computeNode); + + return data.pipeline === undefined || data.version !== computeNode.version; + } + + _needsRenderUpdate(renderObject) { + const data = this.get(renderObject); + + return data.pipeline === undefined || this.backend.needsRenderUpdate(renderObject); + } +} + +export default Pipelines; diff --git a/examples-jsm/examples/renderers/common/ProgrammableStage.ts b/examples-jsm/examples/renderers/common/ProgrammableStage.ts new file mode 100644 index 000000000..a684e4443 --- /dev/null +++ b/examples-jsm/examples/renderers/common/ProgrammableStage.ts @@ -0,0 +1,16 @@ +let _id = 0; + +class ProgrammableStage { + constructor(code, type, transforms = null, attributes = null) { + this.id = _id++; + + this.code = code; + this.stage = type; + this.transforms = transforms; + this.attributes = attributes; + + this.usedTimes = 0; + } +} + +export default ProgrammableStage; diff --git a/examples-jsm/examples/renderers/common/RenderBundle.ts b/examples-jsm/examples/renderers/common/RenderBundle.ts new file mode 100644 index 000000000..e59e49378 --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderBundle.ts @@ -0,0 +1,12 @@ +class RenderBundle { + constructor(scene, camera) { + this.scene = scene; + this.camera = camera; + } + + clone() { + return Object.assign(new this.constructor(), this); + } +} + +export default RenderBundle; diff --git a/examples-jsm/examples/renderers/common/RenderBundles.ts b/examples-jsm/examples/renderers/common/RenderBundles.ts new file mode 100644 index 000000000..291403652 --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderBundles.ts @@ -0,0 +1,28 @@ +import ChainMap from './ChainMap.js'; +import RenderBundle from './RenderBundle.js'; + +class RenderBundles { + constructor() { + this.lists = new ChainMap(); + } + + get(scene, camera) { + const lists = this.lists; + const keys = [scene, camera]; + + let list = lists.get(keys); + + if (list === undefined) { + list = new RenderBundle(scene, camera); + lists.set(keys, list); + } + + return list; + } + + dispose() { + this.lists = new ChainMap(); + } +} + +export default RenderBundles; diff --git a/examples-jsm/examples/renderers/common/RenderContext.ts b/examples-jsm/examples/renderers/common/RenderContext.ts new file mode 100644 index 000000000..3b43028eb --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderContext.ts @@ -0,0 +1,39 @@ +import { Vector4 } from 'three'; + +let id = 0; + +class RenderContext { + constructor() { + this.id = id++; + + this.color = true; + this.clearColor = true; + this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }; + + this.depth = true; + this.clearDepth = true; + this.clearDepthValue = 1; + + this.stencil = false; + this.clearStencil = true; + this.clearStencilValue = 1; + + this.viewport = false; + this.viewportValue = new Vector4(); + + this.scissor = false; + this.scissorValue = new Vector4(); + + this.textures = null; + this.depthTexture = null; + this.activeCubeFace = 0; + this.sampleCount = 1; + + this.width = 0; + this.height = 0; + + this.isRenderContext = true; + } +} + +export default RenderContext; diff --git a/examples-jsm/examples/renderers/common/RenderContexts.ts b/examples-jsm/examples/renderers/common/RenderContexts.ts new file mode 100644 index 000000000..630a2e42d --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderContexts.ts @@ -0,0 +1,47 @@ +import ChainMap from './ChainMap.js'; +import RenderContext from './RenderContext.js'; + +class RenderContexts { + constructor() { + this.chainMaps = {}; + } + + get(scene, camera, renderTarget = null) { + const chainKey = [scene, camera]; + + let attachmentState; + + if (renderTarget === null) { + attachmentState = 'default'; + } else { + const format = renderTarget.texture.format; + const count = renderTarget.count; + + attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`; + } + + const chainMap = this.getChainMap(attachmentState); + + let renderState = chainMap.get(chainKey); + + if (renderState === undefined) { + renderState = new RenderContext(); + + chainMap.set(chainKey, renderState); + } + + if (renderTarget !== null) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; + + return renderState; + } + + getChainMap(attachmentState) { + return this.chainMaps[attachmentState] || (this.chainMaps[attachmentState] = new ChainMap()); + } + + dispose() { + this.chainMaps = {}; + } +} + +export default RenderContexts; diff --git a/examples-jsm/examples/renderers/common/RenderList.ts b/examples-jsm/examples/renderers/common/RenderList.ts new file mode 100644 index 000000000..a72a91dfd --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderList.ts @@ -0,0 +1,145 @@ +import { LightsNode } from '../../nodes/Nodes.js'; + +function painterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.material.id !== b.material.id) { + return a.material.id - b.material.id; + } else if (a.z !== b.z) { + return a.z - b.z; + } else { + return a.id - b.id; + } +} + +function reversePainterSortStable(a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.z !== b.z) { + return b.z - a.z; + } else { + return a.id - b.id; + } +} + +class RenderList { + constructor() { + this.renderItems = []; + this.renderItemsIndex = 0; + + this.opaque = []; + this.transparent = []; + this.bundles = []; + + this.lightsNode = new LightsNode([]); + this.lightsArray = []; + + this.occlusionQueryCount = 0; + } + + begin() { + this.renderItemsIndex = 0; + + this.opaque.length = 0; + this.transparent.length = 0; + this.bundles.length = 0; + + this.lightsArray.length = 0; + + this.occlusionQueryCount = 0; + + return this; + } + + getNextRenderItem(object, geometry, material, groupOrder, z, group) { + let renderItem = this.renderItems[this.renderItemsIndex]; + + if (renderItem === undefined) { + renderItem = { + id: object.id, + object: object, + geometry: geometry, + material: material, + groupOrder: groupOrder, + renderOrder: object.renderOrder, + z: z, + group: group, + }; + + this.renderItems[this.renderItemsIndex] = renderItem; + } else { + renderItem.id = object.id; + renderItem.object = object; + renderItem.geometry = geometry; + renderItem.material = material; + renderItem.groupOrder = groupOrder; + renderItem.renderOrder = object.renderOrder; + renderItem.z = z; + renderItem.group = group; + } + + this.renderItemsIndex++; + + return renderItem; + } + + push(object, geometry, material, groupOrder, z, group) { + const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); + + if (object.occlusionTest === true) this.occlusionQueryCount++; + + (material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque).push(renderItem); + } + + unshift(object, geometry, material, groupOrder, z, group) { + const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); + + (material.transparent === true ? this.transparent : this.opaque).unshift(renderItem); + } + + pushBundle(group) { + this.bundles.push(group); + } + + pushLight(light) { + this.lightsArray.push(light); + } + + getLightsNode() { + return this.lightsNode.fromLights(this.lightsArray); + } + + sort(customOpaqueSort, customTransparentSort) { + if (this.opaque.length > 1) this.opaque.sort(customOpaqueSort || painterSortStable); + if (this.transparent.length > 1) this.transparent.sort(customTransparentSort || reversePainterSortStable); + } + + finish() { + // update lights + + this.lightsNode.fromLights(this.lightsArray); + + // Clear references from inactive renderItems in the list + + for (let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i++) { + const renderItem = this.renderItems[i]; + + if (renderItem.id === null) break; + + renderItem.id = null; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.groupOrder = null; + renderItem.renderOrder = null; + renderItem.z = null; + renderItem.group = null; + } + } +} + +export default RenderList; diff --git a/examples-jsm/examples/renderers/common/RenderLists.ts b/examples-jsm/examples/renderers/common/RenderLists.ts new file mode 100644 index 000000000..3fc3134e6 --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderLists.ts @@ -0,0 +1,28 @@ +import ChainMap from './ChainMap.js'; +import RenderList from './RenderList.js'; + +class RenderLists { + constructor() { + this.lists = new ChainMap(); + } + + get(scene, camera) { + const lists = this.lists; + const keys = [scene, camera]; + + let list = lists.get(keys); + + if (list === undefined) { + list = new RenderList(); + lists.set(keys, list); + } + + return list; + } + + dispose() { + this.lists = new ChainMap(); + } +} + +export default RenderLists; diff --git a/examples-jsm/examples/renderers/common/RenderObject.ts b/examples-jsm/examples/renderers/common/RenderObject.ts new file mode 100644 index 000000000..91ba0f2a4 --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderObject.ts @@ -0,0 +1,215 @@ +import ClippingContext from './ClippingContext.js'; + +let id = 0; + +function getKeys(obj) { + const keys = Object.keys(obj); + + let proto = Object.getPrototypeOf(obj); + + while (proto) { + const descriptors = Object.getOwnPropertyDescriptors(proto); + + for (const key in descriptors) { + if (descriptors[key] !== undefined) { + const descriptor = descriptors[key]; + + if (descriptor && typeof descriptor.get === 'function') { + keys.push(key); + } + } + } + + proto = Object.getPrototypeOf(proto); + } + + return keys; +} + +export default class RenderObject { + constructor(nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext) { + this._nodes = nodes; + this._geometries = geometries; + + this.id = id++; + + this.renderer = renderer; + this.object = object; + this.material = material; + this.scene = scene; + this.camera = camera; + this.lightsNode = lightsNode; + this.context = renderContext; + + this.geometry = object.geometry; + this.version = material.version; + + this.drawRange = null; + + this.attributes = null; + this.pipeline = null; + this.vertexBuffers = null; + + this.updateClipping(renderContext.clippingContext); + + this.clippingContextVersion = this.clippingContext.version; + + this.initialNodesCacheKey = this.getNodesCacheKey(); + this.initialCacheKey = this.getCacheKey(); + + this._nodeBuilderState = null; + this._bindings = null; + + this.onDispose = null; + + this.isRenderObject = true; + + this.onMaterialDispose = () => { + this.dispose(); + }; + + this.material.addEventListener('dispose', this.onMaterialDispose); + } + + updateClipping(parent) { + const material = this.material; + + let clippingContext = this.clippingContext; + + if (Array.isArray(material.clippingPlanes)) { + if (clippingContext === parent || !clippingContext) { + clippingContext = new ClippingContext(); + this.clippingContext = clippingContext; + } + + clippingContext.update(parent, material); + } else if (this.clippingContext !== parent) { + this.clippingContext = parent; + } + } + + get clippingNeedsUpdate() { + if (this.clippingContext.version === this.clippingContextVersion) return false; + + this.clippingContextVersion = this.clippingContext.version; + + return true; + } + + getNodeBuilderState() { + return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this)); + } + + getBindings() { + return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings()); + } + + getIndex() { + return this._geometries.getIndex(this); + } + + getChainArray() { + return [this.object, this.material, this.context, this.lightsNode]; + } + + getAttributes() { + if (this.attributes !== null) return this.attributes; + + const nodeAttributes = this.getNodeBuilderState().nodeAttributes; + const geometry = this.geometry; + + const attributes = []; + const vertexBuffers = new Set(); + + for (const nodeAttribute of nodeAttributes) { + const attribute = + nodeAttribute.node && nodeAttribute.node.attribute + ? nodeAttribute.node.attribute + : geometry.getAttribute(nodeAttribute.name); + + if (attribute === undefined) continue; + + attributes.push(attribute); + + const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute; + vertexBuffers.add(bufferAttribute); + } + + this.attributes = attributes; + this.vertexBuffers = Array.from(vertexBuffers.values()); + + return attributes; + } + + getVertexBuffers() { + if (this.vertexBuffers === null) this.getAttributes(); + + return this.vertexBuffers; + } + + getMaterialCacheKey() { + const { object, material } = this; + + let cacheKey = material.customProgramCacheKey(); + + for (const property of getKeys(material)) { + if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(property)) continue; + + let value = material[property]; + + if (value !== null) { + const type = typeof value; + + if (type === 'number') + value = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc + else if (type === 'object') value = '{}'; + } + + cacheKey += /*property + ':' +*/ value + ','; + } + + cacheKey += this.clippingContextVersion + ','; + + if (object.skeleton) { + cacheKey += object.skeleton.bones.length + ','; + } + + if (object.morphTargetInfluences) { + cacheKey += object.morphTargetInfluences.length + ','; + } + + if (object.isBatchedMesh) { + cacheKey += object._matricesTexture.uuid + ','; + + if (object._colorsTexture !== null) { + cacheKey += object._colorsTexture.uuid + ','; + } + } + + if (object.count > 1) { + cacheKey += object.count + ','; + } + + return cacheKey; + } + + get needsUpdate() { + return this.initialNodesCacheKey !== this.getNodesCacheKey() || this.clippingNeedsUpdate; + } + + getNodesCacheKey() { + // Environment Nodes Cache Key + + return this._nodes.getCacheKey(this.scene, this.lightsNode); + } + + getCacheKey() { + return this.getMaterialCacheKey() + ',' + this.getNodesCacheKey(); + } + + dispose() { + this.material.removeEventListener('dispose', this.onMaterialDispose); + + this.onDispose(); + } +} diff --git a/examples-jsm/examples/renderers/common/RenderObjects.ts b/examples-jsm/examples/renderers/common/RenderObjects.ts new file mode 100644 index 000000000..76dc482e4 --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderObjects.ts @@ -0,0 +1,100 @@ +import ChainMap from './ChainMap.js'; +import RenderObject from './RenderObject.js'; + +class RenderObjects { + constructor(renderer, nodes, geometries, pipelines, bindings, info) { + this.renderer = renderer; + this.nodes = nodes; + this.geometries = geometries; + this.pipelines = pipelines; + this.bindings = bindings; + this.info = info; + + this.chainMaps = {}; + } + + get(object, material, scene, camera, lightsNode, renderContext, passId) { + const chainMap = this.getChainMap(passId); + const chainArray = [object, material, renderContext, lightsNode]; + + let renderObject = chainMap.get(chainArray); + + if (renderObject === undefined) { + renderObject = this.createRenderObject( + this.nodes, + this.geometries, + this.renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + passId, + ); + + chainMap.set(chainArray, renderObject); + } else { + renderObject.updateClipping(renderContext.clippingContext); + + if (renderObject.version !== material.version || renderObject.needsUpdate) { + if (renderObject.initialCacheKey !== renderObject.getCacheKey()) { + renderObject.dispose(); + + renderObject = this.get(object, material, scene, camera, lightsNode, renderContext, passId); + } else { + renderObject.version = material.version; + } + } + } + + return renderObject; + } + + getChainMap(passId = 'default') { + return this.chainMaps[passId] || (this.chainMaps[passId] = new ChainMap()); + } + + dispose() { + this.chainMaps = {}; + } + + createRenderObject( + nodes, + geometries, + renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + passId, + ) { + const chainMap = this.getChainMap(passId); + + const renderObject = new RenderObject( + nodes, + geometries, + renderer, + object, + material, + scene, + camera, + lightsNode, + renderContext, + ); + + renderObject.onDispose = () => { + this.pipelines.delete(renderObject); + this.bindings.delete(renderObject); + this.nodes.delete(renderObject); + + chainMap.delete(renderObject.getChainArray()); + }; + + return renderObject; + } +} + +export default RenderObjects; diff --git a/examples-jsm/examples/renderers/common/RenderPipeline.ts b/examples-jsm/examples/renderers/common/RenderPipeline.ts new file mode 100644 index 000000000..0ec34b043 --- /dev/null +++ b/examples-jsm/examples/renderers/common/RenderPipeline.ts @@ -0,0 +1,12 @@ +import Pipeline from './Pipeline.js'; + +class RenderPipeline extends Pipeline { + constructor(cacheKey, vertexProgram, fragmentProgram) { + super(cacheKey); + + this.vertexProgram = vertexProgram; + this.fragmentProgram = fragmentProgram; + } +} + +export default RenderPipeline; diff --git a/examples-jsm/examples/renderers/common/Renderer.ts b/examples-jsm/examples/renderers/common/Renderer.ts new file mode 100644 index 000000000..b45a68734 --- /dev/null +++ b/examples-jsm/examples/renderers/common/Renderer.ts @@ -0,0 +1,1347 @@ +import Animation from './Animation.js'; +import RenderObjects from './RenderObjects.js'; +import Attributes from './Attributes.js'; +import Geometries from './Geometries.js'; +import Info from './Info.js'; +import Pipelines from './Pipelines.js'; +import Bindings from './Bindings.js'; +import RenderLists from './RenderLists.js'; +import RenderContexts from './RenderContexts.js'; +import Textures from './Textures.js'; +import Background from './Background.js'; +import Nodes from './nodes/Nodes.js'; +import Color4 from './Color4.js'; +import ClippingContext from './ClippingContext.js'; +import { + Scene, + Frustum, + Matrix4, + Vector2, + Vector3, + Vector4, + DoubleSide, + BackSide, + FrontSide, + SRGBColorSpace, + NoColorSpace, + NoToneMapping, + LinearFilter, + LinearSRGBColorSpace, + RenderTarget, + HalfFloatType, + RGBAFormat, +} from 'three'; +import { NodeMaterial } from '../../nodes/Nodes.js'; +import QuadMesh from '../../objects/QuadMesh.js'; +import RenderBundles from './RenderBundles.js'; + +const _scene = new Scene(); +const _drawingBufferSize = new Vector2(); +const _screen = new Vector4(); +const _frustum = new Frustum(); +const _projScreenMatrix = new Matrix4(); +const _vector3 = new Vector3(); +const _quad = new QuadMesh(new NodeMaterial()); + +class Renderer { + constructor(backend, parameters = {}) { + this.isRenderer = true; + + // + + const { logarithmicDepthBuffer = false, alpha = true } = parameters; + + // public + + this.domElement = backend.getDomElement(); + + this.backend = backend; + + this.autoClear = true; + this.autoClearColor = true; + this.autoClearDepth = true; + this.autoClearStencil = true; + + this.alpha = alpha; + + this.logarithmicDepthBuffer = logarithmicDepthBuffer; + + this.outputColorSpace = SRGBColorSpace; + + this.toneMapping = NoToneMapping; + this.toneMappingExposure = 1.0; + + this.sortObjects = true; + + this.depth = true; + this.stencil = false; + + this.clippingPlanes = []; + + this.info = new Info(); + + // nodes + + this.toneMappingNode = null; + + // internals + + this._pixelRatio = 1; + this._width = this.domElement.width; + this._height = this.domElement.height; + + this._viewport = new Vector4(0, 0, this._width, this._height); + this._scissor = new Vector4(0, 0, this._width, this._height); + this._scissorTest = false; + + this._attributes = null; + this._geometries = null; + this._nodes = null; + this._animation = null; + this._bindings = null; + this._objects = null; + this._pipelines = null; + this._bundles = null; + this._renderLists = null; + this._renderContexts = null; + this._textures = null; + this._background = null; + + this._currentRenderContext = null; + + this._opaqueSort = null; + this._transparentSort = null; + + this._frameBufferTarget = null; + + const alphaClear = this.alpha === true ? 0 : 1; + + this._clearColor = new Color4(0, 0, 0, alphaClear); + this._clearDepth = 1; + this._clearStencil = 0; + + this._renderTarget = null; + this._activeCubeFace = 0; + this._activeMipmapLevel = 0; + + this._renderObjectFunction = null; + this._currentRenderObjectFunction = null; + this._currentRenderBundle = null; + + this._handleObjectFunction = this._renderObjectDirect; + + this._initialized = false; + this._initPromise = null; + + this._compilationPromises = null; + + // backwards compatibility + + this.shadowMap = { + enabled: false, + type: null, + }; + + this.xr = { + enabled: false, + }; + + this.debug = { + checkShaderErrors: true, + onShaderError: null, + }; + } + + async init() { + if (this._initialized) { + throw new Error('Renderer: Backend has already been initialized.'); + } + + if (this._initPromise !== null) { + return this._initPromise; + } + + this._initPromise = new Promise(async (resolve, reject) => { + const backend = this.backend; + + try { + await backend.init(this); + } catch (error) { + reject(error); + return; + } + + this._nodes = new Nodes(this, backend); + this._animation = new Animation(this._nodes, this.info); + this._attributes = new Attributes(backend); + this._background = new Background(this, this._nodes); + this._geometries = new Geometries(this._attributes, this.info); + this._textures = new Textures(this, backend, this.info); + this._pipelines = new Pipelines(backend, this._nodes); + this._bindings = new Bindings( + backend, + this._nodes, + this._textures, + this._attributes, + this._pipelines, + this.info, + ); + this._objects = new RenderObjects( + this, + this._nodes, + this._geometries, + this._pipelines, + this._bindings, + this.info, + ); + this._renderLists = new RenderLists(); + this._bundles = new RenderBundles(); + this._renderContexts = new RenderContexts(); + + // + + this._initialized = true; + + resolve(); + }); + + return this._initPromise; + } + + get coordinateSystem() { + return this.backend.coordinateSystem; + } + + async compileAsync(scene, camera, targetScene = null) { + if (this._initialized === false) await this.init(); + + // preserve render tree + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + const previousRenderContext = this._currentRenderContext; + const previousRenderObjectFunction = this._currentRenderObjectFunction; + const previousCompilationPromises = this._compilationPromises; + + // + + const sceneRef = scene.isScene === true ? scene : _scene; + + if (targetScene === null) targetScene = scene; + + const renderTarget = this._renderTarget; + const renderContext = this._renderContexts.get(targetScene, camera, renderTarget); + const activeMipmapLevel = this._activeMipmapLevel; + + const compilationPromises = []; + + this._currentRenderContext = renderContext; + this._currentRenderObjectFunction = this.renderObject; + + this._handleObjectFunction = this._createObjectPipeline; + + this._compilationPromises = compilationPromises; + + nodeFrame.renderId++; + + // + + nodeFrame.update(); + + // + + renderContext.depth = this.depth; + renderContext.stencil = this.stencil; + + if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); + renderContext.clippingContext.updateGlobal(this, camera); + + // + + sceneRef.onBeforeRender(this, scene, camera, renderTarget); + + // + + const renderList = this._renderLists.get(scene, camera); + renderList.begin(); + + this._projectObject(scene, camera, 0, renderList); + + // include lights from target scene + if (targetScene !== scene) { + targetScene.traverseVisible(function (object) { + if (object.isLight && object.layers.test(camera.layers)) { + renderList.pushLight(object); + } + }); + } + + renderList.finish(); + + // + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); + + const renderTargetData = this._textures.get(renderTarget); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + } else { + renderContext.textures = null; + renderContext.depthTexture = null; + } + + // + + this._nodes.updateScene(sceneRef); + + // + + this._background.update(sceneRef, renderList, renderContext); + + // process render lists + + const opaqueObjects = renderList.opaque; + const transparentObjects = renderList.transparent; + const lightsNode = renderList.lightsNode; + + if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + if (transparentObjects.length > 0) this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); + + // restore render tree + + nodeFrame.renderId = previousRenderId; + + this._currentRenderContext = previousRenderContext; + this._currentRenderObjectFunction = previousRenderObjectFunction; + this._compilationPromises = previousCompilationPromises; + + this._handleObjectFunction = this._renderObjectDirect; + + // wait for all promises setup by backends awaiting compilation/linking/pipeline creation to complete + + await Promise.all(compilationPromises); + } + + async renderAsync(scene, camera) { + if (this._initialized === false) await this.init(); + + const renderContext = this._renderScene(scene, camera); + + await this.backend.resolveTimestampAsync(renderContext, 'render'); + } + + _renderBundle(bundle, sceneRef, lightsNode) { + const { object, camera, renderList } = bundle; + + const renderContext = this._currentRenderContext; + const renderContextData = this.backend.get(renderContext); + + // + + const renderBundle = this._bundles.get(object, camera); + + const renderBundleData = this.backend.get(renderBundle); + if (renderBundleData.renderContexts === undefined) renderBundleData.renderContexts = new Set(); + + // + + const renderBundleNeedsUpdate = + renderBundleData.renderContexts.has(renderContext) === false || object.needsUpdate === true; + + renderBundleData.renderContexts.add(renderContext); + + if (renderBundleNeedsUpdate) { + if (renderContextData.renderObjects === undefined || object.needsUpdate === true) { + const nodeFrame = this._nodes.nodeFrame; + + renderContextData.renderObjects = []; + renderContextData.renderBundles = []; + renderContextData.scene = sceneRef; + renderContextData.camera = camera; + renderContextData.renderId = nodeFrame.renderId; + + renderContextData.registerBundlesPhase = true; + } + + this._currentRenderBundle = renderBundle; + + const opaqueObjects = renderList.opaque; + + if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + + this._currentRenderBundle = null; + + // + + object.needsUpdate = false; + } else { + const renderContext = this._currentRenderContext; + const renderContextData = this.backend.get(renderContext); + + for (let i = 0, l = renderContextData.renderObjects.length; i < l; i++) { + const renderObject = renderContextData.renderObjects[i]; + + this._nodes.updateBefore(renderObject); + + // + + renderObject.object.modelViewMatrix.multiplyMatrices( + camera.matrixWorldInverse, + renderObject.object.matrixWorld, + ); + renderObject.object.normalMatrix.getNormalMatrix(renderObject.object.modelViewMatrix); + + this._nodes.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + + this.backend.draw(renderObject, this.info); + + this._nodes.updateAfter(renderObject); + } + } + } + + render(scene, camera) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.', + ); + + return this.renderAsync(scene, camera); + } + + this._renderScene(scene, camera); + } + + _getFrameBufferTarget() { + const { currentColorSpace } = this; + + const useToneMapping = + this._renderTarget === null && (this.toneMapping !== NoToneMapping || this.toneMappingNode !== null); + const useColorSpace = currentColorSpace !== LinearSRGBColorSpace && currentColorSpace !== NoColorSpace; + + if (useToneMapping === false && useColorSpace === false) return null; + + const { width, height } = this.getDrawingBufferSize(_drawingBufferSize); + const { depth, stencil } = this; + + let frameBufferTarget = this._frameBufferTarget; + + if (frameBufferTarget === null) { + frameBufferTarget = new RenderTarget(width, height, { + depthBuffer: depth, + stencilBuffer: stencil, + type: HalfFloatType, // FloatType + format: RGBAFormat, + colorSpace: LinearSRGBColorSpace, + generateMipmaps: false, + minFilter: LinearFilter, + magFilter: LinearFilter, + samples: this.backend.parameters.antialias ? 4 : 0, + }); + + frameBufferTarget.isPostProcessingRenderTarget = true; + + this._frameBufferTarget = frameBufferTarget; + } + + frameBufferTarget.depthBuffer = depth; + frameBufferTarget.stencilBuffer = stencil; + frameBufferTarget.setSize(width, height); + frameBufferTarget.viewport.copy(this._viewport); + frameBufferTarget.scissor.copy(this._scissor); + frameBufferTarget.viewport.multiplyScalar(this._pixelRatio); + frameBufferTarget.scissor.multiplyScalar(this._pixelRatio); + frameBufferTarget.scissorTest = this._scissorTest; + + return frameBufferTarget; + } + + _renderScene(scene, camera, useFrameBufferTarget = true) { + const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null; + + // preserve render tree + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + const previousRenderContext = this._currentRenderContext; + const previousRenderObjectFunction = this._currentRenderObjectFunction; + + // + + const sceneRef = scene.isScene === true ? scene : _scene; + + const outputRenderTarget = this._renderTarget; + + const activeCubeFace = this._activeCubeFace; + const activeMipmapLevel = this._activeMipmapLevel; + + // + + let renderTarget; + + if (frameBufferTarget !== null) { + renderTarget = frameBufferTarget; + + this.setRenderTarget(renderTarget); + } else { + renderTarget = outputRenderTarget; + } + + // + + const renderContext = this._renderContexts.get(scene, camera, renderTarget); + + this._currentRenderContext = renderContext; + this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject; + + // + + this.info.calls++; + this.info.render.calls++; + this.info.render.frameCalls++; + + nodeFrame.renderId = this.info.calls; + + // + + const coordinateSystem = this.coordinateSystem; + + if (camera.coordinateSystem !== coordinateSystem) { + camera.coordinateSystem = coordinateSystem; + + camera.updateProjectionMatrix(); + } + + // + + if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); + + if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); + + // + + let viewport = this._viewport; + let scissor = this._scissor; + let pixelRatio = this._pixelRatio; + + if (renderTarget !== null) { + viewport = renderTarget.viewport; + scissor = renderTarget.scissor; + pixelRatio = 1; + } + + this.getDrawingBufferSize(_drawingBufferSize); + + _screen.set(0, 0, _drawingBufferSize.width, _drawingBufferSize.height); + + const minDepth = viewport.minDepth === undefined ? 0 : viewport.minDepth; + const maxDepth = viewport.maxDepth === undefined ? 1 : viewport.maxDepth; + + renderContext.viewportValue.copy(viewport).multiplyScalar(pixelRatio).floor(); + renderContext.viewportValue.width >>= activeMipmapLevel; + renderContext.viewportValue.height >>= activeMipmapLevel; + renderContext.viewportValue.minDepth = minDepth; + renderContext.viewportValue.maxDepth = maxDepth; + renderContext.viewport = renderContext.viewportValue.equals(_screen) === false; + + renderContext.scissorValue.copy(scissor).multiplyScalar(pixelRatio).floor(); + renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals(_screen) === false; + renderContext.scissorValue.width >>= activeMipmapLevel; + renderContext.scissorValue.height >>= activeMipmapLevel; + + if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); + renderContext.clippingContext.updateGlobal(this, camera); + + // + + sceneRef.onBeforeRender(this, scene, camera, renderTarget); + + // + + _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); + _frustum.setFromProjectionMatrix(_projScreenMatrix, coordinateSystem); + + const renderList = this._renderLists.get(scene, camera); + renderList.begin(); + + this._projectObject(scene, camera, 0, renderList); + + renderList.finish(); + + if (this.sortObjects === true) { + renderList.sort(this._opaqueSort, this._transparentSort); + } + + // + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); + + const renderTargetData = this._textures.get(renderTarget); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + renderContext.width = renderTargetData.width; + renderContext.height = renderTargetData.height; + renderContext.renderTarget = renderTarget; + renderContext.depth = renderTarget.depthBuffer; + renderContext.stencil = renderTarget.stencilBuffer; + } else { + renderContext.textures = null; + renderContext.depthTexture = null; + renderContext.width = this.domElement.width; + renderContext.height = this.domElement.height; + renderContext.depth = this.depth; + renderContext.stencil = this.stencil; + } + + renderContext.width >>= activeMipmapLevel; + renderContext.height >>= activeMipmapLevel; + renderContext.activeCubeFace = activeCubeFace; + renderContext.activeMipmapLevel = activeMipmapLevel; + renderContext.occlusionQueryCount = renderList.occlusionQueryCount; + + // + + this._nodes.updateScene(sceneRef); + + // + + this._background.update(sceneRef, renderList, renderContext); + + // + + this.backend.beginRender(renderContext); + + // process render lists + + const opaqueObjects = renderList.opaque; + const transparentObjects = renderList.transparent; + const bundles = renderList.bundles; + const lightsNode = renderList.lightsNode; + + if (bundles.length > 0) this._renderBundles(bundles, sceneRef, lightsNode); + if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); + if (transparentObjects.length > 0) this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); + + // finish render pass + + this.backend.finishRender(renderContext); + + // restore render tree + + nodeFrame.renderId = previousRenderId; + + this._currentRenderContext = previousRenderContext; + this._currentRenderObjectFunction = previousRenderObjectFunction; + + // + + if (frameBufferTarget !== null) { + this.setRenderTarget(outputRenderTarget, activeCubeFace, activeMipmapLevel); + + _quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); + + this._renderScene(_quad, _quad.camera, false); + } + + // + + sceneRef.onAfterRender(this, scene, camera, renderTarget); + + // + + return renderContext; + } + + getMaxAnisotropy() { + return this.backend.getMaxAnisotropy(); + } + + getActiveCubeFace() { + return this._activeCubeFace; + } + + getActiveMipmapLevel() { + return this._activeMipmapLevel; + } + + async setAnimationLoop(callback) { + if (this._initialized === false) await this.init(); + + this._animation.setAnimationLoop(callback); + } + + async getArrayBufferAsync(attribute) { + return await this.backend.getArrayBufferAsync(attribute); + } + + getContext() { + return this.backend.getContext(); + } + + getPixelRatio() { + return this._pixelRatio; + } + + getDrawingBufferSize(target) { + return target.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor(); + } + + getSize(target) { + return target.set(this._width, this._height); + } + + setPixelRatio(value = 1) { + this._pixelRatio = value; + + this.setSize(this._width, this._height, false); + } + + setDrawingBufferSize(width, height, pixelRatio) { + this._width = width; + this._height = height; + + this._pixelRatio = pixelRatio; + + this.domElement.width = Math.floor(width * pixelRatio); + this.domElement.height = Math.floor(height * pixelRatio); + + this.setViewport(0, 0, width, height); + + if (this._initialized) this.backend.updateSize(); + } + + setSize(width, height, updateStyle = true) { + this._width = width; + this._height = height; + + this.domElement.width = Math.floor(width * this._pixelRatio); + this.domElement.height = Math.floor(height * this._pixelRatio); + + if (updateStyle === true) { + this.domElement.style.width = width + 'px'; + this.domElement.style.height = height + 'px'; + } + + this.setViewport(0, 0, width, height); + + if (this._initialized) this.backend.updateSize(); + } + + setOpaqueSort(method) { + this._opaqueSort = method; + } + + setTransparentSort(method) { + this._transparentSort = method; + } + + getScissor(target) { + const scissor = this._scissor; + + target.x = scissor.x; + target.y = scissor.y; + target.width = scissor.width; + target.height = scissor.height; + + return target; + } + + setScissor(x, y, width, height) { + const scissor = this._scissor; + + if (x.isVector4) { + scissor.copy(x); + } else { + scissor.set(x, y, width, height); + } + } + + getScissorTest() { + return this._scissorTest; + } + + setScissorTest(boolean) { + this._scissorTest = boolean; + + this.backend.setScissorTest(boolean); + } + + getViewport(target) { + return target.copy(this._viewport); + } + + setViewport(x, y, width, height, minDepth = 0, maxDepth = 1) { + const viewport = this._viewport; + + if (x.isVector4) { + viewport.copy(x); + } else { + viewport.set(x, y, width, height); + } + + viewport.minDepth = minDepth; + viewport.maxDepth = maxDepth; + } + + getClearColor(target) { + return target.copy(this._clearColor); + } + + setClearColor(color, alpha = 1) { + this._clearColor.set(color); + this._clearColor.a = alpha; + } + + getClearAlpha() { + return this._clearColor.a; + } + + setClearAlpha(alpha) { + this._clearColor.a = alpha; + } + + getClearDepth() { + return this._clearDepth; + } + + setClearDepth(depth) { + this._clearDepth = depth; + } + + getClearStencil() { + return this._clearStencil; + } + + setClearStencil(stencil) { + this._clearStencil = stencil; + } + + isOccluded(object) { + const renderContext = this._currentRenderContext; + + return renderContext && this.backend.isOccluded(renderContext, object); + } + + clear(color = true, depth = true, stencil = true) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .clear() called before the backend is initialized. Try using .clearAsync() instead.', + ); + + return this.clearAsync(color, depth, stencil); + } + + const renderTarget = this._renderTarget || this._getFrameBufferTarget(); + + let renderTargetData = null; + + if (renderTarget !== null) { + this._textures.updateRenderTarget(renderTarget); + + renderTargetData = this._textures.get(renderTarget); + } + + this.backend.clear(color, depth, stencil, renderTargetData); + + if (renderTarget !== null && this._renderTarget === null) { + // If a color space transform or tone mapping is required, + // the clear operation clears the intermediate renderTarget texture, but does not update the screen canvas. + + _quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); + this._renderScene(_quad, _quad.camera, false); + } + } + + clearColor() { + return this.clear(true, false, false); + } + + clearDepth() { + return this.clear(false, true, false); + } + + clearStencil() { + return this.clear(false, false, true); + } + + async clearAsync(color = true, depth = true, stencil = true) { + if (this._initialized === false) await this.init(); + + this.clear(color, depth, stencil); + } + + clearColorAsync() { + return this.clearAsync(true, false, false); + } + + clearDepthAsync() { + return this.clearAsync(false, true, false); + } + + clearStencilAsync() { + return this.clearAsync(false, false, true); + } + + get currentColorSpace() { + const renderTarget = this._renderTarget; + + if (renderTarget !== null) { + const texture = renderTarget.texture; + + return (Array.isArray(texture) ? texture[0] : texture).colorSpace; + } + + return this.outputColorSpace; + } + + dispose() { + this.info.dispose(); + + this._animation.dispose(); + this._objects.dispose(); + this._pipelines.dispose(); + this._nodes.dispose(); + this._bindings.dispose(); + this._renderLists.dispose(); + this._renderContexts.dispose(); + this._textures.dispose(); + + this.setRenderTarget(null); + this.setAnimationLoop(null); + } + + setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { + this._renderTarget = renderTarget; + this._activeCubeFace = activeCubeFace; + this._activeMipmapLevel = activeMipmapLevel; + } + + getRenderTarget() { + return this._renderTarget; + } + + setRenderObjectFunction(renderObjectFunction) { + this._renderObjectFunction = renderObjectFunction; + } + + getRenderObjectFunction() { + return this._renderObjectFunction; + } + + async computeAsync(computeNodes) { + if (this._initialized === false) await this.init(); + + const nodeFrame = this._nodes.nodeFrame; + + const previousRenderId = nodeFrame.renderId; + + // + + this.info.calls++; + this.info.compute.calls++; + this.info.compute.frameCalls++; + + nodeFrame.renderId = this.info.calls; + + // + + const backend = this.backend; + const pipelines = this._pipelines; + const bindings = this._bindings; + const nodes = this._nodes; + + const computeList = Array.isArray(computeNodes) ? computeNodes : [computeNodes]; + + if (computeList[0] === undefined || computeList[0].isComputeNode !== true) { + throw new Error('THREE.Renderer: .compute() expects a ComputeNode.'); + } + + backend.beginCompute(computeNodes); + + for (const computeNode of computeList) { + // onInit + + if (pipelines.has(computeNode) === false) { + const dispose = () => { + computeNode.removeEventListener('dispose', dispose); + + pipelines.delete(computeNode); + bindings.delete(computeNode); + nodes.delete(computeNode); + }; + + computeNode.addEventListener('dispose', dispose); + + // + + computeNode.onInit({ renderer: this }); + } + + nodes.updateForCompute(computeNode); + bindings.updateForCompute(computeNode); + + const computeBindings = bindings.getForCompute(computeNode); + const computePipeline = pipelines.getForCompute(computeNode, computeBindings); + + backend.compute(computeNodes, computeNode, computeBindings, computePipeline); + } + + backend.finishCompute(computeNodes); + + await this.backend.resolveTimestampAsync(computeNodes, 'compute'); + + // + + nodeFrame.renderId = previousRenderId; + } + + async hasFeatureAsync(name) { + if (this._initialized === false) await this.init(); + + return this.backend.hasFeature(name); + } + + hasFeature(name) { + if (this._initialized === false) { + console.warn( + 'THREE.Renderer: .hasFeature() called before the backend is initialized. Try using .hasFeatureAsync() instead.', + ); + + return false; + } + + return this.backend.hasFeature(name); + } + + copyFramebufferToTexture(framebufferTexture) { + const renderContext = this._currentRenderContext; + + this._textures.updateTexture(framebufferTexture); + + this.backend.copyFramebufferToTexture(framebufferTexture, renderContext); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { + this._textures.updateTexture(srcTexture); + this._textures.updateTexture(dstTexture); + + this.backend.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); + } + + readRenderTargetPixelsAsync(renderTarget, x, y, width, height, index = 0) { + return this.backend.copyTextureToBuffer(renderTarget.textures[index], x, y, width, height); + } + + _projectObject(object, camera, groupOrder, renderList) { + if (object.visible === false) return; + + const visible = object.layers.test(camera.layers); + + if (visible) { + if (object.isGroup) { + groupOrder = object.renderOrder; + } else if (object.isLOD) { + if (object.autoUpdate === true) object.update(camera); + } else if (object.isLight) { + renderList.pushLight(object); + } else if (object.isSprite) { + if (!object.frustumCulled || _frustum.intersectsSprite(object)) { + if (this.sortObjects === true) { + _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); + } + + const geometry = object.geometry; + const material = object.material; + + if (material.visible) { + renderList.push(object, geometry, material, groupOrder, _vector3.z, null); + } + } + } else if (object.isLineLoop) { + console.error( + 'THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.', + ); + } else if (object.isMesh || object.isLine || object.isPoints) { + if (!object.frustumCulled || _frustum.intersectsObject(object)) { + const geometry = object.geometry; + const material = object.material; + + if (this.sortObjects === true) { + if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); + + _vector3 + .copy(geometry.boundingSphere.center) + .applyMatrix4(object.matrixWorld) + .applyMatrix4(_projScreenMatrix); + } + + if (Array.isArray(material)) { + const groups = geometry.groups; + + for (let i = 0, l = groups.length; i < l; i++) { + const group = groups[i]; + const groupMaterial = material[group.materialIndex]; + + if (groupMaterial && groupMaterial.visible) { + renderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); + } + } + } else if (material.visible) { + renderList.push(object, geometry, material, groupOrder, _vector3.z, null); + } + } + } + } + + if (object.static === true) { + const baseRenderList = renderList; + + // replace render list + renderList = this._renderLists.get(object, camera); + + renderList.begin(); + + baseRenderList.pushBundle({ + object, + camera, + renderList, + }); + + renderList.finish(); + } + + const children = object.children; + + for (let i = 0, l = children.length; i < l; i++) { + this._projectObject(children[i], camera, groupOrder, renderList); + } + } + + _renderBundles(bundles, sceneRef, lightsNode) { + for (const bundle of bundles) { + this._renderBundle(bundle, sceneRef, lightsNode); + } + } + + _renderObjects(renderList, camera, scene, lightsNode) { + // process renderable objects + + for (let i = 0, il = renderList.length; i < il; i++) { + const renderItem = renderList[i]; + + // @TODO: Add support for multiple materials per object. This will require to extract + // the material from the renderItem object and pass it with its group data to renderObject(). + + const { object, geometry, material, group } = renderItem; + + if (camera.isArrayCamera) { + const cameras = camera.cameras; + + for (let j = 0, jl = cameras.length; j < jl; j++) { + const camera2 = cameras[j]; + + if (object.layers.test(camera2.layers)) { + const vp = camera2.viewport; + const minDepth = vp.minDepth === undefined ? 0 : vp.minDepth; + const maxDepth = vp.maxDepth === undefined ? 1 : vp.maxDepth; + + const viewportValue = this._currentRenderContext.viewportValue; + viewportValue.copy(vp).multiplyScalar(this._pixelRatio).floor(); + viewportValue.minDepth = minDepth; + viewportValue.maxDepth = maxDepth; + + this.backend.updateViewport(this._currentRenderContext); + + this._currentRenderObjectFunction( + object, + scene, + camera2, + geometry, + material, + group, + lightsNode, + ); + } + } + } else { + this._currentRenderObjectFunction(object, scene, camera, geometry, material, group, lightsNode); + } + } + } + + renderObject(object, scene, camera, geometry, material, group, lightsNode) { + let overridePositionNode; + let overrideFragmentNode; + let overrideDepthNode; + + // + + object.onBeforeRender(this, scene, camera, geometry, material, group); + + // + + if (scene.overrideMaterial !== null) { + const overrideMaterial = scene.overrideMaterial; + + if (material.positionNode && material.positionNode.isNode) { + overridePositionNode = overrideMaterial.positionNode; + overrideMaterial.positionNode = material.positionNode; + } + + if (overrideMaterial.isShadowNodeMaterial) { + overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide; + + if (material.depthNode && material.depthNode.isNode) { + overrideDepthNode = overrideMaterial.depthNode; + overrideMaterial.depthNode = material.depthNode; + } + + if (material.shadowNode && material.shadowNode.isNode) { + overrideFragmentNode = overrideMaterial.fragmentNode; + overrideMaterial.fragmentNode = material.shadowNode; + } + + if (this.localClippingEnabled) { + if (material.clipShadows) { + if (overrideMaterial.clippingPlanes !== material.clippingPlanes) { + overrideMaterial.clippingPlanes = material.clippingPlanes; + overrideMaterial.needsUpdate = true; + } + + if (overrideMaterial.clipIntersection !== material.clipIntersection) { + overrideMaterial.clipIntersection = material.clipIntersection; + } + } else if (Array.isArray(overrideMaterial.clippingPlanes)) { + overrideMaterial.clippingPlanes = null; + overrideMaterial.needsUpdate = true; + } + } + } + + material = overrideMaterial; + } + + // + + if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { + material.side = BackSide; + this._handleObjectFunction(object, material, scene, camera, lightsNode, group, 'backSide'); // create backSide pass id + + material.side = FrontSide; + this._handleObjectFunction(object, material, scene, camera, lightsNode, group); // use default pass id + + material.side = DoubleSide; + } else { + this._handleObjectFunction(object, material, scene, camera, lightsNode, group); + } + + // + + if (overridePositionNode !== undefined) { + scene.overrideMaterial.positionNode = overridePositionNode; + } + + if (overrideDepthNode !== undefined) { + scene.overrideMaterial.depthNode = overrideDepthNode; + } + + if (overrideFragmentNode !== undefined) { + scene.overrideMaterial.fragmentNode = overrideFragmentNode; + } + + // + + object.onAfterRender(this, scene, camera, geometry, material, group); + } + + _renderObjectDirect(object, material, scene, camera, lightsNode, group, passId) { + const renderObject = this._objects.get( + object, + material, + scene, + camera, + lightsNode, + this._currentRenderContext, + passId, + ); + renderObject.drawRange = group || object.geometry.drawRange; + + // + + this._nodes.updateBefore(renderObject); + + // + + object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); + object.normalMatrix.getNormalMatrix(object.modelViewMatrix); + + // + + this._nodes.updateForRender(renderObject); + this._geometries.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + this._pipelines.updateForRender(renderObject); + + // + + if (this._currentRenderBundle !== null && this._currentRenderBundle.needsUpdate === true) { + const renderObjectData = this.backend.get(renderObject); + + renderObjectData.bundleEncoder = undefined; + renderObjectData.lastPipelineGPU = undefined; + } + + this.backend.draw(renderObject, this.info); + + if (this._currentRenderBundle !== null) { + const renderContextData = this.backend.get(this._currentRenderContext); + + renderContextData.renderObjects.push(renderObject); + } + + this._nodes.updateAfter(renderObject); + } + + _createObjectPipeline(object, material, scene, camera, lightsNode, passId) { + const renderObject = this._objects.get( + object, + material, + scene, + camera, + lightsNode, + this._currentRenderContext, + passId, + ); + + // + + this._nodes.updateBefore(renderObject); + + // + + this._nodes.updateForRender(renderObject); + this._geometries.updateForRender(renderObject); + this._bindings.updateForRender(renderObject); + + this._pipelines.getForRender(renderObject, this._compilationPromises); + + this._nodes.updateAfter(renderObject); + } + + get compute() { + return this.computeAsync; + } + + get compile() { + return this.compileAsync; + } +} + +export default Renderer; diff --git a/examples-jsm/examples/renderers/common/SampledTexture.ts b/examples-jsm/examples/renderers/common/SampledTexture.ts new file mode 100644 index 000000000..d995a59f8 --- /dev/null +++ b/examples-jsm/examples/renderers/common/SampledTexture.ts @@ -0,0 +1,61 @@ +import Binding from './Binding.js'; + +let id = 0; + +class SampledTexture extends Binding { + constructor(name, texture) { + super(name); + + this.id = id++; + + this.texture = texture; + this.version = texture ? texture.version : 0; + this.store = false; + + this.isSampledTexture = true; + } + + get needsBindingsUpdate() { + const { texture, version } = this; + + return texture.isVideoTexture ? true : version !== texture.version; // @TODO: version === 0 && texture.version > 0 ( add it just to External Textures like PNG,JPG ) + } + + update() { + const { texture, version } = this; + + if (version !== texture.version) { + this.version = texture.version; + + return true; + } + + return false; + } +} + +class SampledArrayTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampledArrayTexture = true; + } +} + +class Sampled3DTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampled3DTexture = true; + } +} + +class SampledCubeTexture extends SampledTexture { + constructor(name, texture) { + super(name, texture); + + this.isSampledCubeTexture = true; + } +} + +export { SampledTexture, SampledArrayTexture, Sampled3DTexture, SampledCubeTexture }; diff --git a/examples-jsm/examples/renderers/common/Sampler.ts b/examples-jsm/examples/renderers/common/Sampler.ts new file mode 100644 index 000000000..8cd20d04a --- /dev/null +++ b/examples-jsm/examples/renderers/common/Sampler.ts @@ -0,0 +1,14 @@ +import Binding from './Binding.js'; + +class Sampler extends Binding { + constructor(name, texture) { + super(name); + + this.texture = texture; + this.version = texture ? texture.version : 0; + + this.isSampler = true; + } +} + +export default Sampler; diff --git a/examples-jsm/examples/renderers/common/StorageBuffer.ts b/examples-jsm/examples/renderers/common/StorageBuffer.ts new file mode 100644 index 000000000..ef5d3e464 --- /dev/null +++ b/examples-jsm/examples/renderers/common/StorageBuffer.ts @@ -0,0 +1,13 @@ +import Buffer from './Buffer.js'; + +class StorageBuffer extends Buffer { + constructor(name, attribute) { + super(name, attribute ? attribute.array : null); + + this.attribute = attribute; + + this.isStorageBuffer = true; + } +} + +export default StorageBuffer; diff --git a/examples-jsm/examples/renderers/common/Textures.ts b/examples-jsm/examples/renderers/common/Textures.ts new file mode 100644 index 000000000..0eb0509ca --- /dev/null +++ b/examples-jsm/examples/renderers/common/Textures.ts @@ -0,0 +1,288 @@ +import DataMap from './DataMap.js'; + +import { + Vector3, + DepthTexture, + DepthStencilFormat, + DepthFormat, + UnsignedIntType, + UnsignedInt248Type, + LinearFilter, + NearestFilter, + EquirectangularReflectionMapping, + EquirectangularRefractionMapping, + CubeReflectionMapping, + CubeRefractionMapping, + UnsignedByteType, +} from 'three'; + +const _size = new Vector3(); + +class Textures extends DataMap { + constructor(renderer, backend, info) { + super(); + + this.renderer = renderer; + this.backend = backend; + this.info = info; + } + + updateRenderTarget(renderTarget, activeMipmapLevel = 0) { + const renderTargetData = this.get(renderTarget); + + const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; + const depthTextureMips = renderTargetData.depthTextureMips || (renderTargetData.depthTextureMips = {}); + + const texture = renderTarget.texture; + const textures = renderTarget.textures; + + const size = this.getSize(texture); + + const mipWidth = size.width >> activeMipmapLevel; + const mipHeight = size.height >> activeMipmapLevel; + + let depthTexture = renderTarget.depthTexture || depthTextureMips[activeMipmapLevel]; + let textureNeedsUpdate = false; + + if (depthTexture === undefined) { + depthTexture = new DepthTexture(); + depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat : DepthFormat; + depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type : UnsignedIntType; // FloatType + depthTexture.image.width = mipWidth; + depthTexture.image.height = mipHeight; + + depthTextureMips[activeMipmapLevel] = depthTexture; + } + + if (renderTargetData.width !== size.width || size.height !== renderTargetData.height) { + textureNeedsUpdate = true; + depthTexture.needsUpdate = true; + + depthTexture.image.width = mipWidth; + depthTexture.image.height = mipHeight; + } + + renderTargetData.width = size.width; + renderTargetData.height = size.height; + renderTargetData.textures = textures; + renderTargetData.depthTexture = depthTexture; + renderTargetData.depth = renderTarget.depthBuffer; + renderTargetData.stencil = renderTarget.stencilBuffer; + renderTargetData.renderTarget = renderTarget; + + if (renderTargetData.sampleCount !== sampleCount) { + textureNeedsUpdate = true; + depthTexture.needsUpdate = true; + + renderTargetData.sampleCount = sampleCount; + } + + // + + const options = { sampleCount }; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (textureNeedsUpdate) texture.needsUpdate = true; + + this.updateTexture(texture, options); + } + + this.updateTexture(depthTexture, options); + + // dispose handler + + if (renderTargetData.initialized !== true) { + renderTargetData.initialized = true; + + // dispose + + const onDispose = () => { + renderTarget.removeEventListener('dispose', onDispose); + + if (textures !== undefined) { + for (let i = 0; i < textures.length; i++) { + this._destroyTexture(textures[i]); + } + } else { + this._destroyTexture(texture); + } + + this._destroyTexture(depthTexture); + }; + + renderTarget.addEventListener('dispose', onDispose); + } + } + + updateTexture(texture, options = {}) { + const textureData = this.get(texture); + if (textureData.initialized === true && textureData.version === texture.version) return; + + const isRenderTarget = texture.isRenderTargetTexture || texture.isDepthTexture || texture.isFramebufferTexture; + const backend = this.backend; + + if (isRenderTarget && textureData.initialized === true) { + // it's an update + + backend.destroySampler(texture); + backend.destroyTexture(texture); + } + + // + + if (texture.isFramebufferTexture) { + const renderer = this.renderer; + const renderTarget = renderer.getRenderTarget(); + + if (renderTarget) { + texture.type = renderTarget.texture.type; + } else { + texture.type = UnsignedByteType; + } + } + + // + + const { width, height, depth } = this.getSize(texture); + + options.width = width; + options.height = height; + options.depth = depth; + options.needsMipmaps = this.needsMipmaps(texture); + options.levels = options.needsMipmaps ? this.getMipLevels(texture, width, height) : 1; + + // + + if (isRenderTarget || texture.isStorageTexture === true) { + backend.createSampler(texture); + backend.createTexture(texture, options); + } else { + const needsCreate = textureData.initialized !== true; + + if (needsCreate) backend.createSampler(texture); + + if (texture.version > 0) { + const image = texture.image; + + if (image === undefined) { + console.warn('THREE.Renderer: Texture marked for update but image is undefined.'); + } else if (image.complete === false) { + console.warn('THREE.Renderer: Texture marked for update but image is incomplete.'); + } else { + if (texture.images) { + const images = []; + + for (const image of texture.images) { + images.push(image); + } + + options.images = images; + } else { + options.image = image; + } + + if (textureData.isDefaultTexture === undefined || textureData.isDefaultTexture === true) { + backend.createTexture(texture, options); + + textureData.isDefaultTexture = false; + } + + if (texture.source.dataReady === true) backend.updateTexture(texture, options); + + if (options.needsMipmaps && texture.mipmaps.length === 0) backend.generateMipmaps(texture); + } + } else { + // async update + + backend.createDefaultTexture(texture); + + textureData.isDefaultTexture = true; + } + } + + // dispose handler + + if (textureData.initialized !== true) { + textureData.initialized = true; + + // + + this.info.memory.textures++; + + // dispose + + const onDispose = () => { + texture.removeEventListener('dispose', onDispose); + + this._destroyTexture(texture); + + this.info.memory.textures--; + }; + + texture.addEventListener('dispose', onDispose); + } + + // + + textureData.version = texture.version; + } + + getSize(texture, target = _size) { + let image = texture.images ? texture.images[0] : texture.image; + + if (image) { + if (image.image !== undefined) image = image.image; + + target.width = image.width; + target.height = image.height; + target.depth = texture.isCubeTexture ? 6 : image.depth || 1; + } else { + target.width = target.height = target.depth = 1; + } + + return target; + } + + getMipLevels(texture, width, height) { + let mipLevelCount; + + if (texture.isCompressedTexture) { + mipLevelCount = texture.mipmaps.length; + } else { + mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1; + } + + return mipLevelCount; + } + + needsMipmaps(texture) { + if (this.isEnvironmentTexture(texture)) return true; + + return ( + texture.isCompressedTexture === true || + (texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) + ); + } + + isEnvironmentTexture(texture) { + const mapping = texture.mapping; + + return ( + mapping === EquirectangularReflectionMapping || + mapping === EquirectangularRefractionMapping || + mapping === CubeReflectionMapping || + mapping === CubeRefractionMapping + ); + } + + _destroyTexture(texture) { + this.backend.destroySampler(texture); + this.backend.destroyTexture(texture); + + this.delete(texture); + } +} + +export default Textures; diff --git a/examples-jsm/examples/renderers/common/Uniform.ts b/examples-jsm/examples/renderers/common/Uniform.ts new file mode 100644 index 000000000..3d58b44cb --- /dev/null +++ b/examples-jsm/examples/renderers/common/Uniform.ts @@ -0,0 +1,100 @@ +import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three'; + +class Uniform { + constructor(name, value) { + this.name = name; + this.value = value; + + this.boundary = 0; // used to build the uniform buffer according to the STD140 layout + this.itemSize = 0; + + this.offset = 0; // this property is set by WebGPUUniformsGroup and marks the start position in the uniform buffer + } + + setValue(value) { + this.value = value; + } + + getValue() { + return this.value; + } +} + +class NumberUniform extends Uniform { + constructor(name, value = 0) { + super(name, value); + + this.isNumberUniform = true; + + this.boundary = 4; + this.itemSize = 1; + } +} + +class Vector2Uniform extends Uniform { + constructor(name, value = new Vector2()) { + super(name, value); + + this.isVector2Uniform = true; + + this.boundary = 8; + this.itemSize = 2; + } +} + +class Vector3Uniform extends Uniform { + constructor(name, value = new Vector3()) { + super(name, value); + + this.isVector3Uniform = true; + + this.boundary = 16; + this.itemSize = 3; + } +} + +class Vector4Uniform extends Uniform { + constructor(name, value = new Vector4()) { + super(name, value); + + this.isVector4Uniform = true; + + this.boundary = 16; + this.itemSize = 4; + } +} + +class ColorUniform extends Uniform { + constructor(name, value = new Color()) { + super(name, value); + + this.isColorUniform = true; + + this.boundary = 16; + this.itemSize = 3; + } +} + +class Matrix3Uniform extends Uniform { + constructor(name, value = new Matrix3()) { + super(name, value); + + this.isMatrix3Uniform = true; + + this.boundary = 48; + this.itemSize = 12; + } +} + +class Matrix4Uniform extends Uniform { + constructor(name, value = new Matrix4()) { + super(name, value); + + this.isMatrix4Uniform = true; + + this.boundary = 64; + this.itemSize = 16; + } +} + +export { NumberUniform, Vector2Uniform, Vector3Uniform, Vector4Uniform, ColorUniform, Matrix3Uniform, Matrix4Uniform }; diff --git a/examples-jsm/examples/renderers/common/UniformBuffer.ts b/examples-jsm/examples/renderers/common/UniformBuffer.ts new file mode 100644 index 000000000..28aac0d7e --- /dev/null +++ b/examples-jsm/examples/renderers/common/UniformBuffer.ts @@ -0,0 +1,11 @@ +import Buffer from './Buffer.js'; + +class UniformBuffer extends Buffer { + constructor(name, buffer = null) { + super(name, buffer); + + this.isUniformBuffer = true; + } +} + +export default UniformBuffer; diff --git a/examples-jsm/examples/renderers/common/UniformsGroup.ts b/examples-jsm/examples/renderers/common/UniformsGroup.ts new file mode 100644 index 000000000..e2b62671a --- /dev/null +++ b/examples-jsm/examples/renderers/common/UniformsGroup.ts @@ -0,0 +1,277 @@ +import UniformBuffer from './UniformBuffer.js'; +import { GPU_CHUNK_BYTES } from './Constants.js'; + +class UniformsGroup extends UniformBuffer { + constructor(name) { + super(name); + + this.isUniformsGroup = true; + + this._values = null; + + // the order of uniforms in this array must match the order of uniforms in the shader + + this.uniforms = []; + } + + addUniform(uniform) { + this.uniforms.push(uniform); + + return this; + } + + removeUniform(uniform) { + const index = this.uniforms.indexOf(uniform); + + if (index !== -1) { + this.uniforms.splice(index, 1); + } + + return this; + } + + get values() { + if (this._values === null) { + this._values = Array.from(this.buffer); + } + + return this._values; + } + + get buffer() { + let buffer = this._buffer; + + if (buffer === null) { + const byteLength = this.byteLength; + + buffer = new Float32Array(new ArrayBuffer(byteLength)); + + this._buffer = buffer; + } + + return buffer; + } + + get byteLength() { + let offset = 0; // global buffer offset in bytes + + for (let i = 0, l = this.uniforms.length; i < l; i++) { + const uniform = this.uniforms[i]; + + const { boundary, itemSize } = uniform; + + // offset within a single chunk in bytes + + const chunkOffset = offset % GPU_CHUNK_BYTES; + const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset; + + // conformance tests + + if (chunkOffset !== 0 && remainingSizeInChunk - boundary < 0) { + // check for chunk overflow + + offset += GPU_CHUNK_BYTES - chunkOffset; + } else if (chunkOffset % boundary !== 0) { + // check for correct alignment + + offset += chunkOffset % boundary; + } + + uniform.offset = offset / this.bytesPerElement; + + offset += itemSize * this.bytesPerElement; + } + + return Math.ceil(offset / GPU_CHUNK_BYTES) * GPU_CHUNK_BYTES; + } + + update() { + let updated = false; + + for (const uniform of this.uniforms) { + if (this.updateByType(uniform) === true) { + updated = true; + } + } + + return updated; + } + + updateByType(uniform) { + if (uniform.isNumberUniform) return this.updateNumber(uniform); + if (uniform.isVector2Uniform) return this.updateVector2(uniform); + if (uniform.isVector3Uniform) return this.updateVector3(uniform); + if (uniform.isVector4Uniform) return this.updateVector4(uniform); + if (uniform.isColorUniform) return this.updateColor(uniform); + if (uniform.isMatrix3Uniform) return this.updateMatrix3(uniform); + if (uniform.isMatrix4Uniform) return this.updateMatrix4(uniform); + + console.error('THREE.WebGPUUniformsGroup: Unsupported uniform type.', uniform); + } + + updateNumber(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset] !== v) { + const b = this.buffer; + + b[offset] = a[offset] = v; + updated = true; + } + + return updated; + } + + updateVector2(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + + updated = true; + } + + return updated; + } + + updateVector3(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + b[offset + 2] = a[offset + 2] = v.z; + + updated = true; + } + + return updated; + } + + updateVector4(uniform) { + let updated = false; + + const a = this.values; + const v = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z || a[offset + 4] !== v.w) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = v.x; + b[offset + 1] = a[offset + 1] = v.y; + b[offset + 2] = a[offset + 2] = v.z; + b[offset + 3] = a[offset + 3] = v.w; + + updated = true; + } + + return updated; + } + + updateColor(uniform) { + let updated = false; + + const a = this.values; + const c = uniform.getValue(); + const offset = uniform.offset; + + if (a[offset + 0] !== c.r || a[offset + 1] !== c.g || a[offset + 2] !== c.b) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = c.r; + b[offset + 1] = a[offset + 1] = c.g; + b[offset + 2] = a[offset + 2] = c.b; + + updated = true; + } + + return updated; + } + + updateMatrix3(uniform) { + let updated = false; + + const a = this.values; + const e = uniform.getValue().elements; + const offset = uniform.offset; + + if ( + a[offset + 0] !== e[0] || + a[offset + 1] !== e[1] || + a[offset + 2] !== e[2] || + a[offset + 4] !== e[3] || + a[offset + 5] !== e[4] || + a[offset + 6] !== e[5] || + a[offset + 8] !== e[6] || + a[offset + 9] !== e[7] || + a[offset + 10] !== e[8] + ) { + const b = this.buffer; + + b[offset + 0] = a[offset + 0] = e[0]; + b[offset + 1] = a[offset + 1] = e[1]; + b[offset + 2] = a[offset + 2] = e[2]; + b[offset + 4] = a[offset + 4] = e[3]; + b[offset + 5] = a[offset + 5] = e[4]; + b[offset + 6] = a[offset + 6] = e[5]; + b[offset + 8] = a[offset + 8] = e[6]; + b[offset + 9] = a[offset + 9] = e[7]; + b[offset + 10] = a[offset + 10] = e[8]; + + updated = true; + } + + return updated; + } + + updateMatrix4(uniform) { + let updated = false; + + const a = this.values; + const e = uniform.getValue().elements; + const offset = uniform.offset; + + if (arraysEqual(a, e, offset) === false) { + const b = this.buffer; + b.set(e, offset); + setArray(a, e, offset); + updated = true; + } + + return updated; + } +} + +function setArray(a, b, offset) { + for (let i = 0, l = b.length; i < l; i++) { + a[offset + i] = b[i]; + } +} + +function arraysEqual(a, b, offset) { + for (let i = 0, l = b.length; i < l; i++) { + if (a[offset + i] !== b[i]) return false; + } + + return true; +} + +export default UniformsGroup; diff --git a/examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts b/examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts new file mode 100644 index 000000000..b0aa2f8e8 --- /dev/null +++ b/examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts @@ -0,0 +1,659 @@ +import NodeMaterial from '../../../nodes/materials/NodeMaterial.js'; +import { getDirection, blur } from '../../../nodes/pmrem/PMREMUtils.js'; +import { equirectUV } from '../../../nodes/utils/EquirectUVNode.js'; +import { uniform } from '../../../nodes/core/UniformNode.js'; +import { uniforms } from '../../../nodes/accessors/UniformsNode.js'; +import { texture } from '../../../nodes/accessors/TextureNode.js'; +import { cubeTexture } from '../../../nodes/accessors/CubeTextureNode.js'; +import { float, vec3 } from '../../../nodes/shadernode/ShaderNode.js'; +import { uv } from '../../../nodes/accessors/UVNode.js'; +import { attribute } from '../../../nodes/core/AttributeNode.js'; +import { + OrthographicCamera, + Color, + Vector3, + BufferGeometry, + BufferAttribute, + RenderTarget, + Mesh, + CubeReflectionMapping, + CubeRefractionMapping, + CubeUVReflectionMapping, + LinearFilter, + NoBlending, + RGBAFormat, + HalfFloatType, + BackSide, + LinearSRGBColorSpace, + PerspectiveCamera, + MeshBasicMaterial, + BoxGeometry, +} from 'three'; + +const LOD_MIN = 4; + +// The standard deviations (radians) associated with the extra mips. These are +// chosen to approximate a Trowbridge-Reitz distribution function times the +// geometric shadowing function. These sigma values squared must match the +// variance #defines in cube_uv_reflection_fragment.glsl.js. +const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; + +// The maximum length of the blur for loop. Smaller sigmas will use fewer +// samples and exit early, but not recompile the shader. +const MAX_SAMPLES = 20; + +const _flatCamera = /*@__PURE__*/ new OrthographicCamera(-1, 1, 1, -1, 0, 1); +const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera(90, 1); +const _clearColor = /*@__PURE__*/ new Color(); +let _oldTarget = null; +let _oldActiveCubeFace = 0; +let _oldActiveMipmapLevel = 0; + +// Golden Ratio +const PHI = (1 + Math.sqrt(5)) / 2; +const INV_PHI = 1 / PHI; + +// Vertices of a dodecahedron (except the opposites, which represent the +// same axis), used as axis directions evenly spread on a sphere. +const _axisDirections = [ + /*@__PURE__*/ new Vector3(-PHI, INV_PHI, 0), + /*@__PURE__*/ new Vector3(PHI, INV_PHI, 0), + /*@__PURE__*/ new Vector3(-INV_PHI, 0, PHI), + /*@__PURE__*/ new Vector3(INV_PHI, 0, PHI), + /*@__PURE__*/ new Vector3(0, PHI, -INV_PHI), + /*@__PURE__*/ new Vector3(0, PHI, INV_PHI), + /*@__PURE__*/ new Vector3(-1, 1, -1), + /*@__PURE__*/ new Vector3(1, 1, -1), + /*@__PURE__*/ new Vector3(-1, 1, 1), + /*@__PURE__*/ new Vector3(1, 1, 1), +]; + +// + +// WebGPU Face indices +const _faceLib = [3, 1, 5, 0, 4, 2]; + +const direction = getDirection(uv(), attribute('faceIndex')).normalize(); +const outputDirection = vec3(direction.x, direction.y.negate(), direction.z); + +/** + * This class generates a Prefiltered, Mipmapped Radiance Environment Map + * (PMREM) from a cubeMap environment texture. This allows different levels of + * blur to be quickly accessed based on material roughness. It is packed into a + * special CubeUV format that allows us to perform custom interpolation so that + * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap + * chain, it only goes down to the LOD_MIN level (above), and then creates extra + * even more filtered 'mips' at the same LOD_MIN resolution, associated with + * higher roughness levels. In this way we maintain resolution to smoothly + * interpolate diffuse lighting while limiting sampling computation. + * + * Paper: Fast, Accurate Image-Based Lighting + * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view + */ + +class PMREMGenerator { + constructor(renderer) { + this._renderer = renderer; + this._pingPongRenderTarget = null; + + this._lodMax = 0; + this._cubeSize = 0; + this._lodPlanes = []; + this._sizeLods = []; + this._sigmas = []; + this._lodMeshes = []; + + this._blurMaterial = null; + this._cubemapMaterial = null; + this._equirectMaterial = null; + this._backgroundBox = null; + } + + /** + * Generates a PMREM from a supplied Scene, which can be faster than using an + * image if networking bandwidth is low. Optional sigma specifies a blur radius + * in radians to be applied to the scene before PMREM generation. Optional near + * and far planes ensure the scene is rendered in its entirety (the cubeCamera + * is placed at the origin). + */ + fromScene(scene, sigma = 0, near = 0.1, far = 100) { + _oldTarget = this._renderer.getRenderTarget(); + _oldActiveCubeFace = this._renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); + + this._setSize(256); + + const cubeUVRenderTarget = this._allocateTargets(); + cubeUVRenderTarget.depthBuffer = true; + + this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); + + if (sigma > 0) { + this._blur(cubeUVRenderTarget, 0, 0, sigma); + } + + this._applyPMREM(cubeUVRenderTarget); + + this._cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + /** + * Generates a PMREM from an equirectangular texture, which can be either LDR + * or HDR. The ideal input image size is 1k (1024 x 512), + * as this matches best with the 256 x 256 cubemap output. + */ + fromEquirectangular(equirectangular, renderTarget = null) { + return this._fromTexture(equirectangular, renderTarget); + } + + /** + * Generates a PMREM from an cubemap texture, which can be either LDR + * or HDR. The ideal input cube size is 256 x 256, + * as this matches best with the 256 x 256 cubemap output. + */ + fromCubemap(cubemap, renderTarget = null) { + return this._fromTexture(cubemap, renderTarget); + } + + /** + * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + compileCubemapShader() { + if (this._cubemapMaterial === null) { + this._cubemapMaterial = _getCubemapMaterial(); + this._compileMaterial(this._cubemapMaterial); + } + } + + /** + * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during + * your texture's network fetch for increased concurrency. + */ + compileEquirectangularShader() { + if (this._equirectMaterial === null) { + this._equirectMaterial = _getEquirectMaterial(); + this._compileMaterial(this._equirectMaterial); + } + } + + /** + * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, + * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on + * one of them will cause any others to also become unusable. + */ + dispose() { + this._dispose(); + + if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); + if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); + if (this._backgroundBox !== null) { + this._backgroundBox.geometry.dispose(); + this._backgroundBox.material.dispose(); + } + } + + // private interface + + _setSize(cubeSize) { + this._lodMax = Math.floor(Math.log2(cubeSize)); + this._cubeSize = Math.pow(2, this._lodMax); + } + + _dispose() { + if (this._blurMaterial !== null) this._blurMaterial.dispose(); + + if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); + + for (let i = 0; i < this._lodPlanes.length; i++) { + this._lodPlanes[i].dispose(); + } + } + + _cleanup(outputTarget) { + this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); + outputTarget.scissorTest = false; + _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); + } + + _fromTexture(texture, renderTarget) { + if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { + this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); + } else { + // Equirectangular + + this._setSize(texture.image.width / 4); + } + + _oldTarget = this._renderer.getRenderTarget(); + _oldActiveCubeFace = this._renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); + + const cubeUVRenderTarget = renderTarget || this._allocateTargets(); + this._textureToCubeUV(texture, cubeUVRenderTarget); + this._applyPMREM(cubeUVRenderTarget); + this._cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + _allocateTargets() { + const width = 3 * Math.max(this._cubeSize, 16 * 7); + const height = 4 * this._cubeSize; + + const params = { + magFilter: LinearFilter, + minFilter: LinearFilter, + generateMipmaps: false, + type: HalfFloatType, + format: RGBAFormat, + colorSpace: LinearSRGBColorSpace, + //depthBuffer: false + }; + + const cubeUVRenderTarget = _createRenderTarget(width, height, params); + + if ( + this._pingPongRenderTarget === null || + this._pingPongRenderTarget.width !== width || + this._pingPongRenderTarget.height !== height + ) { + if (this._pingPongRenderTarget !== null) { + this._dispose(); + } + + this._pingPongRenderTarget = _createRenderTarget(width, height, params); + + const { _lodMax } = this; + ({ + sizeLods: this._sizeLods, + lodPlanes: this._lodPlanes, + sigmas: this._sigmas, + lodMeshes: this._lodMeshes, + } = _createPlanes(_lodMax)); + + this._blurMaterial = _getBlurShader(_lodMax, width, height); + } + + return cubeUVRenderTarget; + } + + _compileMaterial(material) { + const tmpMesh = this._lodMeshes[0]; + tmpMesh.material = material; + + this._renderer.compile(tmpMesh, _flatCamera); + } + + _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { + const cubeCamera = _cubeCamera; + cubeCamera.near = near; + cubeCamera.far = far; + + // px, py, pz, nx, ny, nz + const upSign = [-1, 1, -1, -1, -1, -1]; + const forwardSign = [1, 1, 1, -1, -1, -1]; + + const renderer = this._renderer; + + const originalAutoClear = renderer.autoClear; + + renderer.getClearColor(_clearColor); + + renderer.autoClear = false; + + let backgroundBox = this._backgroundBox; + + if (backgroundBox === null) { + const backgroundMaterial = new MeshBasicMaterial({ + name: 'PMREM.Background', + side: BackSide, + depthWrite: false, + depthTest: false, + }); + + backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); + } + + let useSolidColor = false; + const background = scene.background; + + if (background) { + if (background.isColor) { + backgroundBox.material.color.copy(background); + scene.background = null; + useSolidColor = true; + } + } else { + backgroundBox.material.color.copy(_clearColor); + useSolidColor = true; + } + + renderer.setRenderTarget(cubeUVRenderTarget); + + renderer.clear(); + + if (useSolidColor) { + renderer.render(backgroundBox, cubeCamera); + } + + for (let i = 0; i < 6; i++) { + const col = i % 3; + + if (col === 0) { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(forwardSign[i], 0, 0); + } else if (col === 1) { + cubeCamera.up.set(0, 0, upSign[i]); + cubeCamera.lookAt(0, forwardSign[i], 0); + } else { + cubeCamera.up.set(0, upSign[i], 0); + cubeCamera.lookAt(0, 0, forwardSign[i]); + } + + const size = this._cubeSize; + + _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); + + renderer.render(scene, cubeCamera); + } + + renderer.autoClear = originalAutoClear; + scene.background = background; + } + + _textureToCubeUV(texture, cubeUVRenderTarget) { + const renderer = this._renderer; + + const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; + + if (isCubeTexture) { + if (this._cubemapMaterial === null) { + this._cubemapMaterial = _getCubemapMaterial(texture); + } + } else { + if (this._equirectMaterial === null) { + this._equirectMaterial = _getEquirectMaterial(texture); + } + } + + const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; + material.fragmentNode.value = texture; + + const mesh = this._lodMeshes[0]; + mesh.material = material; + + const size = this._cubeSize; + + _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); + + renderer.setRenderTarget(cubeUVRenderTarget); + renderer.render(mesh, _flatCamera); + } + + _applyPMREM(cubeUVRenderTarget) { + const renderer = this._renderer; + const autoClear = renderer.autoClear; + renderer.autoClear = false; + const n = this._lodPlanes.length; + + for (let i = 1; i < n; i++) { + const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); + + const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length]; + + this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); + } + + renderer.autoClear = autoClear; + } + + /** + * This is a two-pass Gaussian blur for a cubemap. Normally this is done + * vertically and horizontally, but this breaks down on a cube. Here we apply + * the blur latitudinally (around the poles), and then longitudinally (towards + * the poles) to approximate the orthogonally-separable blur. It is least + * accurate at the poles, but still does a decent job. + */ + _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { + const pingPongRenderTarget = this._pingPongRenderTarget; + + this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); + + this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); + } + + _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { + const renderer = this._renderer; + const blurMaterial = this._blurMaterial; + + if (direction !== 'latitudinal' && direction !== 'longitudinal') { + console.error('blur direction must be either latitudinal or longitudinal!'); + } + + // Number of standard deviations at which to cut off the discrete approximation. + const STANDARD_DEVIATIONS = 3; + + const blurMesh = this._lodMeshes[lodOut]; + blurMesh.material = blurMaterial; + + const blurUniforms = blurMaterial.uniforms; + + const pixels = this._sizeLods[lodIn] - 1; + const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : (2 * Math.PI) / (2 * MAX_SAMPLES - 1); + const sigmaPixels = sigmaRadians / radiansPerPixel; + const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; + + if (samples > MAX_SAMPLES) { + console.warn( + `sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${ + samples + } samples when the maximum is set to ${MAX_SAMPLES}`, + ); + } + + const weights = []; + let sum = 0; + + for (let i = 0; i < MAX_SAMPLES; ++i) { + const x = i / sigmaPixels; + const weight = Math.exp((-x * x) / 2); + weights.push(weight); + + if (i === 0) { + sum += weight; + } else if (i < samples) { + sum += 2 * weight; + } + } + + for (let i = 0; i < weights.length; i++) { + weights[i] = weights[i] / sum; + } + + targetIn.texture.frame = (targetIn.texture.frame || 0) + 1; + + blurUniforms.envMap.value = targetIn.texture; + blurUniforms.samples.value = samples; + blurUniforms.weights.array = weights; + blurUniforms.latitudinal.value = direction === 'latitudinal' ? 1 : 0; + + if (poleAxis) { + blurUniforms.poleAxis.value = poleAxis; + } + + const { _lodMax } = this; + blurUniforms.dTheta.value = radiansPerPixel; + blurUniforms.mipInt.value = _lodMax - lodIn; + + const outputSize = this._sizeLods[lodOut]; + const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); + const y = 4 * (this._cubeSize - outputSize); + + _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); + renderer.setRenderTarget(targetOut); + renderer.render(blurMesh, _flatCamera); + } +} + +function _createPlanes(lodMax) { + const lodPlanes = []; + const sizeLods = []; + const sigmas = []; + const lodMeshes = []; + + let lod = lodMax; + + const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; + + for (let i = 0; i < totalLods; i++) { + const sizeLod = Math.pow(2, lod); + sizeLods.push(sizeLod); + let sigma = 1.0 / sizeLod; + + if (i > lodMax - LOD_MIN) { + sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; + } else if (i === 0) { + sigma = 0; + } + + sigmas.push(sigma); + + const texelSize = 1.0 / (sizeLod - 2); + const min = -texelSize; + const max = 1 + texelSize; + const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; + + const cubeFaces = 6; + const vertices = 6; + const positionSize = 3; + const uvSize = 2; + const faceIndexSize = 1; + + const position = new Float32Array(positionSize * vertices * cubeFaces); + const uv = new Float32Array(uvSize * vertices * cubeFaces); + const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); + + for (let face = 0; face < cubeFaces; face++) { + const x = ((face % 3) * 2) / 3 - 1; + const y = face > 2 ? 0 : -1; + const coordinates = [ + x, + y, + 0, + x + 2 / 3, + y, + 0, + x + 2 / 3, + y + 1, + 0, + x, + y, + 0, + x + 2 / 3, + y + 1, + 0, + x, + y + 1, + 0, + ]; + + const faceIdx = _faceLib[face]; + position.set(coordinates, positionSize * vertices * faceIdx); + uv.set(uv1, uvSize * vertices * faceIdx); + const fill = [faceIdx, faceIdx, faceIdx, faceIdx, faceIdx, faceIdx]; + faceIndex.set(fill, faceIndexSize * vertices * faceIdx); + } + + const planes = new BufferGeometry(); + planes.setAttribute('position', new BufferAttribute(position, positionSize)); + planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); + planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); + lodPlanes.push(planes); + lodMeshes.push(new Mesh(planes, null)); + + if (lod > LOD_MIN) { + lod--; + } + } + + return { lodPlanes, sizeLods, sigmas, lodMeshes }; +} + +function _createRenderTarget(width, height, params) { + const cubeUVRenderTarget = new RenderTarget(width, height, params); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.texture.isPMREMTexture = true; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; +} + +function _setViewport(target, x, y, width, height) { + const viewY = target.height - height - y; + + target.viewport.set(x, viewY, width, height); + target.scissor.set(x, viewY, width, height); +} + +function _getMaterial() { + const material = new NodeMaterial(); + material.depthTest = false; + material.depthWrite = false; + material.blending = NoBlending; + + return material; +} + +function _getBlurShader(lodMax, width, height) { + const weights = uniforms(new Array(MAX_SAMPLES).fill(0)); + const poleAxis = uniform(new Vector3(0, 1, 0)); + const dTheta = uniform(0); + const n = float(MAX_SAMPLES); + const latitudinal = uniform(0); // false, bool + const samples = uniform(1); // int + const envMap = texture(null); + const mipInt = uniform(0); // int + const CUBEUV_TEXEL_WIDTH = float(1 / width); + const CUBEUV_TEXEL_HEIGHT = float(1 / height); + const CUBEUV_MAX_MIP = float(lodMax); + + const materialUniforms = { + n, + latitudinal, + weights, + poleAxis, + outputDirection, + dTheta, + samples, + envMap, + mipInt, + CUBEUV_TEXEL_WIDTH, + CUBEUV_TEXEL_HEIGHT, + CUBEUV_MAX_MIP, + }; + + const material = _getMaterial(); + material.uniforms = materialUniforms; // TODO: Move to outside of the material + material.fragmentNode = blur({ ...materialUniforms, latitudinal: latitudinal.equal(1) }); + + return material; +} + +function _getCubemapMaterial(envTexture) { + const material = _getMaterial(); + material.fragmentNode = cubeTexture(envTexture, outputDirection); + + return material; +} + +function _getEquirectMaterial(envTexture) { + const material = _getMaterial(); + material.fragmentNode = texture(envTexture, equirectUV(outputDirection), 0); + + return material; +} + +export default PMREMGenerator; diff --git a/examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts b/examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts new file mode 100644 index 000000000..e94d965f9 --- /dev/null +++ b/examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts @@ -0,0 +1,55 @@ +import BindGroup from '../BindGroup.js'; + +class NodeBuilderState { + constructor( + vertexShader, + fragmentShader, + computeShader, + nodeAttributes, + bindings, + updateNodes, + updateBeforeNodes, + updateAfterNodes, + instanceBindGroups = true, + transforms = [], + ) { + this.vertexShader = vertexShader; + this.fragmentShader = fragmentShader; + this.computeShader = computeShader; + this.transforms = transforms; + + this.nodeAttributes = nodeAttributes; + this.bindings = bindings; + + this.updateNodes = updateNodes; + this.updateBeforeNodes = updateBeforeNodes; + this.updateAfterNodes = updateAfterNodes; + + this.instanceBindGroups = instanceBindGroups; + + this.usedTimes = 0; + } + + createBindings() { + const bindings = []; + + for (const instanceGroup of this.bindings) { + const shared = this.instanceBindGroups && instanceGroup.bindings[0].groupNode.shared; + + if (shared !== true) { + const bindingsGroup = new BindGroup(instanceGroup.name); + bindings.push(bindingsGroup); + + for (const instanceBinding of instanceGroup.bindings) { + bindingsGroup.bindings.push(instanceBinding.clone()); + } + } else { + bindings.push(instanceGroup); + } + } + + return bindings; + } +} + +export default NodeBuilderState; diff --git a/examples-jsm/examples/renderers/common/nodes/NodeUniform.ts b/examples-jsm/examples/renderers/common/nodes/NodeUniform.ts new file mode 100644 index 000000000..659f5a82f --- /dev/null +++ b/examples-jsm/examples/renderers/common/nodes/NodeUniform.ts @@ -0,0 +1,103 @@ +import { + NumberUniform, + Vector2Uniform, + Vector3Uniform, + Vector4Uniform, + ColorUniform, + Matrix3Uniform, + Matrix4Uniform, +} from '../Uniform.js'; + +class NumberNodeUniform extends NumberUniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector2NodeUniform extends Vector2Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector3NodeUniform extends Vector3Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Vector4NodeUniform extends Vector4Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class ColorNodeUniform extends ColorUniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Matrix3NodeUniform extends Matrix3Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +class Matrix4NodeUniform extends Matrix4Uniform { + constructor(nodeUniform) { + super(nodeUniform.name, nodeUniform.value); + + this.nodeUniform = nodeUniform; + } + + getValue() { + return this.nodeUniform.value; + } +} + +export { + NumberNodeUniform, + Vector2NodeUniform, + Vector3NodeUniform, + Vector4NodeUniform, + ColorNodeUniform, + Matrix3NodeUniform, + Matrix4NodeUniform, +}; diff --git a/examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts b/examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts new file mode 100644 index 000000000..e7b389cd6 --- /dev/null +++ b/examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts @@ -0,0 +1,30 @@ +import UniformsGroup from '../UniformsGroup.js'; + +let id = 0; + +class NodeUniformsGroup extends UniformsGroup { + constructor(name, groupNode) { + super(name); + + this.id = id++; + this.groupNode = groupNode; + + this.isNodeUniformsGroup = true; + } + + getNodes() { + const nodes = []; + + for (const uniform of this.uniforms) { + const node = uniform.nodeUniform.node; + + if (!node) throw new Error('NodeUniformsGroup: Uniform has no node.'); + + nodes.push(node); + } + + return nodes; + } +} + +export default NodeUniformsGroup; diff --git a/examples-jsm/examples/renderers/common/nodes/Nodes.ts b/examples-jsm/examples/renderers/common/nodes/Nodes.ts new file mode 100644 index 000000000..db035f6d9 --- /dev/null +++ b/examples-jsm/examples/renderers/common/nodes/Nodes.ts @@ -0,0 +1,394 @@ +import DataMap from '../DataMap.js'; +import ChainMap from '../ChainMap.js'; +import NodeBuilderState from './NodeBuilderState.js'; +import { + EquirectangularReflectionMapping, + EquirectangularRefractionMapping, + NoToneMapping, + SRGBColorSpace, +} from 'three'; +import { + NodeFrame, + vec4, + objectGroup, + renderGroup, + frameGroup, + cubeTexture, + texture, + rangeFog, + densityFog, + reference, + viewportBottomLeft, + normalWorld, + pmremTexture, + viewportTopLeft, +} from '../../../nodes/Nodes.js'; + +class Nodes extends DataMap { + constructor(renderer, backend) { + super(); + + this.renderer = renderer; + this.backend = backend; + this.nodeFrame = new NodeFrame(); + this.nodeBuilderCache = new Map(); + this.callHashCache = new ChainMap(); + this.groupsData = new ChainMap(); + } + + updateGroup(nodeUniformsGroup) { + const groupNode = nodeUniformsGroup.groupNode; + const name = groupNode.name; + + // objectGroup is every updated + + if (name === objectGroup.name) return true; + + // renderGroup is updated once per render/compute call + + if (name === renderGroup.name) { + const uniformsGroupData = this.get(nodeUniformsGroup); + const renderId = this.nodeFrame.renderId; + + if (uniformsGroupData.renderId !== renderId) { + uniformsGroupData.renderId = renderId; + + return true; + } + + return false; + } + + // frameGroup is updated once per frame + + if (name === frameGroup.name) { + const uniformsGroupData = this.get(nodeUniformsGroup); + const frameId = this.nodeFrame.frameId; + + if (uniformsGroupData.frameId !== frameId) { + uniformsGroupData.frameId = frameId; + + return true; + } + + return false; + } + + // other groups are updated just when groupNode.needsUpdate is true + + const groupChain = [groupNode, nodeUniformsGroup]; + + let groupData = this.groupsData.get(groupChain); + if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {})); + + if (groupData.version !== groupNode.version) { + groupData.version = groupNode.version; + + return true; + } + + return false; + } + + getForRenderCacheKey(renderObject) { + return renderObject.initialCacheKey; + } + + getForRender(renderObject) { + const renderObjectData = this.get(renderObject); + + let nodeBuilderState = renderObjectData.nodeBuilderState; + + if (nodeBuilderState === undefined) { + const { nodeBuilderCache } = this; + + const cacheKey = this.getForRenderCacheKey(renderObject); + + nodeBuilderState = nodeBuilderCache.get(cacheKey); + + if (nodeBuilderState === undefined) { + const nodeBuilder = this.backend.createNodeBuilder(renderObject.object, this.renderer); + nodeBuilder.scene = renderObject.scene; + nodeBuilder.material = renderObject.material; + nodeBuilder.camera = renderObject.camera; + nodeBuilder.context.material = renderObject.material; + nodeBuilder.lightsNode = renderObject.lightsNode; + nodeBuilder.environmentNode = this.getEnvironmentNode(renderObject.scene); + nodeBuilder.fogNode = this.getFogNode(renderObject.scene); + nodeBuilder.clippingContext = renderObject.clippingContext; + nodeBuilder.build(); + + nodeBuilderState = this._createNodeBuilderState(nodeBuilder); + + nodeBuilderCache.set(cacheKey, nodeBuilderState); + } + + nodeBuilderState.usedTimes++; + + renderObjectData.nodeBuilderState = nodeBuilderState; + } + + return nodeBuilderState; + } + + delete(object) { + if (object.isRenderObject) { + const nodeBuilderState = this.get(object).nodeBuilderState; + nodeBuilderState.usedTimes--; + + if (nodeBuilderState.usedTimes === 0) { + this.nodeBuilderCache.delete(this.getForRenderCacheKey(object)); + } + } + + return super.delete(object); + } + + getForCompute(computeNode) { + const computeData = this.get(computeNode); + + let nodeBuilderState = computeData.nodeBuilderState; + + if (nodeBuilderState === undefined) { + const nodeBuilder = this.backend.createNodeBuilder(computeNode, this.renderer); + nodeBuilder.build(); + + nodeBuilderState = this._createNodeBuilderState(nodeBuilder); + + computeData.nodeBuilderState = nodeBuilderState; + } + + return nodeBuilderState; + } + + _createNodeBuilderState(nodeBuilder) { + return new NodeBuilderState( + nodeBuilder.vertexShader, + nodeBuilder.fragmentShader, + nodeBuilder.computeShader, + nodeBuilder.getAttributesArray(), + nodeBuilder.getBindings(), + nodeBuilder.updateNodes, + nodeBuilder.updateBeforeNodes, + nodeBuilder.updateAfterNodes, + nodeBuilder.instanceBindGroups, + nodeBuilder.transforms, + ); + } + + getEnvironmentNode(scene) { + return scene.environmentNode || this.get(scene).environmentNode || null; + } + + getBackgroundNode(scene) { + return scene.backgroundNode || this.get(scene).backgroundNode || null; + } + + getFogNode(scene) { + return scene.fogNode || this.get(scene).fogNode || null; + } + + getCacheKey(scene, lightsNode) { + const chain = [scene, lightsNode]; + const callId = this.renderer.info.calls; + + let cacheKeyData = this.callHashCache.get(chain); + + if (cacheKeyData === undefined || cacheKeyData.callId !== callId) { + const environmentNode = this.getEnvironmentNode(scene); + const fogNode = this.getFogNode(scene); + + const cacheKey = []; + + if (lightsNode) cacheKey.push(lightsNode.getCacheKey()); + if (environmentNode) cacheKey.push(environmentNode.getCacheKey()); + if (fogNode) cacheKey.push(fogNode.getCacheKey()); + + cacheKeyData = { + callId, + cacheKey: cacheKey.join(','), + }; + + this.callHashCache.set(chain, cacheKeyData); + } + + return cacheKeyData.cacheKey; + } + + updateScene(scene) { + this.updateEnvironment(scene); + this.updateFog(scene); + this.updateBackground(scene); + } + + get isToneMappingState() { + return this.renderer.getRenderTarget() ? false : true; + } + + updateBackground(scene) { + const sceneData = this.get(scene); + const background = scene.background; + + if (background) { + if (sceneData.background !== background) { + let backgroundNode = null; + + if ( + background.isCubeTexture === true || + background.mapping === EquirectangularReflectionMapping || + background.mapping === EquirectangularRefractionMapping + ) { + backgroundNode = pmremTexture(background, normalWorld); + } else if (background.isTexture === true) { + backgroundNode = texture(background, viewportBottomLeft).setUpdateMatrix(true); + } else if (background.isColor !== true) { + console.error('WebGPUNodes: Unsupported background configuration.', background); + } + + sceneData.backgroundNode = backgroundNode; + sceneData.background = background; + } + } else if (sceneData.backgroundNode) { + delete sceneData.backgroundNode; + delete sceneData.background; + } + } + + updateFog(scene) { + const sceneData = this.get(scene); + const fog = scene.fog; + + if (fog) { + if (sceneData.fog !== fog) { + let fogNode = null; + + if (fog.isFogExp2) { + fogNode = densityFog(reference('color', 'color', fog), reference('density', 'float', fog)); + } else if (fog.isFog) { + fogNode = rangeFog( + reference('color', 'color', fog), + reference('near', 'float', fog), + reference('far', 'float', fog), + ); + } else { + console.error('WebGPUNodes: Unsupported fog configuration.', fog); + } + + sceneData.fogNode = fogNode; + sceneData.fog = fog; + } + } else { + delete sceneData.fogNode; + delete sceneData.fog; + } + } + + updateEnvironment(scene) { + const sceneData = this.get(scene); + const environment = scene.environment; + + if (environment) { + if (sceneData.environment !== environment) { + let environmentNode = null; + + if (environment.isCubeTexture === true) { + environmentNode = cubeTexture(environment); + } else if (environment.isTexture === true) { + environmentNode = texture(environment); + } else { + console.error('Nodes: Unsupported environment configuration.', environment); + } + + sceneData.environmentNode = environmentNode; + sceneData.environment = environment; + } + } else if (sceneData.environmentNode) { + delete sceneData.environmentNode; + delete sceneData.environment; + } + } + + getNodeFrame(renderer = this.renderer, scene = null, object = null, camera = null, material = null) { + const nodeFrame = this.nodeFrame; + nodeFrame.renderer = renderer; + nodeFrame.scene = scene; + nodeFrame.object = object; + nodeFrame.camera = camera; + nodeFrame.material = material; + + return nodeFrame; + } + + getNodeFrameForRender(renderObject) { + return this.getNodeFrame( + renderObject.renderer, + renderObject.scene, + renderObject.object, + renderObject.camera, + renderObject.material, + ); + } + + getOutputNode(outputTexture) { + let output = texture(outputTexture, viewportTopLeft); + + if (this.isToneMappingState) { + if (this.renderer.toneMappingNode) { + output = vec4(this.renderer.toneMappingNode.context({ color: output.rgb }), output.a); + } else if (this.renderer.toneMapping !== NoToneMapping) { + output = output.toneMapping(this.renderer.toneMapping); + } + } + + if (this.renderer.currentColorSpace === SRGBColorSpace) { + output = output.linearToColorSpace(this.renderer.currentColorSpace); + } + + return output; + } + + updateBefore(renderObject) { + const nodeFrame = this.getNodeFrameForRender(renderObject); + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateBeforeNodes) { + nodeFrame.updateBeforeNode(node); + } + } + + updateAfter(renderObject) { + const nodeFrame = this.getNodeFrameForRender(renderObject); + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateAfterNodes) { + nodeFrame.updateAfterNode(node); + } + } + + updateForCompute(computeNode) { + const nodeFrame = this.getNodeFrame(); + const nodeBuilder = this.getForCompute(computeNode); + + for (const node of nodeBuilder.updateNodes) { + nodeFrame.updateNode(node); + } + } + + updateForRender(renderObject) { + const nodeFrame = this.getNodeFrameForRender(renderObject); + const nodeBuilder = renderObject.getNodeBuilderState(); + + for (const node of nodeBuilder.updateNodes) { + nodeFrame.updateNode(node); + } + } + + dispose() { + super.dispose(); + + this.nodeFrame = new NodeFrame(); + this.nodeBuilderCache = new Map(); + } +} + +export default Nodes; diff --git a/examples-jsm/examples/renderers/webgl/WebGLBackend.ts b/examples-jsm/examples/renderers/webgl/WebGLBackend.ts new file mode 100644 index 000000000..f32af4344 --- /dev/null +++ b/examples-jsm/examples/renderers/webgl/WebGLBackend.ts @@ -0,0 +1,1268 @@ +import { WebGLCoordinateSystem } from 'three'; + +import GLSLNodeBuilder from './nodes/GLSLNodeBuilder.js'; +import Backend from '../common/Backend.js'; + +import WebGLAttributeUtils from './utils/WebGLAttributeUtils.js'; +import WebGLState from './utils/WebGLState.js'; +import WebGLUtils from './utils/WebGLUtils.js'; +import WebGLTextureUtils from './utils/WebGLTextureUtils.js'; +import WebGLExtensions from './utils/WebGLExtensions.js'; +import WebGLCapabilities from './utils/WebGLCapabilities.js'; +import { GLFeatureName } from './utils/WebGLConstants.js'; +import { WebGLBufferRenderer } from './WebGLBufferRenderer.js'; + +// + +class WebGLBackend extends Backend { + constructor(parameters = {}) { + super(parameters); + + this.isWebGLBackend = true; + } + + init(renderer) { + super.init(renderer); + + // + + const parameters = this.parameters; + + const glContext = + parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgl2'); + + this.gl = glContext; + + this.extensions = new WebGLExtensions(this); + this.capabilities = new WebGLCapabilities(this); + this.attributeUtils = new WebGLAttributeUtils(this); + this.textureUtils = new WebGLTextureUtils(this); + this.bufferRenderer = new WebGLBufferRenderer(this); + + this.state = new WebGLState(this); + this.utils = new WebGLUtils(this); + + this.vaoCache = {}; + this.transformFeedbackCache = {}; + this.discard = false; + this.trackTimestamp = parameters.trackTimestamp === true; + + this.extensions.get('EXT_color_buffer_float'); + this.disjoint = this.extensions.get('EXT_disjoint_timer_query_webgl2'); + this.parallel = this.extensions.get('KHR_parallel_shader_compile'); + this._currentContext = null; + } + + get coordinateSystem() { + return WebGLCoordinateSystem; + } + + async getArrayBufferAsync(attribute) { + return await this.attributeUtils.getArrayBufferAsync(attribute); + } + + initTimestampQuery(renderContext) { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (this.queryRunning) { + if (!renderContextData.queryQueue) renderContextData.queryQueue = []; + renderContextData.queryQueue.push(renderContext); + return; + } + + if (renderContextData.activeQuery) { + this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); + renderContextData.activeQuery = null; + } + + renderContextData.activeQuery = this.gl.createQuery(); + + if (renderContextData.activeQuery !== null) { + this.gl.beginQuery(this.disjoint.TIME_ELAPSED_EXT, renderContextData.activeQuery); + this.queryRunning = true; + } + } + + // timestamp utils + + prepareTimestampBuffer(renderContext) { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (renderContextData.activeQuery) { + this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); + + if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; + renderContextData.gpuQueries.push({ query: renderContextData.activeQuery }); + renderContextData.activeQuery = null; + this.queryRunning = false; + + if (renderContextData.queryQueue && renderContextData.queryQueue.length > 0) { + const nextRenderContext = renderContextData.queryQueue.shift(); + this.initTimestampQuery(nextRenderContext); + } + } + } + + async resolveTimestampAsync(renderContext, type = 'render') { + if (!this.disjoint || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; + + for (let i = 0; i < renderContextData.gpuQueries.length; i++) { + const queryInfo = renderContextData.gpuQueries[i]; + const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE); + const disjoint = this.gl.getParameter(this.disjoint.GPU_DISJOINT_EXT); + + if (available && !disjoint) { + const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT); + const duration = Number(elapsed) / 1000000; // Convert nanoseconds to milliseconds + this.gl.deleteQuery(queryInfo.query); + renderContextData.gpuQueries.splice(i, 1); // Remove the processed query + i--; + this.renderer.info.updateTimestamp(type, duration); + } + } + } + + getContext() { + return this.gl; + } + + beginRender(renderContext) { + const { gl } = this; + const renderContextData = this.get(renderContext); + + // + + // + + this.initTimestampQuery(renderContext); + + renderContextData.previousContext = this._currentContext; + this._currentContext = renderContext; + + this._setFramebuffer(renderContext); + + this.clear( + renderContext.clearColor, + renderContext.clearDepth, + renderContext.clearStencil, + renderContext, + false, + ); + + // + if (renderContext.viewport) { + this.updateViewport(renderContext); + } else { + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + gl.scissor(x, y, width, height); + } + + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (occlusionQueryCount > 0) { + // Get a reference to the array of objects with queries. The renderContextData property + // can be changed by another render pass before the async reading of all previous queries complete + renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries; + renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; + + renderContextData.lastOcclusionObject = null; + renderContextData.occlusionQueries = new Array(occlusionQueryCount); + renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); + renderContextData.occlusionQueryIndex = 0; + } + } + + finishRender(renderContext) { + const { gl, state } = this; + const renderContextData = this.get(renderContext); + const previousContext = renderContextData.previousContext; + + const textures = renderContext.textures; + + if (textures !== null) { + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (texture.generateMipmaps) { + this.generateMipmaps(texture); + } + } + } + + this._currentContext = previousContext; + + if (renderContext.textures !== null && renderContext.renderTarget) { + const renderTargetContextData = this.get(renderContext.renderTarget); + + const { samples } = renderContext.renderTarget; + const fb = renderTargetContextData.framebuffer; + + const mask = gl.COLOR_BUFFER_BIT; + + if (samples > 0) { + const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; + + const textures = renderContext.textures; + + state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); + state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); + + for (let i = 0; i < textures.length; i++) { + // TODO Add support for MRT + + gl.blitFramebuffer( + 0, + 0, + renderContext.width, + renderContext.height, + 0, + 0, + renderContext.width, + renderContext.height, + mask, + gl.NEAREST, + ); + + gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray); + } + } + } + + if (previousContext !== null) { + this._setFramebuffer(previousContext); + + if (previousContext.viewport) { + this.updateViewport(previousContext); + } else { + const gl = this.gl; + + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } + } + + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (occlusionQueryCount > 0) { + const renderContextData = this.get(renderContext); + + if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { + const { gl } = this; + + gl.endQuery(gl.ANY_SAMPLES_PASSED); + } + + this.resolveOccludedAsync(renderContext); + } + + this.prepareTimestampBuffer(renderContext); + } + + resolveOccludedAsync(renderContext) { + const renderContextData = this.get(renderContext); + + // handle occlusion query results + + const { currentOcclusionQueries, currentOcclusionQueryObjects } = renderContextData; + + if (currentOcclusionQueries && currentOcclusionQueryObjects) { + const occluded = new WeakSet(); + const { gl } = this; + + renderContextData.currentOcclusionQueryObjects = null; + renderContextData.currentOcclusionQueries = null; + + const check = () => { + let completed = 0; + + // check all queries and requeue as appropriate + for (let i = 0; i < currentOcclusionQueries.length; i++) { + const query = currentOcclusionQueries[i]; + + if (query === null) continue; + + if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) { + if (gl.getQueryParameter(query, gl.QUERY_RESULT) > 0) + occluded.add(currentOcclusionQueryObjects[i]); + + currentOcclusionQueries[i] = null; + gl.deleteQuery(query); + + completed++; + } + } + + if (completed < currentOcclusionQueries.length) { + requestAnimationFrame(check); + } else { + renderContextData.occluded = occluded; + } + }; + + check(); + } + } + + isOccluded(renderContext, object) { + const renderContextData = this.get(renderContext); + + return renderContextData.occluded && renderContextData.occluded.has(object); + } + + updateViewport(renderContext) { + const gl = this.gl; + const { x, y, width, height } = renderContext.viewportValue; + + gl.viewport(x, y, width, height); + } + + setScissorTest(boolean) { + const gl = this.gl; + + if (boolean) { + gl.enable(gl.SCISSOR_TEST); + } else { + gl.disable(gl.SCISSOR_TEST); + } + } + + clear(color, depth, stencil, descriptor = null, setFrameBuffer = true) { + const { gl } = this; + + if (descriptor === null) { + descriptor = { + textures: null, + clearColorValue: this.getClearColor(), + }; + } + + // + + let clear = 0; + + if (color) clear |= gl.COLOR_BUFFER_BIT; + if (depth) clear |= gl.DEPTH_BUFFER_BIT; + if (stencil) clear |= gl.STENCIL_BUFFER_BIT; + + if (clear !== 0) { + const clearColor = descriptor.clearColorValue || this.getClearColor(); + + if (depth) this.state.setDepthMask(true); + + if (descriptor.textures === null) { + gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + gl.clear(clear); + } else { + if (setFrameBuffer) this._setFramebuffer(descriptor); + + if (color) { + for (let i = 0; i < descriptor.textures.length; i++) { + gl.clearBufferfv(gl.COLOR, i, [clearColor.r, clearColor.g, clearColor.b, clearColor.a]); + } + } + + if (depth && stencil) { + gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0); + } else if (depth) { + gl.clearBufferfv(gl.DEPTH, 0, [1.0]); + } else if (stencil) { + gl.clearBufferiv(gl.STENCIL, 0, [0]); + } + } + } + } + + beginCompute(computeGroup) { + const gl = this.gl; + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + this.initTimestampQuery(computeGroup); + } + + compute(computeGroup, computeNode, bindings, pipeline) { + const gl = this.gl; + + if (!this.discard) { + // required here to handle async behaviour of render.compute() + gl.enable(gl.RASTERIZER_DISCARD); + this.discard = true; + } + + const { programGPU, transformBuffers, attributes } = this.get(pipeline); + + const vaoKey = this._getVaoKey(null, attributes); + + const vaoGPU = this.vaoCache[vaoKey]; + + if (vaoGPU === undefined) { + this._createVao(null, attributes); + } else { + gl.bindVertexArray(vaoGPU); + } + + gl.useProgram(programGPU); + + this._bindUniforms(bindings); + + const transformFeedbackGPU = this._getTransformFeedback(transformBuffers); + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); + gl.beginTransformFeedback(gl.POINTS); + + if (attributes[0].isStorageInstancedBufferAttribute) { + gl.drawArraysInstanced(gl.POINTS, 0, 1, computeNode.count); + } else { + gl.drawArrays(gl.POINTS, 0, computeNode.count); + } + + gl.endTransformFeedback(); + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + + // switch active buffers + + for (let i = 0; i < transformBuffers.length; i++) { + const dualAttributeData = transformBuffers[i]; + + if (dualAttributeData.pbo) { + this.textureUtils.copyBufferToTexture(dualAttributeData.transformBuffer, dualAttributeData.pbo); + } + + dualAttributeData.switchBuffers(); + } + } + + finishCompute(computeGroup) { + const gl = this.gl; + + this.discard = false; + + gl.disable(gl.RASTERIZER_DISCARD); + + this.prepareTimestampBuffer(computeGroup); + } + + draw(renderObject /*, info*/) { + const { object, pipeline, material, context } = renderObject; + const { programGPU } = this.get(pipeline); + + const { gl, state } = this; + + const contextData = this.get(context); + + // + + this._bindUniforms(renderObject.getBindings()); + + const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; + + state.setMaterial(material, frontFaceCW); + + gl.useProgram(programGPU); + + // + + let vaoGPU = renderObject.staticVao; + + if (vaoGPU === undefined) { + const vaoKey = this._getVaoKey(renderObject.getIndex(), renderObject.getAttributes()); + + vaoGPU = this.vaoCache[vaoKey]; + + if (vaoGPU === undefined) { + let staticVao; + + ({ vaoGPU, staticVao } = this._createVao(renderObject.getIndex(), renderObject.getAttributes())); + + if (staticVao) renderObject.staticVao = vaoGPU; + } + } + + gl.bindVertexArray(vaoGPU); + + // + + const index = renderObject.getIndex(); + + const geometry = renderObject.geometry; + const drawRange = renderObject.drawRange; + const firstVertex = drawRange.start; + + // + + const lastObject = contextData.lastOcclusionObject; + + if (lastObject !== object && lastObject !== undefined) { + if (lastObject !== null && lastObject.occlusionTest === true) { + gl.endQuery(gl.ANY_SAMPLES_PASSED); + + contextData.occlusionQueryIndex++; + } + + if (object.occlusionTest === true) { + const query = gl.createQuery(); + + gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); + + contextData.occlusionQueries[contextData.occlusionQueryIndex] = query; + contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; + } + + contextData.lastOcclusionObject = object; + } + + // + + const renderer = this.bufferRenderer; + + if (object.isPoints) renderer.mode = gl.POINTS; + else if (object.isLineSegments) renderer.mode = gl.LINES; + else if (object.isLine) renderer.mode = gl.LINE_STRIP; + else if (object.isLineLoop) renderer.mode = gl.LINE_LOOP; + else { + if (material.wireframe === true) { + state.setLineWidth(material.wireframeLinewidth * this.renderer.getPixelRatio()); + renderer.mode = gl.LINES; + } else { + renderer.mode = gl.TRIANGLES; + } + } + + // + + let count; + + renderer.object = object; + + if (index !== null) { + const indexData = this.get(index); + const indexCount = drawRange.count !== Infinity ? drawRange.count : index.count; + + renderer.index = index.count; + renderer.type = indexData.type; + + count = indexCount; + } else { + renderer.index = 0; + + const vertexCount = drawRange.count !== Infinity ? drawRange.count : geometry.attributes.position.count; + + count = vertexCount; + } + + const instanceCount = this.getInstanceCount(renderObject); + + if (object.isBatchedMesh) { + if (object._multiDrawInstances !== null) { + renderer.renderMultiDrawInstances( + object._multiDrawStarts, + object._multiDrawCounts, + object._multiDrawCount, + object._multiDrawInstances, + ); + } else { + renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); + } + } else if (instanceCount > 1) { + renderer.renderInstances(firstVertex, count, instanceCount); + } else { + renderer.render(firstVertex, count); + } + // + + gl.bindVertexArray(null); + } + + needsRenderUpdate(/*renderObject*/) { + return false; + } + + getRenderCacheKey(renderObject) { + return renderObject.id; + } + + // textures + + createDefaultTexture(texture) { + this.textureUtils.createDefaultTexture(texture); + } + + createTexture(texture, options) { + this.textureUtils.createTexture(texture, options); + } + + updateTexture(texture, options) { + this.textureUtils.updateTexture(texture, options); + } + + generateMipmaps(texture) { + this.textureUtils.generateMipmaps(texture); + } + + destroyTexture(texture) { + this.textureUtils.destroyTexture(texture); + } + + copyTextureToBuffer(texture, x, y, width, height) { + return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height); + } + + createSampler(/*texture*/) { + //console.warn( 'Abstract class.' ); + } + + destroySampler() {} + + // node builder + + createNodeBuilder(object, renderer) { + return new GLSLNodeBuilder(object, renderer); + } + + // program + + createProgram(program) { + const gl = this.gl; + const { stage, code } = program; + + const shader = stage === 'fragment' ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); + + gl.shaderSource(shader, code); + gl.compileShader(shader); + + this.set(program, { + shaderGPU: shader, + }); + } + + destroyProgram(/*program*/) { + console.warn('Abstract class.'); + } + + createRenderPipeline(renderObject, promises) { + const gl = this.gl; + const pipeline = renderObject.pipeline; + + // Program + + const { fragmentProgram, vertexProgram } = pipeline; + + const programGPU = gl.createProgram(); + + const fragmentShader = this.get(fragmentProgram).shaderGPU; + const vertexShader = this.get(vertexProgram).shaderGPU; + + gl.attachShader(programGPU, fragmentShader); + gl.attachShader(programGPU, vertexShader); + gl.linkProgram(programGPU); + + this.set(pipeline, { + programGPU, + fragmentShader, + vertexShader, + }); + + if (promises !== null && this.parallel) { + const p = new Promise((resolve /*, reject*/) => { + const parallel = this.parallel; + const checkStatus = () => { + if (gl.getProgramParameter(programGPU, parallel.COMPLETION_STATUS_KHR)) { + this._completeCompile(renderObject, pipeline); + resolve(); + } else { + requestAnimationFrame(checkStatus); + } + }; + + checkStatus(); + }); + + promises.push(p); + + return; + } + + this._completeCompile(renderObject, pipeline); + } + + _handleSource(string, errorLine) { + const lines = string.split('\n'); + const lines2 = []; + + const from = Math.max(errorLine - 6, 0); + const to = Math.min(errorLine + 6, lines.length); + + for (let i = from; i < to; i++) { + const line = i + 1; + lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); + } + + return lines2.join('\n'); + } + + _getShaderErrors(gl, shader, type) { + const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); + const errors = gl.getShaderInfoLog(shader).trim(); + + if (status && errors === '') return ''; + + const errorMatches = /ERROR: 0:(\d+)/.exec(errors); + if (errorMatches) { + const errorLine = parseInt(errorMatches[1]); + return ( + type.toUpperCase() + + '\n\n' + + errors + + '\n\n' + + this._handleSource(gl.getShaderSource(shader), errorLine) + ); + } else { + return errors; + } + } + + _logProgramError(programGPU, glFragmentShader, glVertexShader) { + if (this.renderer.debug.checkShaderErrors) { + const gl = this.gl; + + const programLog = gl.getProgramInfoLog(programGPU).trim(); + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + if (typeof this.renderer.debug.onShaderError === 'function') { + this.renderer.debug.onShaderError(gl, programGPU, glVertexShader, glFragmentShader); + } else { + // default error reporting + + const vertexErrors = this._getShaderErrors(gl, glVertexShader, 'vertex'); + const fragmentErrors = this._getShaderErrors(gl, glFragmentShader, 'fragment'); + + console.error( + 'THREE.WebGLProgram: Shader Error ' + + gl.getError() + + ' - ' + + 'VALIDATE_STATUS ' + + gl.getProgramParameter(programGPU, gl.VALIDATE_STATUS) + + '\n\n' + + 'Program Info Log: ' + + programLog + + '\n' + + vertexErrors + + '\n' + + fragmentErrors, + ); + } + } else if (programLog !== '') { + console.warn('THREE.WebGLProgram: Program Info Log:', programLog); + } + } + } + + _completeCompile(renderObject, pipeline) { + const gl = this.gl; + const pipelineData = this.get(pipeline); + const { programGPU, fragmentShader, vertexShader } = pipelineData; + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + this._logProgramError(programGPU, fragmentShader, vertexShader); + } + + gl.useProgram(programGPU); + + // Bindings + + const bindings = renderObject.getBindings(); + + this._setupBindings(bindings, programGPU); + + // + + this.set(pipeline, { + programGPU, + }); + } + + createComputePipeline(computePipeline, bindings) { + const gl = this.gl; + + // Program + + const fragmentProgram = { + stage: 'fragment', + code: '#version 300 es\nprecision highp float;\nvoid main() {}', + }; + + this.createProgram(fragmentProgram); + + const { computeProgram } = computePipeline; + + const programGPU = gl.createProgram(); + + const fragmentShader = this.get(fragmentProgram).shaderGPU; + const vertexShader = this.get(computeProgram).shaderGPU; + + const transforms = computeProgram.transforms; + + const transformVaryingNames = []; + const transformAttributeNodes = []; + + for (let i = 0; i < transforms.length; i++) { + const transform = transforms[i]; + + transformVaryingNames.push(transform.varyingName); + transformAttributeNodes.push(transform.attributeNode); + } + + gl.attachShader(programGPU, fragmentShader); + gl.attachShader(programGPU, vertexShader); + + gl.transformFeedbackVaryings(programGPU, transformVaryingNames, gl.SEPARATE_ATTRIBS); + + gl.linkProgram(programGPU); + + if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { + this._logProgramError(programGPU, fragmentShader, vertexShader); + } + + gl.useProgram(programGPU); + + // Bindings + + this.createBindings(null, bindings); + + this._setupBindings(bindings, programGPU); + + const attributeNodes = computeProgram.attributes; + const attributes = []; + const transformBuffers = []; + + for (let i = 0; i < attributeNodes.length; i++) { + const attribute = attributeNodes[i].node.attribute; + + attributes.push(attribute); + + if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + for (let i = 0; i < transformAttributeNodes.length; i++) { + const attribute = transformAttributeNodes[i].attribute; + + if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + + const attributeData = this.get(attribute); + + transformBuffers.push(attributeData); + } + + // + + this.set(computePipeline, { + programGPU, + transformBuffers, + attributes, + }); + } + + createBindings(bindGroup, bindings) { + this.updateBindings(bindGroup, bindings); + } + + updateBindings(bindGroup, bindings) { + const { gl } = this; + + let groupIndex = 0; + let textureIndex = 0; + + for (const bindGroup of bindings) { + for (const binding of bindGroup.bindings) { + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const bufferGPU = gl.createBuffer(); + const data = binding.buffer; + + gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); + gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); + gl.bindBufferBase(gl.UNIFORM_BUFFER, groupIndex, bufferGPU); + + this.set(binding, { + index: groupIndex++, + bufferGPU, + }); + } else if (binding.isSampledTexture) { + const { textureGPU, glTextureType } = this.get(binding.texture); + + this.set(binding, { + index: textureIndex++, + textureGPU, + glTextureType, + }); + } + } + } + } + + updateBinding(binding) { + const gl = this.gl; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const bindingData = this.get(binding); + const bufferGPU = bindingData.bufferGPU; + const data = binding.buffer; + + gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); + gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); + } + } + + // attributes + + createIndexAttribute(attribute) { + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ELEMENT_ARRAY_BUFFER); + } + + createAttribute(attribute) { + if (this.has(attribute)) return; + + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + createStorageAttribute(attribute) { + if (this.has(attribute)) return; + + const gl = this.gl; + + this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); + } + + updateAttribute(attribute) { + this.attributeUtils.updateAttribute(attribute); + } + + destroyAttribute(attribute) { + this.attributeUtils.destroyAttribute(attribute); + } + + updateSize() { + //console.warn( 'Abstract class.' ); + } + + hasFeature(name) { + const keysMatching = Object.keys(GLFeatureName).filter(key => GLFeatureName[key] === name); + + const extensions = this.extensions; + + for (let i = 0; i < keysMatching.length; i++) { + if (extensions.has(keysMatching[i])) return true; + } + + return false; + } + + getMaxAnisotropy() { + return this.capabilities.getMaxAnisotropy(); + } + + copyTextureToTexture(position, srcTexture, dstTexture, level) { + this.textureUtils.copyTextureToTexture(position, srcTexture, dstTexture, level); + } + + copyFramebufferToTexture(texture, renderContext) { + this.textureUtils.copyFramebufferToTexture(texture, renderContext); + } + + _setFramebuffer(renderContext) { + const { gl, state } = this; + + let currentFrameBuffer = null; + + if (renderContext.textures !== null) { + const renderTarget = renderContext.renderTarget; + const renderTargetContextData = this.get(renderTarget); + const { samples, depthBuffer, stencilBuffer } = renderTarget; + const cubeFace = this.renderer._activeCubeFace; + const isCube = renderTarget.isWebGLCubeRenderTarget === true; + + let msaaFb = renderTargetContextData.msaaFrameBuffer; + let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; + + let fb; + + if (isCube) { + if (renderTargetContextData.cubeFramebuffers === undefined) { + renderTargetContextData.cubeFramebuffers = []; + } + + fb = renderTargetContextData.cubeFramebuffers[cubeFace]; + } else { + fb = renderTargetContextData.framebuffer; + } + + if (fb === undefined) { + fb = gl.createFramebuffer(); + + state.bindFramebuffer(gl.FRAMEBUFFER, fb); + + const textures = renderContext.textures; + + if (isCube) { + renderTargetContextData.cubeFramebuffers[cubeFace] = fb; + const { textureGPU } = this.get(textures[0]); + + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, + textureGPU, + 0, + ); + } else { + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + const textureData = this.get(texture); + textureData.renderTarget = renderContext.renderTarget; + + const attachment = gl.COLOR_ATTACHMENT0 + i; + + gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0); + } + + renderTargetContextData.framebuffer = fb; + + state.drawBuffers(renderContext, fb); + } + + if (renderContext.depthTexture !== null) { + const textureData = this.get(renderContext.depthTexture); + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + + gl.framebufferTexture2D(gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0); + } + } + + if (samples > 0) { + if (msaaFb === undefined) { + const invalidationArray = []; + + msaaFb = gl.createFramebuffer(); + + state.bindFramebuffer(gl.FRAMEBUFFER, msaaFb); + + const msaaRenderbuffers = []; + + const textures = renderContext.textures; + + for (let i = 0; i < textures.length; i++) { + msaaRenderbuffers[i] = gl.createRenderbuffer(); + + gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRenderbuffers[i]); + + invalidationArray.push(gl.COLOR_ATTACHMENT0 + i); + + if (depthBuffer) { + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + invalidationArray.push(depthStyle); + } + + const texture = renderContext.textures[i]; + const textureData = this.get(texture); + + gl.renderbufferStorageMultisample( + gl.RENDERBUFFER, + samples, + textureData.glInternalFormat, + renderContext.width, + renderContext.height, + ); + gl.framebufferRenderbuffer( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0 + i, + gl.RENDERBUFFER, + msaaRenderbuffers[i], + ); + } + + renderTargetContextData.msaaFrameBuffer = msaaFb; + renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers; + + if (depthRenderbuffer === undefined) { + depthRenderbuffer = gl.createRenderbuffer(); + this.textureUtils.setupRenderBufferStorage(depthRenderbuffer, renderContext); + + renderTargetContextData.depthRenderbuffer = depthRenderbuffer; + + const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; + invalidationArray.push(depthStyle); + } + + renderTargetContextData.invalidationArray = invalidationArray; + } + + currentFrameBuffer = renderTargetContextData.msaaFrameBuffer; + } else { + currentFrameBuffer = fb; + } + } + + state.bindFramebuffer(gl.FRAMEBUFFER, currentFrameBuffer); + } + + _getVaoKey(index, attributes) { + let key = []; + + if (index !== null) { + const indexData = this.get(index); + + key += ':' + indexData.id; + } + + for (let i = 0; i < attributes.length; i++) { + const attributeData = this.get(attributes[i]); + + key += ':' + attributeData.id; + } + + return key; + } + + _createVao(index, attributes) { + const { gl } = this; + + const vaoGPU = gl.createVertexArray(); + let key = ''; + + let staticVao = true; + + gl.bindVertexArray(vaoGPU); + + if (index !== null) { + const indexData = this.get(index); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU); + + key += ':' + indexData.id; + } + + for (let i = 0; i < attributes.length; i++) { + const attribute = attributes[i]; + const attributeData = this.get(attribute); + + key += ':' + attributeData.id; + + gl.bindBuffer(gl.ARRAY_BUFFER, attributeData.bufferGPU); + gl.enableVertexAttribArray(i); + + if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) staticVao = false; + + let stride, offset; + + if (attribute.isInterleavedBufferAttribute === true) { + stride = attribute.data.stride * attributeData.bytesPerElement; + offset = attribute.offset * attributeData.bytesPerElement; + } else { + stride = 0; + offset = 0; + } + + if (attributeData.isInteger) { + gl.vertexAttribIPointer(i, attribute.itemSize, attributeData.type, stride, offset); + } else { + gl.vertexAttribPointer(i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset); + } + + if (attribute.isInstancedBufferAttribute && !attribute.isInterleavedBufferAttribute) { + gl.vertexAttribDivisor(i, attribute.meshPerAttribute); + } else if (attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer) { + gl.vertexAttribDivisor(i, attribute.data.meshPerAttribute); + } + } + + gl.bindBuffer(gl.ARRAY_BUFFER, null); + + this.vaoCache[key] = vaoGPU; + + return { vaoGPU, staticVao }; + } + + _getTransformFeedback(transformBuffers) { + let key = ''; + + for (let i = 0; i < transformBuffers.length; i++) { + key += ':' + transformBuffers[i].id; + } + + let transformFeedbackGPU = this.transformFeedbackCache[key]; + + if (transformFeedbackGPU !== undefined) { + return transformFeedbackGPU; + } + + const gl = this.gl; + + transformFeedbackGPU = gl.createTransformFeedback(); + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); + + for (let i = 0; i < transformBuffers.length; i++) { + const attributeData = transformBuffers[i]; + + gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer); + } + + gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); + + this.transformFeedbackCache[key] = transformFeedbackGPU; + + return transformFeedbackGPU; + } + + _setupBindings(bindings, programGPU) { + const gl = this.gl; + + for (const bindGroup of bindings) { + for (const binding of bindGroup.bindings) { + const bindingData = this.get(binding); + const index = bindingData.index; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + const location = gl.getUniformBlockIndex(programGPU, binding.name); + gl.uniformBlockBinding(programGPU, location, index); + } else if (binding.isSampledTexture) { + const location = gl.getUniformLocation(programGPU, binding.name); + gl.uniform1i(location, index); + } + } + } + } + + _bindUniforms(bindings) { + const { gl, state } = this; + + for (const bindGroup of bindings) { + for (const binding of bindGroup.bindings) { + const bindingData = this.get(binding); + const index = bindingData.index; + + if (binding.isUniformsGroup || binding.isUniformBuffer) { + gl.bindBufferBase(gl.UNIFORM_BUFFER, index, bindingData.bufferGPU); + } else if (binding.isSampledTexture) { + state.bindTexture(bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index); + } + } + } + } +} + +export default WebGLBackend; diff --git a/examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts b/examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts new file mode 100644 index 000000000..816b83eaf --- /dev/null +++ b/examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts @@ -0,0 +1,747 @@ +import { MathNode, GLSLNodeParser, NodeBuilder, TextureNode, vectorComponents } from '../../../nodes/Nodes.js'; + +import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; +import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; + +import { + NodeSampledTexture, + NodeSampledCubeTexture, + NodeSampledTexture3D, +} from '../../common/nodes/NodeSampledTexture.js'; + +import { + ByteType, + ShortType, + RGBAIntegerFormat, + RGBIntegerFormat, + RedIntegerFormat, + RGIntegerFormat, + UnsignedByteType, + UnsignedIntType, + UnsignedShortType, + RedFormat, + RGFormat, + IntType, + DataTexture, + RGBFormat, + RGBAFormat, + FloatType, +} from 'three'; + +const glslMethods = { + [MathNode.ATAN2]: 'atan', + textureDimensions: 'textureSize', + equals: 'equal', +}; + +const precisionLib = { + low: 'lowp', + medium: 'mediump', + high: 'highp', +}; + +const supports = { + swizzleAssign: true, + storageBuffer: false, +}; + +const defaultPrecisions = ` +precision highp float; +precision highp int; +precision highp sampler2D; +precision highp sampler3D; +precision highp samplerCube; +precision highp sampler2DArray; + +precision highp usampler2D; +precision highp usampler3D; +precision highp usamplerCube; +precision highp usampler2DArray; + +precision highp isampler2D; +precision highp isampler3D; +precision highp isamplerCube; +precision highp isampler2DArray; + +precision lowp sampler2DShadow; +`; + +class GLSLNodeBuilder extends NodeBuilder { + constructor(object, renderer) { + super(object, renderer, new GLSLNodeParser()); + + this.uniformGroups = {}; + this.transforms = []; + + this.instanceBindGroups = false; + } + + getMethod(method) { + return glslMethods[method] || method; + } + + getOutputStructName() { + return ''; + } + + buildFunctionCode(shaderNode) { + const layout = shaderNode.layout; + const flowData = this.flowShaderNode(shaderNode); + + const parameters = []; + + for (const input of layout.inputs) { + parameters.push(this.getType(input.type) + ' ' + input.name); + } + + // + + const code = `${this.getType(layout.type)} ${layout.name}( ${parameters.join(', ')} ) { + + ${flowData.vars} + +${flowData.code} + return ${flowData.result}; + +}`; + + // + + return code; + } + + setupPBO(storageBufferNode) { + const attribute = storageBufferNode.value; + + if (attribute.pbo === undefined) { + const originalArray = attribute.array; + const numElements = attribute.count * attribute.itemSize; + + const { itemSize } = attribute; + + const isInteger = attribute.array.constructor.name.toLowerCase().includes('int'); + + let format = isInteger ? RedIntegerFormat : RedFormat; + + if (itemSize === 2) { + format = isInteger ? RGIntegerFormat : RGFormat; + } else if (itemSize === 3) { + format = isInteger ? RGBIntegerFormat : RGBFormat; + } else if (itemSize === 4) { + format = isInteger ? RGBAIntegerFormat : RGBAFormat; + } + + const typeMap = { + Float32Array: FloatType, + Uint8Array: UnsignedByteType, + Uint16Array: UnsignedShortType, + Uint32Array: UnsignedIntType, + Int8Array: ByteType, + Int16Array: ShortType, + Int32Array: IntType, + Uint8ClampedArray: UnsignedByteType, + }; + + const width = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(numElements / itemSize)))); + let height = Math.ceil(numElements / itemSize / width); + if (width * height * itemSize < numElements) height++; // Ensure enough space + + const newSize = width * height * itemSize; + + const newArray = new originalArray.constructor(newSize); + + newArray.set(originalArray, 0); + + attribute.array = newArray; + + const pboTexture = new DataTexture( + attribute.array, + width, + height, + format, + typeMap[attribute.array.constructor.name] || FloatType, + ); + pboTexture.needsUpdate = true; + pboTexture.isPBOTexture = true; + + const pbo = new TextureNode(pboTexture); + pbo.setPrecision('high'); + + attribute.pboNode = pbo; + attribute.pbo = pbo.value; + + this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); + } + } + + getPropertyName(node, shaderStage = this.shaderStage) { + if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) { + return shaderStage.charAt(0) + '_' + node.name; + } + + return super.getPropertyName(node, shaderStage); + } + + generatePBO(storageArrayElementNode) { + const { node, indexNode } = storageArrayElementNode; + const attribute = node.value; + + if (this.renderer.backend.has(attribute)) { + const attributeData = this.renderer.backend.get(attribute); + attributeData.pbo = attribute.pbo; + } + + const nodeUniform = this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); + const textureName = this.getPropertyName(nodeUniform); + + indexNode.increaseUsage(this); // force cache generate to be used as index in x,y + const indexSnippet = indexNode.build(this, 'uint'); + + const elementNodeData = this.getDataFromNode(storageArrayElementNode); + + let propertyName = elementNodeData.propertyName; + + if (propertyName === undefined) { + // property element + + const nodeVar = this.getVarFromNode(storageArrayElementNode); + + propertyName = this.getPropertyName(nodeVar); + + // property size + + const bufferNodeData = this.getDataFromNode(node); + + let propertySizeName = bufferNodeData.propertySizeName; + + if (propertySizeName === undefined) { + propertySizeName = propertyName + 'Size'; + + this.getVarFromNode(node, propertySizeName, 'uint'); + + this.addLineFlowCode(`${propertySizeName} = uint( textureSize( ${textureName}, 0 ).x )`); + + bufferNodeData.propertySizeName = propertySizeName; + } + + // + + const { itemSize } = attribute; + + const channel = '.' + vectorComponents.join('').slice(0, itemSize); + const uvSnippet = `ivec2(${indexSnippet} % ${propertySizeName}, ${indexSnippet} / ${propertySizeName})`; + + const snippet = this.generateTextureLoad(null, textureName, uvSnippet, null, '0'); + + // + + const typePrefix = attribute.array.constructor.name.toLowerCase().charAt(0); + + let prefix = 'vec4'; + if (typePrefix === 'u') { + prefix = 'uvec4'; + } else if (typePrefix === 'i') { + prefix = 'ivec4'; + } + + this.addLineFlowCode(`${propertyName} = ${prefix}(${snippet})${channel}`); + + elementNodeData.propertyName = propertyName; + } + + return propertyName; + } + + generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0') { + if (depthSnippet) { + return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`; + } else { + return `texelFetch( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; + } + } + + generateTexture(texture, textureProperty, uvSnippet, depthSnippet) { + if (texture.isDepthTexture) { + return `texture( ${textureProperty}, ${uvSnippet} ).x`; + } else { + if (depthSnippet) uvSnippet = `vec3( ${uvSnippet}, ${depthSnippet} )`; + + return `texture( ${textureProperty}, ${uvSnippet} )`; + } + } + + generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet) { + return `textureLod( ${textureProperty}, ${uvSnippet}, ${levelSnippet} )`; + } + + generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet) { + return `textureGrad( ${textureProperty}, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; + } + + generateTextureCompare( + texture, + textureProperty, + uvSnippet, + compareSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`; + } else { + console.error( + `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, + ); + } + } + + getVars(shaderStage) { + const snippets = []; + + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippets.push(`${this.getVar(variable.type, variable.name)};`); + } + } + + return snippets.join('\n\t'); + } + + getUniforms(shaderStage) { + const uniforms = this.uniforms[shaderStage]; + + const bindingSnippets = []; + const uniformGroups = {}; + + for (const uniform of uniforms) { + let snippet = null; + let group = false; + + if (uniform.type === 'texture') { + const texture = uniform.node.value; + + let typePrefix = ''; + + if (texture.isPBOTexture === true) { + const prefix = texture.source.data.data.constructor.name.toLowerCase().charAt(0); + + if (prefix === 'u' || prefix === 'i') { + typePrefix = prefix; + } + } + + if (texture.compareFunction) { + snippet = `sampler2DShadow ${uniform.name};`; + } else if (texture.isDataArrayTexture === true) { + snippet = `${typePrefix}sampler2DArray ${uniform.name};`; + } else { + snippet = `${typePrefix}sampler2D ${uniform.name};`; + } + } else if (uniform.type === 'cubeTexture') { + snippet = `samplerCube ${uniform.name};`; + } else if (uniform.type === 'texture3D') { + snippet = `sampler3D ${uniform.name};`; + } else if (uniform.type === 'buffer') { + const bufferNode = uniform.node; + const bufferType = this.getType(bufferNode.bufferType); + const bufferCount = bufferNode.bufferCount; + + const bufferCountSnippet = bufferCount > 0 ? bufferCount : ''; + snippet = `${bufferNode.name} {\n\t${bufferType} ${uniform.name}[${bufferCountSnippet}];\n};\n`; + } else { + const vectorType = this.getVectorType(uniform.type); + + snippet = `${vectorType} ${this.getPropertyName(uniform, shaderStage)};`; + + group = true; + } + + const precision = uniform.node.precision; + + if (precision !== null) { + snippet = precisionLib[precision] + ' ' + snippet; + } + + if (group) { + snippet = '\t' + snippet; + + const groupName = uniform.groupNode.name; + const groupSnippets = uniformGroups[groupName] || (uniformGroups[groupName] = []); + + groupSnippets.push(snippet); + } else { + snippet = 'uniform ' + snippet; + + bindingSnippets.push(snippet); + } + } + + let output = ''; + + for (const name in uniformGroups) { + const groupSnippets = uniformGroups[name]; + + output += this._getGLSLUniformStruct(shaderStage + '_' + name, groupSnippets.join('\n')) + '\n'; + } + + output += bindingSnippets.join('\n'); + + return output; + } + + getTypeFromAttribute(attribute) { + let nodeType = super.getTypeFromAttribute(attribute); + + if (/^[iu]/.test(nodeType) && attribute.gpuType !== IntType) { + let dataAttribute = attribute; + + if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; + + const array = dataAttribute.array; + + if ( + (array instanceof Uint32Array || + array instanceof Int32Array || + array instanceof Uint16Array || + array instanceof Int16Array) === false + ) { + nodeType = nodeType.slice(1); + } + } + + return nodeType; + } + + getAttributes(shaderStage) { + let snippet = ''; + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + const attributes = this.getAttributesArray(); + + let location = 0; + + for (const attribute of attributes) { + snippet += `layout( location = ${location++} ) in ${attribute.type} ${attribute.name};\n`; + } + } + + return snippet; + } + + getStructMembers(struct) { + const snippets = []; + const members = struct.getMemberTypes(); + + for (let i = 0; i < members.length; i++) { + const member = members[i]; + snippets.push(`layout( location = ${i} ) out ${member} m${i};`); + } + + return snippets.join('\n'); + } + + getStructs(shaderStage) { + const snippets = []; + const structs = this.structs[shaderStage]; + + if (structs.length === 0) { + return 'layout( location = 0 ) out vec4 fragColor;\n'; + } + + for (let index = 0, length = structs.length; index < length; index++) { + const struct = structs[index]; + + let snippet = '\n'; + snippet += this.getStructMembers(struct); + snippet += '\n'; + + snippets.push(snippet); + } + + return snippets.join('\n\n'); + } + + getVaryings(shaderStage) { + let snippet = ''; + + const varyings = this.varyings; + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + for (const varying of varyings) { + if (shaderStage === 'compute') varying.needsInterpolation = true; + const type = varying.type; + const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; + + snippet += `${flat}${varying.needsInterpolation ? 'out' : '/*out*/'} ${type} ${varying.name};\n`; + } + } else if (shaderStage === 'fragment') { + for (const varying of varyings) { + if (varying.needsInterpolation) { + const type = varying.type; + const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; + + snippet += `${flat}in ${type} ${varying.name};\n`; + } + } + } + + return snippet; + } + + getVertexIndex() { + return 'uint( gl_VertexID )'; + } + + getInstanceIndex() { + return 'uint( gl_InstanceID )'; + } + + getFrontFacing() { + return 'gl_FrontFacing'; + } + + getFragCoord() { + return 'gl_FragCoord'; + } + + getFragDepth() { + return 'gl_FragDepth'; + } + + isAvailable(name) { + let result = supports[name]; + + if (result === undefined) { + if (name === 'float32Filterable') { + const extentions = this.renderer.backend.extensions; + + if (extentions.has('OES_texture_float_linear')) { + extentions.get('OES_texture_float_linear'); + result = true; + } else { + result = false; + } + } + + supports[name] = result; + } + + return result; + } + + isFlipY() { + return true; + } + + registerTransform(varyingName, attributeNode) { + this.transforms.push({ varyingName, attributeNode }); + } + + getTransforms(/* shaderStage */) { + const transforms = this.transforms; + + let snippet = ''; + + for (let i = 0; i < transforms.length; i++) { + const transform = transforms[i]; + + const attributeName = this.getPropertyName(transform.attributeNode); + + snippet += `${transform.varyingName} = ${attributeName};\n\t`; + } + + return snippet; + } + + _getGLSLUniformStruct(name, vars) { + return ` +layout( std140 ) uniform ${name} { +${vars} +};`; + } + + _getGLSLVertexCode(shaderData) { + return `#version 300 es + +${this.getSignature()} + +// precision +${defaultPrecisions} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} + +// attributes +${shaderData.attributes} + +// codes +${shaderData.codes} + +void main() { + + // vars + ${shaderData.vars} + + // transforms + ${shaderData.transforms} + + // flow + ${shaderData.flow} + + gl_PointSize = 1.0; + +} +`; + } + + _getGLSLFragmentCode(shaderData) { + return `#version 300 es + +${this.getSignature()} + +// precision +${defaultPrecisions} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} + +// codes +${shaderData.codes} + +${shaderData.structs} + +void main() { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + buildCode() { + const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; + + for (const shaderStage in shadersData) { + let flow = '// code\n\n'; + flow += this.flowCode[shaderStage]; + + const flowNodes = this.flowNodes[shaderStage]; + const mainNode = flowNodes[flowNodes.length - 1]; + + for (const node of flowNodes) { + const flowSlotData = this.getFlowData(node /*, shaderStage*/); + const slotName = node.name; + + if (slotName) { + if (flow.length > 0) flow += '\n'; + + flow += `\t// flow -> ${slotName}\n\t`; + } + + flow += `${flowSlotData.code}\n\t`; + + if (node === mainNode && shaderStage !== 'compute') { + flow += '// result\n\t'; + + if (shaderStage === 'vertex') { + flow += 'gl_Position = '; + flow += `${flowSlotData.result};`; + } else if (shaderStage === 'fragment') { + if (!node.outputNode.isOutputStructNode) { + flow += 'fragColor = '; + flow += `${flowSlotData.result};`; + } + } + } + } + + const stageData = shadersData[shaderStage]; + + stageData.uniforms = this.getUniforms(shaderStage); + stageData.attributes = this.getAttributes(shaderStage); + stageData.varyings = this.getVaryings(shaderStage); + stageData.vars = this.getVars(shaderStage); + stageData.structs = this.getStructs(shaderStage); + stageData.codes = this.getCodes(shaderStage); + stageData.transforms = this.getTransforms(shaderStage); + stageData.flow = flow; + } + + if (this.material !== null) { + this.vertexShader = this._getGLSLVertexCode(shadersData.vertex); + this.fragmentShader = this._getGLSLFragmentCode(shadersData.fragment); + } else { + this.computeShader = this._getGLSLVertexCode(shadersData.compute); + } + } + + getUniformFromNode(node, type, shaderStage, name = null) { + const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + let uniformGPU = nodeData.uniformGPU; + + if (uniformGPU === undefined) { + const group = node.groupNode; + const groupName = group.name; + + const bindings = this.getBindGroupArray(groupName, shaderStage); + + if (type === 'texture') { + uniformGPU = new NodeSampledTexture(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'cubeTexture') { + uniformGPU = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'texture3D') { + uniformGPU = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group); + bindings.push(uniformGPU); + } else if (type === 'buffer') { + node.name = `NodeBuffer_${node.id}`; + uniformNode.name = `buffer${node.id}`; + + const buffer = new NodeUniformBuffer(node, group); + buffer.name = node.name; + + bindings.push(buffer); + + uniformGPU = buffer; + } else { + const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); + + let uniformsGroup = uniformsStage[groupName]; + + if (uniformsGroup === undefined) { + uniformsGroup = new NodeUniformsGroup(shaderStage + '_' + groupName, group); + //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); + + uniformsStage[groupName] = uniformsGroup; + + bindings.push(uniformsGroup); + } + + uniformGPU = this.getNodeUniform(uniformNode, type); + + uniformsGroup.addUniform(uniformGPU); + } + + nodeData.uniformGPU = uniformGPU; + } + + return uniformNode; + } +} + +export default GLSLNodeBuilder; diff --git a/examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts b/examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts new file mode 100644 index 000000000..a5c38c170 --- /dev/null +++ b/examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts @@ -0,0 +1,1205 @@ +/*// debugger tools +import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js'; +//*/ + +import { WebGPUCoordinateSystem } from 'three'; + +import { + GPUFeatureName, + GPUTextureFormat, + GPULoadOp, + GPUStoreOp, + GPUIndexFormat, + GPUTextureViewDimension, +} from './utils/WebGPUConstants.js'; + +import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js'; +import Backend from '../common/Backend.js'; + +import WebGPUUtils from './utils/WebGPUUtils.js'; +import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js'; +import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; +import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; +import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; + +// + +class WebGPUBackend extends Backend { + constructor(parameters = {}) { + super(parameters); + + this.isWebGPUBackend = true; + + // some parameters require default values other than "undefined" + this.parameters.alpha = parameters.alpha === undefined ? true : parameters.alpha; + + this.parameters.antialias = parameters.antialias === true; + + if (this.parameters.antialias === true) { + this.parameters.sampleCount = parameters.sampleCount === undefined ? 4 : parameters.sampleCount; + } else { + this.parameters.sampleCount = 1; + } + + this.parameters.requiredLimits = parameters.requiredLimits === undefined ? {} : parameters.requiredLimits; + + this.trackTimestamp = parameters.trackTimestamp === true; + + this.device = null; + this.context = null; + this.colorBuffer = null; + this.defaultRenderPassdescriptor = null; + + this.utils = new WebGPUUtils(this); + this.attributeUtils = new WebGPUAttributeUtils(this); + this.bindingUtils = new WebGPUBindingUtils(this); + this.pipelineUtils = new WebGPUPipelineUtils(this); + this.textureUtils = new WebGPUTextureUtils(this); + this.occludedResolveCache = new Map(); + } + + async init(renderer) { + await super.init(renderer); + + // + + const parameters = this.parameters; + + // create the device if it is not passed with parameters + + let device; + + if (parameters.device === undefined) { + const adapterOptions = { + powerPreference: parameters.powerPreference, + }; + + const adapter = await navigator.gpu.requestAdapter(adapterOptions); + + if (adapter === null) { + throw new Error('WebGPUBackend: Unable to create WebGPU adapter.'); + } + + // feature support + + const features = Object.values(GPUFeatureName); + + const supportedFeatures = []; + + for (const name of features) { + if (adapter.features.has(name)) { + supportedFeatures.push(name); + } + } + + const deviceDescriptor = { + requiredFeatures: supportedFeatures, + requiredLimits: parameters.requiredLimits, + }; + + device = await adapter.requestDevice(deviceDescriptor); + } else { + device = parameters.device; + } + + const context = + parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgpu'); + + this.device = device; + this.context = context; + + const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque'; + + this.context.configure({ + device: this.device, + format: GPUTextureFormat.BGRA8Unorm, + usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, + alphaMode: alphaMode, + }); + + this.updateSize(); + } + + get coordinateSystem() { + return WebGPUCoordinateSystem; + } + + async getArrayBufferAsync(attribute) { + return await this.attributeUtils.getArrayBufferAsync(attribute); + } + + getContext() { + return this.context; + } + + _getDefaultRenderPassDescriptor() { + let descriptor = this.defaultRenderPassdescriptor; + + const antialias = this.parameters.antialias; + + if (descriptor === null) { + const renderer = this.renderer; + + descriptor = { + colorAttachments: [ + { + view: null, + }, + ], + depthStencilAttachment: { + view: this.textureUtils.getDepthBuffer(renderer.depth, renderer.stencil).createView(), + }, + }; + + const colorAttachment = descriptor.colorAttachments[0]; + + if (antialias === true) { + colorAttachment.view = this.colorBuffer.createView(); + } else { + colorAttachment.resolveTarget = undefined; + } + + this.defaultRenderPassdescriptor = descriptor; + } + + const colorAttachment = descriptor.colorAttachments[0]; + + if (antialias === true) { + colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); + } else { + colorAttachment.view = this.context.getCurrentTexture().createView(); + } + + return descriptor; + } + + _getRenderPassDescriptor(renderContext) { + const renderTarget = renderContext.renderTarget; + const renderTargetData = this.get(renderTarget); + + let descriptors = renderTargetData.descriptors; + + if (descriptors === undefined) { + descriptors = []; + + renderTargetData.descriptors = descriptors; + } + + if ( + renderTargetData.width !== renderTarget.width || + renderTargetData.height !== renderTarget.height || + renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel || + renderTargetData.samples !== renderTarget.samples + ) { + descriptors.length = 0; + } + + let descriptor = descriptors[renderContext.activeCubeFace]; + + if (descriptor === undefined) { + const textures = renderContext.textures; + const colorAttachments = []; + + for (let i = 0; i < textures.length; i++) { + const textureData = this.get(textures[i]); + + const textureView = textureData.texture.createView({ + baseMipLevel: renderContext.activeMipmapLevel, + mipLevelCount: 1, + baseArrayLayer: renderContext.activeCubeFace, + dimension: GPUTextureViewDimension.TwoD, + }); + + let view, resolveTarget; + + if (textureData.msaaTexture !== undefined) { + view = textureData.msaaTexture.createView(); + resolveTarget = textureView; + } else { + view = textureView; + resolveTarget = undefined; + } + + colorAttachments.push({ + view, + resolveTarget, + loadOp: GPULoadOp.Load, + storeOp: GPUStoreOp.Store, + }); + } + + const depthTextureData = this.get(renderContext.depthTexture); + + const depthStencilAttachment = { + view: depthTextureData.texture.createView(), + }; + + descriptor = { + colorAttachments, + depthStencilAttachment, + }; + + descriptors[renderContext.activeCubeFace] = descriptor; + + renderTargetData.width = renderTarget.width; + renderTargetData.height = renderTarget.height; + renderTargetData.samples = renderTarget.samples; + renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel; + } + + return descriptor; + } + + beginRender(renderContext) { + const renderContextData = this.get(renderContext); + + const device = this.device; + const occlusionQueryCount = renderContext.occlusionQueryCount; + + let occlusionQuerySet; + + if (occlusionQueryCount > 0) { + if (renderContextData.currentOcclusionQuerySet) renderContextData.currentOcclusionQuerySet.destroy(); + if (renderContextData.currentOcclusionQueryBuffer) renderContextData.currentOcclusionQueryBuffer.destroy(); + + // Get a reference to the array of objects with queries. The renderContextData property + // can be changed by another render pass before the buffer.mapAsyc() completes. + renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet; + renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer; + renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; + + // + + occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: occlusionQueryCount }); + + renderContextData.occlusionQuerySet = occlusionQuerySet; + renderContextData.occlusionQueryIndex = 0; + renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); + + renderContextData.lastOcclusionObject = null; + } + + let descriptor; + + if (renderContext.textures === null) { + descriptor = this._getDefaultRenderPassDescriptor(); + } else { + descriptor = this._getRenderPassDescriptor(renderContext); + } + + this.initTimestampQuery(renderContext, descriptor); + + descriptor.occlusionQuerySet = occlusionQuerySet; + + const depthStencilAttachment = descriptor.depthStencilAttachment; + + if (renderContext.textures !== null) { + const colorAttachments = descriptor.colorAttachments; + + for (let i = 0; i < colorAttachments.length; i++) { + const colorAttachment = colorAttachments[i]; + + if (renderContext.clearColor) { + colorAttachment.clearValue = renderContext.clearColorValue; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } else { + colorAttachment.loadOp = GPULoadOp.Load; + colorAttachment.storeOp = GPUStoreOp.Store; + } + } + } else { + const colorAttachment = descriptor.colorAttachments[0]; + + if (renderContext.clearColor) { + colorAttachment.clearValue = renderContext.clearColorValue; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } else { + colorAttachment.loadOp = GPULoadOp.Load; + colorAttachment.storeOp = GPUStoreOp.Store; + } + } + + // + + if (renderContext.depth) { + if (renderContext.clearDepth) { + depthStencilAttachment.depthClearValue = renderContext.clearDepthValue; + depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } + } + + if (renderContext.stencil) { + if (renderContext.clearStencil) { + depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue; + depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } + } + + // + + const encoder = device.createCommandEncoder({ label: 'renderContext_' + renderContext.id }); + const currentPass = encoder.beginRenderPass(descriptor); + + // + + renderContextData.descriptor = descriptor; + renderContextData.encoder = encoder; + renderContextData.currentPass = currentPass; + renderContextData.currentSets = { attributes: {} }; + + // + + if (renderContext.viewport) { + this.updateViewport(renderContext); + } + + if (renderContext.scissor) { + const { x, y, width, height } = renderContext.scissorValue; + + currentPass.setScissorRect(x, renderContext.height - height - y, width, height); + } + } + + finishRender(renderContext) { + const renderContextData = this.get(renderContext); + const occlusionQueryCount = renderContext.occlusionQueryCount; + + if (renderContextData.renderBundles !== undefined && renderContextData.renderBundles.length > 0) { + renderContextData.registerBundlesPhase = false; + renderContextData.currentPass.executeBundles(renderContextData.renderBundles); + } + + if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { + renderContextData.currentPass.endOcclusionQuery(); + } + + renderContextData.currentPass.end(); + + if (occlusionQueryCount > 0) { + const bufferSize = occlusionQueryCount * 8; // 8 byte entries for query results + + // + + let queryResolveBuffer = this.occludedResolveCache.get(bufferSize); + + if (queryResolveBuffer === undefined) { + queryResolveBuffer = this.device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, + }); + + this.occludedResolveCache.set(bufferSize, queryResolveBuffer); + } + + // + + const readBuffer = this.device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }); + + // two buffers required here - WebGPU doesn't allow usage of QUERY_RESOLVE & MAP_READ to be combined + renderContextData.encoder.resolveQuerySet( + renderContextData.occlusionQuerySet, + 0, + occlusionQueryCount, + queryResolveBuffer, + 0, + ); + renderContextData.encoder.copyBufferToBuffer(queryResolveBuffer, 0, readBuffer, 0, bufferSize); + + renderContextData.occlusionQueryBuffer = readBuffer; + + // + + this.resolveOccludedAsync(renderContext); + } + + this.prepareTimestampBuffer(renderContext, renderContextData.encoder); + + this.device.queue.submit([renderContextData.encoder.finish()]); + + // + + if (renderContext.textures !== null) { + const textures = renderContext.textures; + + for (let i = 0; i < textures.length; i++) { + const texture = textures[i]; + + if (texture.generateMipmaps === true) { + this.textureUtils.generateMipmaps(texture); + } + } + } + } + + isOccluded(renderContext, object) { + const renderContextData = this.get(renderContext); + + return renderContextData.occluded && renderContextData.occluded.has(object); + } + + async resolveOccludedAsync(renderContext) { + const renderContextData = this.get(renderContext); + + // handle occlusion query results + + const { currentOcclusionQueryBuffer, currentOcclusionQueryObjects } = renderContextData; + + if (currentOcclusionQueryBuffer && currentOcclusionQueryObjects) { + const occluded = new WeakSet(); + + renderContextData.currentOcclusionQueryObjects = null; + renderContextData.currentOcclusionQueryBuffer = null; + + await currentOcclusionQueryBuffer.mapAsync(GPUMapMode.READ); + + const buffer = currentOcclusionQueryBuffer.getMappedRange(); + const results = new BigUint64Array(buffer); + + for (let i = 0; i < currentOcclusionQueryObjects.length; i++) { + if (results[i] !== 0n) { + occluded.add(currentOcclusionQueryObjects[i]); + } + } + + currentOcclusionQueryBuffer.destroy(); + + renderContextData.occluded = occluded; + } + } + + updateViewport(renderContext) { + const { currentPass } = this.get(renderContext); + const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue; + + currentPass.setViewport(x, renderContext.height - height - y, width, height, minDepth, maxDepth); + } + + clear(color, depth, stencil, renderTargetData = null) { + const device = this.device; + const renderer = this.renderer; + + let colorAttachments = []; + + let depthStencilAttachment; + let clearValue; + + let supportsDepth; + let supportsStencil; + + if (color) { + const clearColor = this.getClearColor(); + + clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a }; + } + + if (renderTargetData === null) { + supportsDepth = renderer.depth; + supportsStencil = renderer.stencil; + + const descriptor = this._getDefaultRenderPassDescriptor(); + + if (color) { + colorAttachments = descriptor.colorAttachments; + + const colorAttachment = colorAttachments[0]; + + colorAttachment.clearValue = clearValue; + colorAttachment.loadOp = GPULoadOp.Clear; + colorAttachment.storeOp = GPUStoreOp.Store; + } + + if (supportsDepth || supportsStencil) { + depthStencilAttachment = descriptor.depthStencilAttachment; + } + } else { + supportsDepth = renderTargetData.depth; + supportsStencil = renderTargetData.stencil; + + if (color) { + for (const texture of renderTargetData.textures) { + const textureData = this.get(texture); + const textureView = textureData.texture.createView(); + + let view, resolveTarget; + + if (textureData.msaaTexture !== undefined) { + view = textureData.msaaTexture.createView(); + resolveTarget = textureView; + } else { + view = textureView; + resolveTarget = undefined; + } + + colorAttachments.push({ + view, + resolveTarget, + clearValue, + loadOp: GPULoadOp.Clear, + storeOp: GPUStoreOp.Store, + }); + } + } + + if (supportsDepth || supportsStencil) { + const depthTextureData = this.get(renderTargetData.depthTexture); + + depthStencilAttachment = { + view: depthTextureData.texture.createView(), + }; + } + } + + // + + if (supportsDepth) { + if (depth) { + depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; + depthStencilAttachment.depthClearValue = renderer.getClearDepth(); + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; + } + } + + // + + if (supportsStencil) { + if (stencil) { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; + depthStencilAttachment.stencilClearValue = renderer.getClearStencil(); + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } else { + depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; + } + } + + // + + const encoder = device.createCommandEncoder({}); + const currentPass = encoder.beginRenderPass({ + colorAttachments, + depthStencilAttachment, + }); + + currentPass.end(); + + device.queue.submit([encoder.finish()]); + } + + // compute + + beginCompute(computeGroup) { + const groupGPU = this.get(computeGroup); + + const descriptor = {}; + + this.initTimestampQuery(computeGroup, descriptor); + + groupGPU.cmdEncoderGPU = this.device.createCommandEncoder(); + + groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass(descriptor); + } + + compute(computeGroup, computeNode, bindings, pipeline) { + const { passEncoderGPU } = this.get(computeGroup); + + // pipeline + + const pipelineGPU = this.get(pipeline).pipeline; + passEncoderGPU.setPipeline(pipelineGPU); + + // bind groups + + for (let i = 0, l = bindings.length; i < l; i++) { + const bindGroup = bindings[i]; + const bindingsData = this.get(bindGroup); + + passEncoderGPU.setBindGroup(i, bindingsData.group); + } + + passEncoderGPU.dispatchWorkgroups(computeNode.dispatchCount); + } + + finishCompute(computeGroup) { + const groupData = this.get(computeGroup); + + groupData.passEncoderGPU.end(); + + this.prepareTimestampBuffer(computeGroup, groupData.cmdEncoderGPU); + + this.device.queue.submit([groupData.cmdEncoderGPU.finish()]); + } + + // render object + + draw(renderObject, info) { + const { object, geometry, context, pipeline } = renderObject; + + const bindings = renderObject.getBindings(); + const contextData = this.get(context); + const pipelineGPU = this.get(pipeline).pipeline; + const currentSets = contextData.currentSets; + + const renderObjectData = this.get(renderObject); + + const { bundleEncoder, renderBundle, lastPipelineGPU } = renderObjectData; + + const renderContextData = this.get(context); + + if ( + renderContextData.registerBundlesPhase === true && + bundleEncoder !== undefined && + lastPipelineGPU === pipelineGPU + ) { + renderContextData.renderBundles.push(renderBundle); + return; + } + + const passEncoderGPU = this.renderer._currentRenderBundle + ? this.createBundleEncoder(context, renderObject) + : contextData.currentPass; + + // pipeline + + if (currentSets.pipeline !== pipelineGPU) { + passEncoderGPU.setPipeline(pipelineGPU); + + currentSets.pipeline = pipelineGPU; + } + + // bind groups + + for (let i = 0, l = bindings.length; i < l; i++) { + const bindGroup = bindings[i]; + const bindingsData = this.get(bindGroup); + + passEncoderGPU.setBindGroup(i, bindingsData.group); + } + + // attributes + + const index = renderObject.getIndex(); + + const hasIndex = index !== null; + + // index + + if (hasIndex === true) { + if (currentSets.index !== index) { + const buffer = this.get(index).buffer; + const indexFormat = index.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; + + passEncoderGPU.setIndexBuffer(buffer, indexFormat); + + currentSets.index = index; + } + } + + // vertex buffers + + const vertexBuffers = renderObject.getVertexBuffers(); + + for (let i = 0, l = vertexBuffers.length; i < l; i++) { + const vertexBuffer = vertexBuffers[i]; + + if (currentSets.attributes[i] !== vertexBuffer) { + const buffer = this.get(vertexBuffer).buffer; + passEncoderGPU.setVertexBuffer(i, buffer); + + currentSets.attributes[i] = vertexBuffer; + } + } + + // occlusion queries - handle multiple consecutive draw calls for an object + + if (contextData.occlusionQuerySet !== undefined) { + const lastObject = contextData.lastOcclusionObject; + + if (lastObject !== object) { + if (lastObject !== null && lastObject.occlusionTest === true) { + passEncoderGPU.endOcclusionQuery(); + contextData.occlusionQueryIndex++; + } + + if (object.occlusionTest === true) { + passEncoderGPU.beginOcclusionQuery(contextData.occlusionQueryIndex); + contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; + } + + contextData.lastOcclusionObject = object; + } + } + + // draw + + const drawRange = renderObject.drawRange; + const firstVertex = drawRange.start; + + const instanceCount = this.getInstanceCount(renderObject); + if (instanceCount === 0) return; + + if (hasIndex === true) { + const indexCount = drawRange.count !== Infinity ? drawRange.count : index.count; + + passEncoderGPU.drawIndexed(indexCount, instanceCount, firstVertex, 0, 0); + + info.update(object, indexCount, instanceCount); + } else { + const positionAttribute = geometry.attributes.position; + const vertexCount = drawRange.count !== Infinity ? drawRange.count : positionAttribute.count; + + passEncoderGPU.draw(vertexCount, instanceCount, firstVertex, 0); + + info.update(object, vertexCount, instanceCount); + } + + if (this.renderer._currentRenderBundle) { + const renderBundle = passEncoderGPU.finish(); + renderObjectData.lastPipelineGPU = pipelineGPU; + renderObjectData.renderBundle = renderBundle; + renderObjectData.bundleEncoder = passEncoderGPU; + } + } + + // cache key + + needsRenderUpdate(renderObject) { + const data = this.get(renderObject); + + const { object, material } = renderObject; + + const utils = this.utils; + + const sampleCount = utils.getSampleCount(renderObject.context); + const colorSpace = utils.getCurrentColorSpace(renderObject.context); + const colorFormat = utils.getCurrentColorFormat(renderObject.context); + const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); + const primitiveTopology = utils.getPrimitiveTopology(object, material); + + let needsUpdate = false; + + if ( + data.material !== material || + data.materialVersion !== material.version || + data.transparent !== material.transparent || + data.blending !== material.blending || + data.premultipliedAlpha !== material.premultipliedAlpha || + data.blendSrc !== material.blendSrc || + data.blendDst !== material.blendDst || + data.blendEquation !== material.blendEquation || + data.blendSrcAlpha !== material.blendSrcAlpha || + data.blendDstAlpha !== material.blendDstAlpha || + data.blendEquationAlpha !== material.blendEquationAlpha || + data.colorWrite !== material.colorWrite || + data.depthWrite !== material.depthWrite || + data.depthTest !== material.depthTest || + data.depthFunc !== material.depthFunc || + data.stencilWrite !== material.stencilWrite || + data.stencilFunc !== material.stencilFunc || + data.stencilFail !== material.stencilFail || + data.stencilZFail !== material.stencilZFail || + data.stencilZPass !== material.stencilZPass || + data.stencilFuncMask !== material.stencilFuncMask || + data.stencilWriteMask !== material.stencilWriteMask || + data.side !== material.side || + data.alphaToCoverage !== material.alphaToCoverage || + data.sampleCount !== sampleCount || + data.colorSpace !== colorSpace || + data.colorFormat !== colorFormat || + data.depthStencilFormat !== depthStencilFormat || + data.primitiveTopology !== primitiveTopology || + data.clippingContextVersion !== renderObject.clippingContextVersion + ) { + data.material = material; + data.materialVersion = material.version; + data.transparent = material.transparent; + data.blending = material.blending; + data.premultipliedAlpha = material.premultipliedAlpha; + data.blendSrc = material.blendSrc; + data.blendDst = material.blendDst; + data.blendEquation = material.blendEquation; + data.blendSrcAlpha = material.blendSrcAlpha; + data.blendDstAlpha = material.blendDstAlpha; + data.blendEquationAlpha = material.blendEquationAlpha; + data.colorWrite = material.colorWrite; + data.depthWrite = material.depthWrite; + data.depthTest = material.depthTest; + data.depthFunc = material.depthFunc; + data.stencilWrite = material.stencilWrite; + data.stencilFunc = material.stencilFunc; + data.stencilFail = material.stencilFail; + data.stencilZFail = material.stencilZFail; + data.stencilZPass = material.stencilZPass; + data.stencilFuncMask = material.stencilFuncMask; + data.stencilWriteMask = material.stencilWriteMask; + data.side = material.side; + data.alphaToCoverage = material.alphaToCoverage; + data.sampleCount = sampleCount; + data.colorSpace = colorSpace; + data.colorFormat = colorFormat; + data.depthStencilFormat = depthStencilFormat; + data.primitiveTopology = primitiveTopology; + data.clippingContextVersion = renderObject.clippingContextVersion; + + needsUpdate = true; + } + + return needsUpdate; + } + + getRenderCacheKey(renderObject) { + const { object, material } = renderObject; + + const utils = this.utils; + const renderContext = renderObject.context; + + return [ + material.transparent, + material.blending, + material.premultipliedAlpha, + material.blendSrc, + material.blendDst, + material.blendEquation, + material.blendSrcAlpha, + material.blendDstAlpha, + material.blendEquationAlpha, + material.colorWrite, + material.depthWrite, + material.depthTest, + material.depthFunc, + material.stencilWrite, + material.stencilFunc, + material.stencilFail, + material.stencilZFail, + material.stencilZPass, + material.stencilFuncMask, + material.stencilWriteMask, + material.side, + utils.getSampleCount(renderContext), + utils.getCurrentColorSpace(renderContext), + utils.getCurrentColorFormat(renderContext), + utils.getCurrentDepthStencilFormat(renderContext), + utils.getPrimitiveTopology(object, material), + renderObject.clippingContextVersion, + ].join(); + } + + // textures + + createSampler(texture) { + this.textureUtils.createSampler(texture); + } + + destroySampler(texture) { + this.textureUtils.destroySampler(texture); + } + + createDefaultTexture(texture) { + this.textureUtils.createDefaultTexture(texture); + } + + createTexture(texture, options) { + this.textureUtils.createTexture(texture, options); + } + + updateTexture(texture, options) { + this.textureUtils.updateTexture(texture, options); + } + + generateMipmaps(texture) { + this.textureUtils.generateMipmaps(texture); + } + + destroyTexture(texture) { + this.textureUtils.destroyTexture(texture); + } + + copyTextureToBuffer(texture, x, y, width, height) { + return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height); + } + + initTimestampQuery(renderContext, descriptor) { + if (!this.hasFeature(GPUFeatureName.TimestampQuery) || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (!renderContextData.timeStampQuerySet) { + // Create a GPUQuerySet which holds 2 timestamp query results: one for the + // beginning and one for the end of compute pass execution. + const timeStampQuerySet = this.device.createQuerySet({ type: 'timestamp', count: 2 }); + + const timestampWrites = { + querySet: timeStampQuerySet, + beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins. + endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends. + }; + + Object.assign(descriptor, { + timestampWrites, + }); + + renderContextData.timeStampQuerySet = timeStampQuerySet; + } + } + + // timestamp utils + + prepareTimestampBuffer(renderContext, encoder) { + if (!this.hasFeature(GPUFeatureName.TimestampQuery) || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; + + if (renderContextData.currentTimestampQueryBuffers === undefined) { + renderContextData.currentTimestampQueryBuffers = { + resolveBuffer: this.device.createBuffer({ + label: 'timestamp resolve buffer', + size: size, + usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, + }), + resultBuffer: this.device.createBuffer({ + label: 'timestamp result buffer', + size: size, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }), + isMappingPending: false, + }; + } + + const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + + if (isMappingPending === true) return; + + encoder.resolveQuerySet(renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0); + encoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size); + } + + async resolveTimestampAsync(renderContext, type = 'render') { + if (!this.hasFeature(GPUFeatureName.TimestampQuery) || !this.trackTimestamp) return; + + const renderContextData = this.get(renderContext); + + if (renderContextData.currentTimestampQueryBuffers === undefined) return; + + const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; + + if (isMappingPending === true) return; + + renderContextData.currentTimestampQueryBuffers.isMappingPending = true; + + resultBuffer.mapAsync(GPUMapMode.READ).then(() => { + const times = new BigUint64Array(resultBuffer.getMappedRange()); + const duration = Number(times[1] - times[0]) / 1000000; + + this.renderer.info.updateTimestamp(type, duration); + + resultBuffer.unmap(); + + renderContextData.currentTimestampQueryBuffers.isMappingPending = false; + }); + } + + // node builder + + createNodeBuilder(object, renderer) { + return new WGSLNodeBuilder(object, renderer); + } + + // program + + createProgram(program) { + const programGPU = this.get(program); + + programGPU.module = { + module: this.device.createShaderModule({ code: program.code, label: program.stage }), + entryPoint: 'main', + }; + } + + destroyProgram(program) { + this.delete(program); + } + + // pipelines + + createRenderPipeline(renderObject, promises) { + this.pipelineUtils.createRenderPipeline(renderObject, promises); + } + + createComputePipeline(computePipeline, bindings) { + this.pipelineUtils.createComputePipeline(computePipeline, bindings); + } + + createBundleEncoder(renderContext, renderObject) { + return this.pipelineUtils.createBundleEncoder(renderContext, renderObject); + } + + // bindings + + createBindings(bindGroup) { + this.bindingUtils.createBindings(bindGroup); + } + + updateBindings(bindGroup) { + this.bindingUtils.createBindings(bindGroup); + } + + updateBinding(binding) { + this.bindingUtils.updateBinding(binding); + } + + // attributes + + createIndexAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + createStorageAttribute(attribute) { + this.attributeUtils.createAttribute( + attribute, + GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, + ); + } + + updateAttribute(attribute) { + this.attributeUtils.updateAttribute(attribute); + } + + destroyAttribute(attribute) { + this.attributeUtils.destroyAttribute(attribute); + } + + // canvas + + updateSize() { + this.colorBuffer = this.textureUtils.getColorBuffer(); + this.defaultRenderPassdescriptor = null; + } + + // utils public + + getMaxAnisotropy() { + return 16; + } + + hasFeature(name) { + return this.device.features.has(name); + } + + copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { + let dstX = 0; + let dstY = 0; + + if (dstPosition !== null) { + dstX = dstPosition.x; + dstY = dstPosition.y; + } + + const encoder = this.device.createCommandEncoder({ + label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id, + }); + + const sourceGPU = this.get(srcTexture).texture; + const destinationGPU = this.get(dstTexture).texture; + + encoder.copyTextureToTexture( + { + texture: sourceGPU, + mipLevel: level, + origin: { x: 0, y: 0, z: 0 }, + }, + { + texture: destinationGPU, + mipLevel: level, + origin: { x: dstX, y: dstY, z: 0 }, + }, + [srcTexture.image.width, srcTexture.image.height], + ); + + this.device.queue.submit([encoder.finish()]); + } + + copyFramebufferToTexture(texture, renderContext) { + const renderContextData = this.get(renderContext); + + const { encoder, descriptor } = renderContextData; + + let sourceGPU = null; + + if (renderContext.renderTarget) { + if (texture.isDepthTexture) { + sourceGPU = this.get(renderContext.depthTexture).texture; + } else { + sourceGPU = this.get(renderContext.textures[0]).texture; + } + } else { + if (texture.isDepthTexture) { + sourceGPU = this.textureUtils.getDepthBuffer(renderContext.depth, renderContext.stencil); + } else { + sourceGPU = this.context.getCurrentTexture(); + } + } + + const destinationGPU = this.get(texture).texture; + + if (sourceGPU.format !== destinationGPU.format) { + console.error( + 'WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.', + sourceGPU.format, + destinationGPU.format, + ); + + return; + } + + renderContextData.currentPass.end(); + + encoder.copyTextureToTexture( + { + texture: sourceGPU, + origin: { x: 0, y: 0, z: 0 }, + }, + { + texture: destinationGPU, + }, + [texture.image.width, texture.image.height], + ); + + if (texture.generateMipmaps) this.textureUtils.generateMipmaps(texture); + + descriptor.colorAttachments[0].loadOp = GPULoadOp.Load; + if (renderContext.depth) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; + if (renderContext.stencil) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; + + renderContextData.currentPass = encoder.beginRenderPass(descriptor); + renderContextData.currentSets = { attributes: {} }; + } +} + +export default WebGPUBackend; diff --git a/examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts b/examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts new file mode 100644 index 000000000..1e548639e --- /dev/null +++ b/examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts @@ -0,0 +1,43 @@ +import WebGPU from '../../capabilities/WebGPU.js'; + +import Renderer from '../common/Renderer.js'; +import WebGLBackend from '../webgl/WebGLBackend.js'; +import WebGPUBackend from './WebGPUBackend.js'; +/* +const debugHandler = { + + get: function ( target, name ) { + + // Add |update + if ( /^(create|destroy)/.test( name ) ) console.log( 'WebGPUBackend.' + name ); + + return target[ name ]; + + } + +}; +*/ +class WebGPURenderer extends Renderer { + constructor(parameters = {}) { + let BackendClass; + + if (parameters.forceWebGL) { + BackendClass = WebGLBackend; + } else if (WebGPU.isAvailable()) { + BackendClass = WebGPUBackend; + } else { + BackendClass = WebGLBackend; + + console.warn('THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend.'); + } + + const backend = new BackendClass(parameters); + + //super( new Proxy( backend, debugHandler ) ); + super(backend, parameters); + + this.isWebGPURenderer = true; + } +} + +export default WebGPURenderer; diff --git a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts new file mode 100644 index 000000000..205865b39 --- /dev/null +++ b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts @@ -0,0 +1,1017 @@ +import { NoColorSpace, FloatType } from 'three'; + +import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; + +import NodeSampler from '../../common/nodes/NodeSampler.js'; +import { + NodeSampledTexture, + NodeSampledCubeTexture, + NodeSampledTexture3D, +} from '../../common/nodes/NodeSampledTexture.js'; + +import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; +import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js'; + +import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js'; + +import { getFormat } from '../utils/WebGPUTextureUtils.js'; + +import WGSLNodeParser from './WGSLNodeParser.js'; +import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js'; + +// GPUShaderStage is not defined in browsers not supporting WebGPU +const GPUShaderStage = self.GPUShaderStage; + +const gpuShaderStageLib = { + vertex: GPUShaderStage ? GPUShaderStage.VERTEX : 1, + fragment: GPUShaderStage ? GPUShaderStage.FRAGMENT : 2, + compute: GPUShaderStage ? GPUShaderStage.COMPUTE : 4, +}; + +const supports = { + instance: true, + swizzleAssign: false, + storageBuffer: true, +}; + +const wgslFnOpLib = { + '^^': 'threejs_xor', +}; + +const wgslTypeLib = { + float: 'f32', + int: 'i32', + uint: 'u32', + bool: 'bool', + color: 'vec3', + + vec2: 'vec2', + ivec2: 'vec2', + uvec2: 'vec2', + bvec2: 'vec2', + + vec3: 'vec3', + ivec3: 'vec3', + uvec3: 'vec3', + bvec3: 'vec3', + + vec4: 'vec4', + ivec4: 'vec4', + uvec4: 'vec4', + bvec4: 'vec4', + + mat2: 'mat2x2', + imat2: 'mat2x2', + umat2: 'mat2x2', + bmat2: 'mat2x2', + + mat3: 'mat3x3', + imat3: 'mat3x3', + umat3: 'mat3x3', + bmat3: 'mat3x3', + + mat4: 'mat4x4', + imat4: 'mat4x4', + umat4: 'mat4x4', + bmat4: 'mat4x4', +}; + +const wgslMethods = { + dFdx: 'dpdx', + dFdy: '- dpdy', + mod_float: 'threejs_mod_float', + mod_vec2: 'threejs_mod_vec2', + mod_vec3: 'threejs_mod_vec3', + mod_vec4: 'threejs_mod_vec4', + equals_bool: 'threejs_equals_bool', + equals_bvec2: 'threejs_equals_bvec2', + equals_bvec3: 'threejs_equals_bvec3', + equals_bvec4: 'threejs_equals_bvec4', + lessThanEqual: 'threejs_lessThanEqual', + greaterThan: 'threejs_greaterThan', + inversesqrt: 'inverseSqrt', + bitcast: 'bitcast', +}; + +const wgslPolyfill = { + threejs_xor: new CodeNode(` +fn threejs_xor( a : bool, b : bool ) -> bool { + + return ( a || b ) && !( a && b ); + +} +`), + lessThanEqual: new CodeNode(` +fn threejs_lessThanEqual( a : vec3, b : vec3 ) -> vec3 { + + return vec3( a.x <= b.x, a.y <= b.y, a.z <= b.z ); + +} +`), + greaterThan: new CodeNode(` +fn threejs_greaterThan( a : vec3, b : vec3 ) -> vec3 { + + return vec3( a.x > b.x, a.y > b.y, a.z > b.z ); + +} +`), + mod_float: new CodeNode('fn threejs_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }'), + mod_vec2: new CodeNode('fn threejs_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }'), + mod_vec3: new CodeNode('fn threejs_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }'), + mod_vec4: new CodeNode('fn threejs_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }'), + equals_bool: new CodeNode('fn threejs_equals_bool( a : bool, b : bool ) -> bool { return a == b; }'), + equals_bvec2: new CodeNode( + 'fn threejs_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }', + ), + equals_bvec3: new CodeNode( + 'fn threejs_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }', + ), + equals_bvec4: new CodeNode( + 'fn threejs_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }', + ), + repeatWrapping: new CodeNode(` +fn threejs_repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { + + let uvScaled = vec2( uv * vec2( dimension ) ); + + return ( ( uvScaled % dimension ) + dimension ) % dimension; + +} +`), + biquadraticTexture: new CodeNode(` +fn threejs_biquadraticTexture( map : texture_2d, coord : vec2f, level : i32 ) -> vec4f { + + let res = vec2f( textureDimensions( map, level ) ); + + let uvScaled = coord * res; + let uvWrapping = ( ( uvScaled % res ) + res ) % res; + + // https://www.shadertoy.com/view/WtyXRy + + let uv = uvWrapping - 0.5; + let iuv = floor( uv ); + let f = fract( uv ); + + let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ), level ); + let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ), level ); + let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ), level ); + let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ), level ); + + return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); + +} +`), +}; + +class WGSLNodeBuilder extends NodeBuilder { + constructor(object, renderer) { + super(object, renderer, new WGSLNodeParser()); + + this.uniformGroups = {}; + + this.builtins = {}; + } + + needsColorSpaceToLinear(texture) { + return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; + } + + _generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { + if (shaderStage === 'fragment') { + if (depthSnippet) { + return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${depthSnippet} )`; + } else { + return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`; + } + } else if (this.isFilteredTexture(texture)) { + return this.generateFilteredTexture(texture, textureProperty, uvSnippet); + } else { + return this.generateTextureLod(texture, textureProperty, uvSnippet, '0'); + } + } + + _generateVideoSample(textureProperty, uvSnippet, shaderStage = this.shaderStage) { + if (shaderStage === 'fragment') { + return `textureSampleBaseClampToEdge( ${textureProperty}, ${textureProperty}_sampler, vec2( ${uvSnippet}.x, 1.0 - ${uvSnippet}.y ) )`; + } else { + console.error(`WebGPURenderer: THREE.VideoTexture does not support ${shaderStage} shader.`); + } + } + + _generateTextureSampleLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment' && this.isUnfilterable(texture) === false) { + return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${levelSnippet} )`; + } else if (this.isFilteredTexture(texture)) { + return this.generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet); + } else { + return this.generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet); + } + } + + generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet = '0') { + this._include('biquadraticTexture'); + + return `threejs_biquadraticTexture( ${textureProperty}, ${uvSnippet}, i32( ${levelSnippet} ) )`; + } + + generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet = '0') { + this._include('repeatWrapping'); + + const dimension = `textureDimensions( ${textureProperty}, 0 )`; + + return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${levelSnippet} ) )`; + } + + generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u') { + if (depthSnippet) { + return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${depthSnippet}, ${levelSnippet} )`; + } else { + return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; + } + } + + generateTextureStore(texture, textureProperty, uvIndexSnippet, valueSnippet) { + return `textureStore( ${textureProperty}, ${uvIndexSnippet}, ${valueSnippet} )`; + } + + isUnfilterable(texture) { + return ( + this.getComponentTypeFromTexture(texture) !== 'float' || + (texture.isDataTexture === true && texture.type === FloatType) + ); + } + + generateTexture(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { + let snippet = null; + + if (texture.isVideoTexture === true) { + snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); + } else if (this.isUnfilterable(texture)) { + snippet = this.generateTextureLod(texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage); + } else { + snippet = this._generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage); + } + + return snippet; + } + + generateTextureGrad( + texture, + textureProperty, + uvSnippet, + gradSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy + return `textureSampleGrad( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; + } else { + console.error(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${shaderStage} shader.`); + } + } + + generateTextureCompare( + texture, + textureProperty, + uvSnippet, + compareSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + if (shaderStage === 'fragment') { + return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`; + } else { + console.error( + `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, + ); + } + } + + generateTextureLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage = this.shaderStage, + ) { + let snippet = null; + + if (texture.isVideoTexture === true) { + snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); + } else { + snippet = this._generateTextureSampleLevel( + texture, + textureProperty, + uvSnippet, + levelSnippet, + depthSnippet, + shaderStage, + ); + } + + return snippet; + } + + getPropertyName(node, shaderStage = this.shaderStage) { + if (node.isNodeVarying === true && node.needsInterpolation === true) { + if (shaderStage === 'vertex') { + return `varyings.${node.name}`; + } + } else if (node.isNodeUniform === true) { + const name = node.name; + const type = node.type; + + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { + return name; + } else if (type === 'buffer' || type === 'storageBuffer') { + return `NodeBuffer_${node.id}.${name}`; + } else { + return node.groupNode.name + '.' + name; + } + } + + return super.getPropertyName(node); + } + + getOutputStructName() { + return 'output'; + } + + _getUniformGroupCount(shaderStage) { + return Object.keys(this.uniforms[shaderStage]).length; + } + + getFunctionOperator(op) { + const fnOp = wgslFnOpLib[op]; + + if (fnOp !== undefined) { + this._include(fnOp); + + return fnOp; + } + + return null; + } + + getStorageAccess(node) { + if (node.isStorageTextureNode) { + switch (node.access) { + case GPUStorageTextureAccess.ReadOnly: + return 'read'; + + case GPUStorageTextureAccess.WriteOnly: + return 'write'; + + default: + return 'read_write'; + } + } else { + switch (node.access) { + case GPUBufferBindingType.Storage: + return 'read_write'; + + case GPUBufferBindingType.ReadOnlyStorage: + return 'read'; + + default: + return 'write'; + } + } + } + + getUniformFromNode(node, type, shaderStage, name = null) { + const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); + const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); + + if (nodeData.uniformGPU === undefined) { + let uniformGPU; + + const group = node.groupNode; + const groupName = group.name; + + const bindings = this.getBindGroupArray(groupName, shaderStage); + + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { + let texture = null; + + if (type === 'texture' || type === 'storageTexture') { + texture = new NodeSampledTexture( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } else if (type === 'cubeTexture') { + texture = new NodeSampledCubeTexture( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } else if (type === 'texture3D') { + texture = new NodeSampledTexture3D( + uniformNode.name, + uniformNode.node, + group, + node.access ? node.access : null, + ); + } + + texture.store = node.isStorageTextureNode === true; + texture.setVisibility(gpuShaderStageLib[shaderStage]); + + if ( + shaderStage === 'fragment' && + this.isUnfilterable(node.value) === false && + texture.store === false + ) { + const sampler = new NodeSampler(`${uniformNode.name}_sampler`, uniformNode.node, group); + sampler.setVisibility(gpuShaderStageLib[shaderStage]); + + bindings.push(sampler, texture); + + uniformGPU = [sampler, texture]; + } else { + bindings.push(texture); + + uniformGPU = [texture]; + } + } else if (type === 'buffer' || type === 'storageBuffer') { + const bufferClass = type === 'storageBuffer' ? NodeStorageBuffer : NodeUniformBuffer; + const buffer = new bufferClass(node, group); + buffer.setVisibility(gpuShaderStageLib[shaderStage]); + + bindings.push(buffer); + + uniformGPU = buffer; + } else { + const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); + + let uniformsGroup = uniformsStage[groupName]; + + if (uniformsGroup === undefined) { + uniformsGroup = new NodeUniformsGroup(groupName, group); + uniformsGroup.setVisibility(gpuShaderStageLib[shaderStage]); + + uniformsStage[groupName] = uniformsGroup; + + bindings.push(uniformsGroup); + } + + uniformGPU = this.getNodeUniform(uniformNode, type); + + uniformsGroup.addUniform(uniformGPU); + } + + nodeData.uniformGPU = uniformGPU; + } + + return uniformNode; + } + + getBuiltin(name, property, type, shaderStage = this.shaderStage) { + const map = this.builtins[shaderStage] || (this.builtins[shaderStage] = new Map()); + + if (map.has(name) === false) { + map.set(name, { + name, + property, + type, + }); + } + + return property; + } + + getVertexIndex() { + if (this.shaderStage === 'vertex') { + return this.getBuiltin('vertex_index', 'vertexIndex', 'u32', 'attribute'); + } + + return 'vertexIndex'; + } + + buildFunctionCode(shaderNode) { + const layout = shaderNode.layout; + const flowData = this.flowShaderNode(shaderNode); + + const parameters = []; + + for (const input of layout.inputs) { + parameters.push(input.name + ' : ' + this.getType(input.type)); + } + + // + + const code = `fn ${layout.name}( ${parameters.join(', ')} ) -> ${this.getType(layout.type)} { +${flowData.vars} +${flowData.code} + return ${flowData.result}; + +}`; + + // + + return code; + } + + getInstanceIndex() { + if (this.shaderStage === 'vertex') { + return this.getBuiltin('instance_index', 'instanceIndex', 'u32', 'attribute'); + } + + return 'instanceIndex'; + } + + getFrontFacing() { + return this.getBuiltin('front_facing', 'isFront', 'bool'); + } + + getFragCoord() { + return this.getBuiltin('position', 'fragCoord', 'vec4') + '.xyz'; + } + + getFragDepth() { + return 'output.' + this.getBuiltin('frag_depth', 'depth', 'f32', 'output'); + } + + isFlipY() { + return false; + } + + getBuiltins(shaderStage) { + const snippets = []; + const builtins = this.builtins[shaderStage]; + + if (builtins !== undefined) { + for (const { name, property, type } of builtins.values()) { + snippets.push(`@builtin( ${name} ) ${property} : ${type}`); + } + } + + return snippets.join(',\n\t'); + } + + getAttributes(shaderStage) { + const snippets = []; + + if (shaderStage === 'compute') { + this.getBuiltin('global_invocation_id', 'id', 'vec3', 'attribute'); + } + + if (shaderStage === 'vertex' || shaderStage === 'compute') { + const builtins = this.getBuiltins('attribute'); + + if (builtins) snippets.push(builtins); + + const attributes = this.getAttributesArray(); + + for (let index = 0, length = attributes.length; index < length; index++) { + const attribute = attributes[index]; + const name = attribute.name; + const type = this.getType(attribute.type); + + snippets.push(`@location( ${index} ) ${name} : ${type}`); + } + } + + return snippets.join(',\n\t'); + } + + getStructMembers(struct) { + const snippets = []; + const members = struct.getMemberTypes(); + + for (let i = 0; i < members.length; i++) { + const member = members[i]; + snippets.push(`\t@location( ${i} ) m${i} : ${member}`); + } + + const builtins = this.getBuiltins('output'); + + if (builtins) snippets.push(builtins); + + return snippets.join(',\n'); + } + + getStructs(shaderStage) { + const snippets = []; + const structs = this.structs[shaderStage]; + + for (let index = 0, length = structs.length; index < length; index++) { + const struct = structs[index]; + const name = struct.name; + + let snippet = `\struct ${name} {\n`; + snippet += this.getStructMembers(struct); + snippet += '\n}'; + + snippets.push(snippet); + + snippets.push(`\nvar output : ${name};\n\n`); + } + + return snippets.join('\n\n'); + } + + getVar(type, name) { + return `var ${name} : ${this.getType(type)}`; + } + + getVars(shaderStage) { + const snippets = []; + const vars = this.vars[shaderStage]; + + if (vars !== undefined) { + for (const variable of vars) { + snippets.push(`\t${this.getVar(variable.type, variable.name)};`); + } + } + + return `\n${snippets.join('\n')}\n`; + } + + getVaryings(shaderStage) { + const snippets = []; + + if (shaderStage === 'vertex') { + this.getBuiltin('position', 'Vertex', 'vec4', 'vertex'); + } + + if (shaderStage === 'vertex' || shaderStage === 'fragment') { + const varyings = this.varyings; + const vars = this.vars[shaderStage]; + + for (let index = 0; index < varyings.length; index++) { + const varying = varyings[index]; + + if (varying.needsInterpolation) { + let attributesSnippet = `@location( ${index} )`; + + if (/^(int|uint|ivec|uvec)/.test(varying.type)) { + attributesSnippet += ' @interpolate( flat )'; + } + + snippets.push(`${attributesSnippet} ${varying.name} : ${this.getType(varying.type)}`); + } else if (shaderStage === 'vertex' && vars.includes(varying) === false) { + vars.push(varying); + } + } + } + + const builtins = this.getBuiltins(shaderStage); + + if (builtins) snippets.push(builtins); + + const code = snippets.join(',\n\t'); + + return shaderStage === 'vertex' ? this._getWGSLStruct('VaryingsStruct', '\t' + code) : code; + } + + getUniforms(shaderStage) { + const uniforms = this.uniforms[shaderStage]; + + const bindingSnippets = []; + const bufferSnippets = []; + const structSnippets = []; + const uniformGroups = {}; + + for (const uniform of uniforms) { + const groundName = uniform.groupNode.name; + const uniformIndexes = this.bindingsIndexes[groundName]; + + if ( + uniform.type === 'texture' || + uniform.type === 'cubeTexture' || + uniform.type === 'storageTexture' || + uniform.type === 'texture3D' + ) { + const texture = uniform.node.value; + + if ( + shaderStage === 'fragment' && + this.isUnfilterable(texture) === false && + uniform.node.isStorageTextureNode !== true + ) { + if (texture.isDepthTexture === true && texture.compareFunction !== null) { + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler_comparison;`, + ); + } else { + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler;`, + ); + } + } + + let textureType; + + if (texture.isCubeTexture === true) { + textureType = 'texture_cube'; + } else if (texture.isDataArrayTexture === true) { + textureType = 'texture_2d_array'; + } else if (texture.isDepthTexture === true) { + textureType = 'texture_depth_2d'; + } else if (texture.isVideoTexture === true) { + textureType = 'texture_external'; + } else if (texture.isData3DTexture === true) { + textureType = 'texture_3d'; + } else if (uniform.node.isStorageTextureNode === true) { + const format = getFormat(texture); + const access = this.getStorageAccess(uniform.node); + + textureType = `texture_storage_2d<${format}, ${access}>`; + } else { + const componentPrefix = this.getComponentTypeFromTexture(texture).charAt(0); + + textureType = `texture_2d<${componentPrefix}32>`; + } + + bindingSnippets.push( + `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name} : ${textureType};`, + ); + } else if (uniform.type === 'buffer' || uniform.type === 'storageBuffer') { + const bufferNode = uniform.node; + const bufferType = this.getType(bufferNode.bufferType); + const bufferCount = bufferNode.bufferCount; + + const bufferCountSnippet = bufferCount > 0 ? ', ' + bufferCount : ''; + const bufferSnippet = `\t${uniform.name} : array< ${bufferType}${bufferCountSnippet} >\n`; + const bufferAccessMode = bufferNode.isStorageBufferNode + ? `storage, ${this.getStorageAccess(bufferNode)}` + : 'uniform'; + + bufferSnippets.push( + this._getWGSLStructBinding( + 'NodeBuffer_' + bufferNode.id, + bufferSnippet, + bufferAccessMode, + uniformIndexes.binding++, + uniformIndexes.group, + ), + ); + } else { + const vectorType = this.getType(this.getVectorType(uniform.type)); + const groupName = uniform.groupNode.name; + + const group = + uniformGroups[groupName] || + (uniformGroups[groupName] = { + index: uniformIndexes.binding++, + id: uniformIndexes.group, + snippets: [], + }); + + group.snippets.push(`\t${uniform.name} : ${vectorType}`); + } + } + + for (const name in uniformGroups) { + const group = uniformGroups[name]; + + structSnippets.push( + this._getWGSLStructBinding(name, group.snippets.join(',\n'), 'uniform', group.index, group.id), + ); + } + + let code = bindingSnippets.join('\n'); + code += bufferSnippets.join('\n'); + code += structSnippets.join('\n'); + + return code; + } + + buildCode() { + const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; + + for (const shaderStage in shadersData) { + const stageData = shadersData[shaderStage]; + stageData.uniforms = this.getUniforms(shaderStage); + stageData.attributes = this.getAttributes(shaderStage); + stageData.varyings = this.getVaryings(shaderStage); + stageData.structs = this.getStructs(shaderStage); + stageData.vars = this.getVars(shaderStage); + stageData.codes = this.getCodes(shaderStage); + + // + + let flow = '// code\n\n'; + flow += this.flowCode[shaderStage]; + + const flowNodes = this.flowNodes[shaderStage]; + const mainNode = flowNodes[flowNodes.length - 1]; + + const outputNode = mainNode.outputNode; + const isOutputStruct = outputNode !== undefined && outputNode.isOutputStructNode === true; + + for (const node of flowNodes) { + const flowSlotData = this.getFlowData(node /*, shaderStage*/); + const slotName = node.name; + + if (slotName) { + if (flow.length > 0) flow += '\n'; + + flow += `\t// flow -> ${slotName}\n\t`; + } + + flow += `${flowSlotData.code}\n\t`; + + if (node === mainNode && shaderStage !== 'compute') { + flow += '// result\n\n\t'; + + if (shaderStage === 'vertex') { + flow += `varyings.Vertex = ${flowSlotData.result};`; + } else if (shaderStage === 'fragment') { + if (isOutputStruct) { + stageData.returnType = outputNode.nodeType; + + flow += `return ${flowSlotData.result};`; + } else { + let structSnippet = '\t@location(0) color: vec4'; + + const builtins = this.getBuiltins('output'); + + if (builtins) structSnippet += ',\n\t' + builtins; + + stageData.returnType = 'OutputStruct'; + stageData.structs += this._getWGSLStruct('OutputStruct', structSnippet); + stageData.structs += '\nvar output : OutputStruct;\n\n'; + + flow += `output.color = ${flowSlotData.result};\n\n\treturn output;`; + } + } + } + } + + stageData.flow = flow; + } + + if (this.material !== null) { + this.vertexShader = this._getWGSLVertexCode(shadersData.vertex); + this.fragmentShader = this._getWGSLFragmentCode(shadersData.fragment); + } else { + this.computeShader = this._getWGSLComputeCode( + shadersData.compute, + (this.object.workgroupSize || [64]).join(', '), + ); + } + } + + getMethod(method, output = null) { + let wgslMethod; + + if (output !== null) { + wgslMethod = this._getWGSLMethod(method + '_' + output); + } + + if (wgslMethod === undefined) { + wgslMethod = this._getWGSLMethod(method); + } + + return wgslMethod || method; + } + + getType(type) { + return wgslTypeLib[type] || type; + } + + isAvailable(name) { + let result = supports[name]; + + if (result === undefined) { + if (name === 'float32Filterable') { + result = this.renderer.hasFeature('float32-filterable'); + } + + supports[name] = result; + } + + return result; + } + + _getWGSLMethod(method) { + if (wgslPolyfill[method] !== undefined) { + this._include(method); + } + + return wgslMethods[method]; + } + + _include(name) { + const codeNode = wgslPolyfill[name]; + codeNode.build(this); + + if (this.currentFunctionNode !== null) { + this.currentFunctionNode.includes.push(codeNode); + } + + return codeNode; + } + + _getWGSLVertexCode(shaderData) { + return `${this.getSignature()} + +// uniforms +${shaderData.uniforms} + +// varyings +${shaderData.varyings} +var varyings : VaryingsStruct; + +// codes +${shaderData.codes} + +@vertex +fn main( ${shaderData.attributes} ) -> VaryingsStruct { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + + return varyings; + +} +`; + } + + _getWGSLFragmentCode(shaderData) { + return `${this.getSignature()} + +// uniforms +${shaderData.uniforms} + +// structs +${shaderData.structs} + +// codes +${shaderData.codes} + +@fragment +fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + _getWGSLComputeCode(shaderData, workgroupSize) { + return `${this.getSignature()} +// system +var instanceIndex : u32; + +// uniforms +${shaderData.uniforms} + +// codes +${shaderData.codes} + +@compute @workgroup_size( ${workgroupSize} ) +fn main( ${shaderData.attributes} ) { + + // system + instanceIndex = id.x; + + // vars + ${shaderData.vars} + + // flow + ${shaderData.flow} + +} +`; + } + + _getWGSLStruct(name, vars) { + return ` +struct ${name} { +${vars} +};`; + } + + _getWGSLStructBinding(name, vars, access, binding = 0, group = 0) { + const structName = name + 'Struct'; + const structSnippet = this._getWGSLStruct(structName, vars); + + return `${structSnippet} +@binding( ${binding} ) @group( ${group} ) +var<${access}> ${name} : ${structName};`; + } +} + +export default WGSLNodeBuilder; diff --git a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts new file mode 100644 index 000000000..dfe1a2f37 --- /dev/null +++ b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts @@ -0,0 +1,127 @@ +import NodeFunction from '../../../nodes/core/NodeFunction.js'; +import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js'; + +const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i; +const propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi; + +const wgslTypeLib = { + f32: 'float', + i32: 'int', + u32: 'uint', + bool: 'bool', + + 'vec2': 'vec2', + 'vec2': 'ivec2', + 'vec2': 'uvec2', + 'vec2': 'bvec2', + + vec2f: 'vec2', + vec2i: 'ivec2', + vec2u: 'uvec2', + vec2b: 'bvec2', + + 'vec3': 'vec3', + 'vec3': 'ivec3', + 'vec3': 'uvec3', + 'vec3': 'bvec3', + + vec3f: 'vec3', + vec3i: 'ivec3', + vec3u: 'uvec3', + vec3b: 'bvec3', + + 'vec4': 'vec4', + 'vec4': 'ivec4', + 'vec4': 'uvec4', + 'vec4': 'bvec4', + + vec4f: 'vec4', + vec4i: 'ivec4', + vec4u: 'uvec4', + vec4b: 'bvec4', + + 'mat2x2': 'mat2', + mat2x2f: 'mat2', + + 'mat3x3': 'mat3', + mat3x3f: 'mat3', + + 'mat4x4': 'mat4', + mat4x4f: 'mat4', + + sampler: 'sampler', + texture_2d: 'texture', + texture_cube: 'cubeTexture', + texture_depth_2d: 'depthTexture', + texture_storage_2d: 'storageTexture', + texture_3d: 'texture3D', +}; + +const parse = source => { + source = source.trim(); + + const declaration = source.match(declarationRegexp); + + if (declaration !== null && declaration.length === 4) { + const inputsCode = declaration[2]; + const propsMatches = []; + let match = null; + + while ((match = propertiesRegexp.exec(inputsCode)) !== null) { + propsMatches.push({ name: match[1], type: match[2] }); + } + + // Process matches to correctly pair names and types + const inputs = []; + for (let i = 0; i < propsMatches.length; i++) { + const { name, type } = propsMatches[i]; + + let resolvedType = type; + + if (resolvedType.startsWith('texture')) { + resolvedType = type.split('<')[0]; + } + + resolvedType = wgslTypeLib[resolvedType] || resolvedType; + + inputs.push(new NodeFunctionInput(resolvedType, name)); + } + + const blockCode = source.substring(declaration[0].length); + const outputType = declaration[3] || 'void'; + + const name = declaration[1] !== undefined ? declaration[1] : ''; + const type = wgslTypeLib[outputType] || outputType; + + return { + type, + inputs, + name, + inputsCode, + blockCode, + outputType, + }; + } else { + throw new Error('FunctionNode: Function is not a WGSL code.'); + } +}; + +class WGSLNodeFunction extends NodeFunction { + constructor(source) { + const { type, inputs, name, inputsCode, blockCode, outputType } = parse(source); + + super(type, inputs, name); + + this.inputsCode = inputsCode; + this.blockCode = blockCode; + this.outputType = outputType; + } + + getCode(name = this.name) { + const outputType = this.outputType !== 'void' ? '-> ' + this.outputType : ''; + + return `fn ${name} ( ${this.inputsCode.trim()} ) ${outputType}` + this.blockCode; + } +} + +export default WGSLNodeFunction; diff --git a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts new file mode 100644 index 000000000..c32133df4 --- /dev/null +++ b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts @@ -0,0 +1,10 @@ +import NodeParser from '../../../nodes/core/NodeParser.js'; +import WGSLNodeFunction from './WGSLNodeFunction.js'; + +class WGSLNodeParser extends NodeParser { + parseFunction(source) { + return new WGSLNodeFunction(source); + } +} + +export default WGSLNodeParser; From 3d4d781956e571e618df9b1ef372efc26aa7a9be Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:56:13 -0400 Subject: [PATCH 65/72] Update patch --- examples-jsm/changes.patch | 47 +++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/examples-jsm/changes.patch b/examples-jsm/changes.patch index 9360c8abb..65e909227 100644 --- a/examples-jsm/changes.patch +++ b/examples-jsm/changes.patch @@ -6653,10 +6653,10 @@ index e7b389cd..53406066 100644 for (const uniform of this.uniforms) { const node = uniform.nodeUniform.node; diff --git a/examples-jsm/examples/renderers/common/nodes/Nodes.ts b/examples-jsm/examples/renderers/common/nodes/Nodes.ts -index db035f6d..e8a2a222 100644 +index db035f6d..5d4b35ba 100644 --- a/examples-jsm/examples/renderers/common/nodes/Nodes.ts +++ b/examples-jsm/examples/renderers/common/nodes/Nodes.ts -@@ -2,10 +2,20 @@ import DataMap from '../DataMap.js'; +@@ -2,10 +2,19 @@ import DataMap from '../DataMap.js'; import ChainMap from '../ChainMap.js'; import NodeBuilderState from './NodeBuilderState.js'; import { @@ -6666,7 +6666,6 @@ index db035f6d..e8a2a222 100644 EquirectangularReflectionMapping, EquirectangularRefractionMapping, + Fog, -+ FogBase, + FogExp2, + Material, NoToneMapping, @@ -6677,7 +6676,7 @@ index db035f6d..e8a2a222 100644 } from 'three'; import { NodeFrame, -@@ -22,21 +32,66 @@ import { +@@ -22,21 +31,66 @@ import { normalWorld, pmremTexture, viewportTopLeft, @@ -6712,7 +6711,7 @@ index db035f6d..e8a2a222 100644 +interface SceneData { + background?: Color | Texture | CubeTexture | undefined; + backgroundNode?: Node | undefined; -+ fog?: FogBase | undefined; ++ fog?: Fog | FogExp2 | undefined; + fogNode?: Node | undefined; + environment?: Texture | undefined; + environmentNode?: Node | undefined; @@ -6748,7 +6747,7 @@ index db035f6d..e8a2a222 100644 const groupNode = nodeUniformsGroup.groupNode; const name = groupNode.name; -@@ -76,7 +131,7 @@ class Nodes extends DataMap { +@@ -76,7 +130,7 @@ class Nodes extends DataMap { // other groups are updated just when groupNode.needsUpdate is true @@ -6757,7 +6756,7 @@ index db035f6d..e8a2a222 100644 let groupData = this.groupsData.get(groupChain); if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {})); -@@ -90,11 +145,11 @@ class Nodes extends DataMap { +@@ -90,11 +144,11 @@ class Nodes extends DataMap { return false; } @@ -6771,7 +6770,7 @@ index db035f6d..e8a2a222 100644 const renderObjectData = this.get(renderObject); let nodeBuilderState = renderObjectData.nodeBuilderState; -@@ -131,20 +186,20 @@ class Nodes extends DataMap { +@@ -131,20 +185,20 @@ class Nodes extends DataMap { return nodeBuilderState; } @@ -6797,7 +6796,7 @@ index db035f6d..e8a2a222 100644 const computeData = this.get(computeNode); let nodeBuilderState = computeData.nodeBuilderState; -@@ -161,7 +216,7 @@ class Nodes extends DataMap { +@@ -161,7 +215,7 @@ class Nodes extends DataMap { return nodeBuilderState; } @@ -6806,7 +6805,7 @@ index db035f6d..e8a2a222 100644 return new NodeBuilderState( nodeBuilder.vertexShader, nodeBuilder.fragmentShader, -@@ -176,20 +231,28 @@ class Nodes extends DataMap { +@@ -176,20 +230,28 @@ class Nodes extends DataMap { ); } @@ -6843,7 +6842,7 @@ index db035f6d..e8a2a222 100644 const callId = this.renderer.info.calls; let cacheKeyData = this.callHashCache.get(chain); -@@ -215,7 +278,7 @@ class Nodes extends DataMap { +@@ -215,7 +277,7 @@ class Nodes extends DataMap { return cacheKeyData.cacheKey; } @@ -6852,7 +6851,7 @@ index db035f6d..e8a2a222 100644 this.updateEnvironment(scene); this.updateFog(scene); this.updateBackground(scene); -@@ -225,7 +288,7 @@ class Nodes extends DataMap { +@@ -225,7 +287,7 @@ class Nodes extends DataMap { return this.renderer.getRenderTarget() ? false : true; } @@ -6861,7 +6860,7 @@ index db035f6d..e8a2a222 100644 const sceneData = this.get(scene); const background = scene.background; -@@ -234,15 +297,15 @@ class Nodes extends DataMap { +@@ -234,15 +296,15 @@ class Nodes extends DataMap { let backgroundNode = null; if ( @@ -6884,7 +6883,7 @@ index db035f6d..e8a2a222 100644 } sceneData.backgroundNode = backgroundNode; -@@ -254,7 +317,7 @@ class Nodes extends DataMap { +@@ -254,7 +316,7 @@ class Nodes extends DataMap { } } @@ -6893,7 +6892,7 @@ index db035f6d..e8a2a222 100644 const sceneData = this.get(scene); const fog = scene.fog; -@@ -262,9 +325,9 @@ class Nodes extends DataMap { +@@ -262,9 +324,9 @@ class Nodes extends DataMap { if (sceneData.fog !== fog) { let fogNode = null; @@ -6905,7 +6904,7 @@ index db035f6d..e8a2a222 100644 fogNode = rangeFog( reference('color', 'color', fog), reference('near', 'float', fog), -@@ -283,7 +346,7 @@ class Nodes extends DataMap { +@@ -283,7 +345,7 @@ class Nodes extends DataMap { } } @@ -6914,7 +6913,7 @@ index db035f6d..e8a2a222 100644 const sceneData = this.get(scene); const environment = scene.environment; -@@ -291,7 +354,7 @@ class Nodes extends DataMap { +@@ -291,7 +353,7 @@ class Nodes extends DataMap { if (sceneData.environment !== environment) { let environmentNode = null; @@ -6923,7 +6922,7 @@ index db035f6d..e8a2a222 100644 environmentNode = cubeTexture(environment); } else if (environment.isTexture === true) { environmentNode = texture(environment); -@@ -308,7 +371,13 @@ class Nodes extends DataMap { +@@ -308,7 +370,13 @@ class Nodes extends DataMap { } } @@ -6938,7 +6937,7 @@ index db035f6d..e8a2a222 100644 const nodeFrame = this.nodeFrame; nodeFrame.renderer = renderer; nodeFrame.scene = scene; -@@ -319,7 +388,7 @@ class Nodes extends DataMap { +@@ -319,7 +387,7 @@ class Nodes extends DataMap { return nodeFrame; } @@ -6947,7 +6946,7 @@ index db035f6d..e8a2a222 100644 return this.getNodeFrame( renderObject.renderer, renderObject.scene, -@@ -329,8 +398,8 @@ class Nodes extends DataMap { +@@ -329,8 +397,8 @@ class Nodes extends DataMap { ); } @@ -6958,7 +6957,7 @@ index db035f6d..e8a2a222 100644 if (this.isToneMappingState) { if (this.renderer.toneMappingNode) { -@@ -347,7 +416,7 @@ class Nodes extends DataMap { +@@ -347,7 +415,7 @@ class Nodes extends DataMap { return output; } @@ -6967,7 +6966,7 @@ index db035f6d..e8a2a222 100644 const nodeFrame = this.getNodeFrameForRender(renderObject); const nodeBuilder = renderObject.getNodeBuilderState(); -@@ -356,7 +425,7 @@ class Nodes extends DataMap { +@@ -356,7 +424,7 @@ class Nodes extends DataMap { } } @@ -6976,7 +6975,7 @@ index db035f6d..e8a2a222 100644 const nodeFrame = this.getNodeFrameForRender(renderObject); const nodeBuilder = renderObject.getNodeBuilderState(); -@@ -365,7 +434,7 @@ class Nodes extends DataMap { +@@ -365,7 +433,7 @@ class Nodes extends DataMap { } } @@ -6985,7 +6984,7 @@ index db035f6d..e8a2a222 100644 const nodeFrame = this.getNodeFrame(); const nodeBuilder = this.getForCompute(computeNode); -@@ -374,7 +443,7 @@ class Nodes extends DataMap { +@@ -374,7 +442,7 @@ class Nodes extends DataMap { } } From 60c2a0579272ba7ab66e4c57a9fbb9a15f26d1a7 Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:56:49 -0400 Subject: [PATCH 66/72] Delete examples --- examples-jsm/examples/nodes/Nodes.ts | 414 ----- .../nodes/accessors/BufferAttributeNode.ts | 131 -- .../examples/nodes/accessors/TextureNode.ts | 327 ---- examples-jsm/examples/nodes/code/CodeNode.ts | 66 - .../examples/nodes/code/FunctionNode.ts | 100 -- .../examples/nodes/core/ContextNode.ts | 55 - examples-jsm/examples/nodes/core/InputNode.ts | 65 - examples-jsm/examples/nodes/core/Node.ts | 424 ------ .../examples/nodes/core/NodeAttribute.ts | 11 - .../examples/nodes/core/NodeBuilder.ts | 1119 -------------- examples-jsm/examples/nodes/core/NodeCache.ts | 26 - examples-jsm/examples/nodes/core/NodeCode.ts | 11 - examples-jsm/examples/nodes/core/NodeFrame.ts | 127 -- .../examples/nodes/core/NodeFunction.ts | 16 - .../examples/nodes/core/NodeKeywords.ts | 58 - .../examples/nodes/core/NodeParser.ts | 7 - .../examples/nodes/core/NodeUniform.ts | 27 - examples-jsm/examples/nodes/core/NodeUtils.ts | 132 -- examples-jsm/examples/nodes/core/NodeVar.ts | 10 - .../examples/nodes/core/NodeVarying.ts | 13 - examples-jsm/examples/nodes/core/StackNode.ts | 71 - .../examples/nodes/core/StructTypeNode.ts | 18 - .../examples/nodes/core/UniformGroupNode.ts | 30 - .../examples/nodes/core/UniformNode.ts | 90 -- examples-jsm/examples/nodes/core/constants.ts | 28 - examples-jsm/examples/nodes/fog/FogNode.ts | 38 - .../examples/nodes/gpgpu/ComputeNode.ts | 67 - .../nodes/lighting/EnvironmentNode.ts | 119 -- .../nodes/lighting/LightingContextNode.ts | 58 - .../examples/nodes/lighting/LightsNode.ts | 170 --- .../examples/nodes/materials/NodeMaterial.ts | 514 ------- .../examples/nodes/shadernode/ShaderNode.ts | 532 ------- .../examples/renderers/common/Animation.ts | 38 - .../examples/renderers/common/Attributes.ts | 53 - .../examples/renderers/common/Backend.ts | 165 -- .../examples/renderers/common/Background.ts | 118 -- .../examples/renderers/common/BindGroup.ts | 12 - .../examples/renderers/common/Binding.ts | 17 - .../examples/renderers/common/Bindings.ts | 161 -- .../examples/renderers/common/Buffer.ts | 28 - .../examples/renderers/common/BufferUtils.ts | 23 - .../examples/renderers/common/ChainMap.ts | 43 - .../renderers/common/ClippingContext.ts | 128 -- .../examples/renderers/common/Color4.ts | 27 - .../renderers/common/ComputePipeline.ts | 13 - .../examples/renderers/common/Constants.ts | 14 - .../renderers/common/CubeRenderTarget.ts | 69 - .../examples/renderers/common/DataMap.ts | 38 - .../examples/renderers/common/Geometries.ts | 182 --- .../examples/renderers/common/Info.ts | 95 -- .../examples/renderers/common/Pipeline.ts | 9 - .../examples/renderers/common/Pipelines.ts | 270 ---- .../renderers/common/ProgrammableStage.ts | 16 - .../examples/renderers/common/RenderBundle.ts | 12 - .../renderers/common/RenderBundles.ts | 28 - .../renderers/common/RenderContext.ts | 39 - .../renderers/common/RenderContexts.ts | 47 - .../examples/renderers/common/RenderList.ts | 145 -- .../examples/renderers/common/RenderLists.ts | 28 - .../examples/renderers/common/RenderObject.ts | 215 --- .../renderers/common/RenderObjects.ts | 100 -- .../renderers/common/RenderPipeline.ts | 12 - .../examples/renderers/common/Renderer.ts | 1347 ----------------- .../renderers/common/SampledTexture.ts | 61 - .../examples/renderers/common/Sampler.ts | 14 - .../renderers/common/StorageBuffer.ts | 13 - .../examples/renderers/common/Textures.ts | 288 ---- .../examples/renderers/common/Uniform.ts | 100 -- .../renderers/common/UniformBuffer.ts | 11 - .../renderers/common/UniformsGroup.ts | 277 ---- .../renderers/common/extras/PMREMGenerator.ts | 659 -------- .../common/nodes/NodeBuilderState.ts | 55 - .../renderers/common/nodes/NodeUniform.ts | 103 -- .../common/nodes/NodeUniformsGroup.ts | 30 - .../examples/renderers/common/nodes/Nodes.ts | 394 ----- .../examples/renderers/webgl/WebGLBackend.ts | 1268 ---------------- .../renderers/webgl/nodes/GLSLNodeBuilder.ts | 747 --------- .../renderers/webgpu/WebGPUBackend.ts | 1205 --------------- .../renderers/webgpu/WebGPURenderer.ts | 43 - .../renderers/webgpu/nodes/WGSLNodeBuilder.ts | 1017 ------------- .../webgpu/nodes/WGSLNodeFunction.ts | 127 -- .../renderers/webgpu/nodes/WGSLNodeParser.ts | 10 - 82 files changed, 14788 deletions(-) delete mode 100644 examples-jsm/examples/nodes/Nodes.ts delete mode 100644 examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts delete mode 100644 examples-jsm/examples/nodes/accessors/TextureNode.ts delete mode 100644 examples-jsm/examples/nodes/code/CodeNode.ts delete mode 100644 examples-jsm/examples/nodes/code/FunctionNode.ts delete mode 100644 examples-jsm/examples/nodes/core/ContextNode.ts delete mode 100644 examples-jsm/examples/nodes/core/InputNode.ts delete mode 100644 examples-jsm/examples/nodes/core/Node.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeAttribute.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeBuilder.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeCache.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeCode.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeFrame.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeFunction.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeKeywords.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeParser.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeUniform.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeUtils.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeVar.ts delete mode 100644 examples-jsm/examples/nodes/core/NodeVarying.ts delete mode 100644 examples-jsm/examples/nodes/core/StackNode.ts delete mode 100644 examples-jsm/examples/nodes/core/StructTypeNode.ts delete mode 100644 examples-jsm/examples/nodes/core/UniformGroupNode.ts delete mode 100644 examples-jsm/examples/nodes/core/UniformNode.ts delete mode 100644 examples-jsm/examples/nodes/core/constants.ts delete mode 100644 examples-jsm/examples/nodes/fog/FogNode.ts delete mode 100644 examples-jsm/examples/nodes/gpgpu/ComputeNode.ts delete mode 100644 examples-jsm/examples/nodes/lighting/EnvironmentNode.ts delete mode 100644 examples-jsm/examples/nodes/lighting/LightingContextNode.ts delete mode 100644 examples-jsm/examples/nodes/lighting/LightsNode.ts delete mode 100644 examples-jsm/examples/nodes/materials/NodeMaterial.ts delete mode 100644 examples-jsm/examples/nodes/shadernode/ShaderNode.ts delete mode 100644 examples-jsm/examples/renderers/common/Animation.ts delete mode 100644 examples-jsm/examples/renderers/common/Attributes.ts delete mode 100644 examples-jsm/examples/renderers/common/Backend.ts delete mode 100644 examples-jsm/examples/renderers/common/Background.ts delete mode 100644 examples-jsm/examples/renderers/common/BindGroup.ts delete mode 100644 examples-jsm/examples/renderers/common/Binding.ts delete mode 100644 examples-jsm/examples/renderers/common/Bindings.ts delete mode 100644 examples-jsm/examples/renderers/common/Buffer.ts delete mode 100644 examples-jsm/examples/renderers/common/BufferUtils.ts delete mode 100644 examples-jsm/examples/renderers/common/ChainMap.ts delete mode 100644 examples-jsm/examples/renderers/common/ClippingContext.ts delete mode 100644 examples-jsm/examples/renderers/common/Color4.ts delete mode 100644 examples-jsm/examples/renderers/common/ComputePipeline.ts delete mode 100644 examples-jsm/examples/renderers/common/Constants.ts delete mode 100644 examples-jsm/examples/renderers/common/CubeRenderTarget.ts delete mode 100644 examples-jsm/examples/renderers/common/DataMap.ts delete mode 100644 examples-jsm/examples/renderers/common/Geometries.ts delete mode 100644 examples-jsm/examples/renderers/common/Info.ts delete mode 100644 examples-jsm/examples/renderers/common/Pipeline.ts delete mode 100644 examples-jsm/examples/renderers/common/Pipelines.ts delete mode 100644 examples-jsm/examples/renderers/common/ProgrammableStage.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderBundle.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderBundles.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderContext.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderContexts.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderList.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderLists.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderObject.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderObjects.ts delete mode 100644 examples-jsm/examples/renderers/common/RenderPipeline.ts delete mode 100644 examples-jsm/examples/renderers/common/Renderer.ts delete mode 100644 examples-jsm/examples/renderers/common/SampledTexture.ts delete mode 100644 examples-jsm/examples/renderers/common/Sampler.ts delete mode 100644 examples-jsm/examples/renderers/common/StorageBuffer.ts delete mode 100644 examples-jsm/examples/renderers/common/Textures.ts delete mode 100644 examples-jsm/examples/renderers/common/Uniform.ts delete mode 100644 examples-jsm/examples/renderers/common/UniformBuffer.ts delete mode 100644 examples-jsm/examples/renderers/common/UniformsGroup.ts delete mode 100644 examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts delete mode 100644 examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts delete mode 100644 examples-jsm/examples/renderers/common/nodes/NodeUniform.ts delete mode 100644 examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts delete mode 100644 examples-jsm/examples/renderers/common/nodes/Nodes.ts delete mode 100644 examples-jsm/examples/renderers/webgl/WebGLBackend.ts delete mode 100644 examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts delete mode 100644 examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts delete mode 100644 examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts delete mode 100644 examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts delete mode 100644 examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts delete mode 100644 examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts diff --git a/examples-jsm/examples/nodes/Nodes.ts b/examples-jsm/examples/nodes/Nodes.ts deleted file mode 100644 index da3779345..000000000 --- a/examples-jsm/examples/nodes/Nodes.ts +++ /dev/null @@ -1,414 +0,0 @@ -// @TODO: We can simplify "export { default as SomeNode, other, exports } from '...'" to just "export * from '...'" if we will use only named exports -// this will also solve issues like "import TempNode from '../core/Node.js'" - -// constants -export * from './core/constants.js'; - -// core -export { default as AssignNode, assign } from './core/AssignNode.js'; -export { default as AttributeNode, attribute } from './core/AttributeNode.js'; -export { default as BypassNode, bypass } from './core/BypassNode.js'; -export { default as CacheNode, cache } from './core/CacheNode.js'; -export { default as ConstNode } from './core/ConstNode.js'; -export { default as ContextNode, context, label } from './core/ContextNode.js'; -export { default as IndexNode, vertexIndex, instanceIndex } from './core/IndexNode.js'; -export { default as LightingModel } from './core/LightingModel.js'; -export { default as Node, addNodeClass, createNodeFromType } from './core/Node.js'; -export { default as VarNode, temp } from './core/VarNode.js'; -export { default as NodeAttribute } from './core/NodeAttribute.js'; -export { default as NodeBuilder } from './core/NodeBuilder.js'; -export { default as NodeCache } from './core/NodeCache.js'; -export { default as NodeCode } from './core/NodeCode.js'; -export { default as NodeFrame } from './core/NodeFrame.js'; -export { default as NodeFunctionInput } from './core/NodeFunctionInput.js'; -export { default as NodeKeywords } from './core/NodeKeywords.js'; -export { default as NodeUniform } from './core/NodeUniform.js'; -export { default as NodeVar } from './core/NodeVar.js'; -export { default as NodeVarying } from './core/NodeVarying.js'; -export { default as ParameterNode, parameter } from './core/ParameterNode.js'; -export { - default as PropertyNode, - property, - varyingProperty, - output, - diffuseColor, - roughness, - metalness, - clearcoat, - clearcoatRoughness, - sheen, - sheenRoughness, - iridescence, - iridescenceIOR, - iridescenceThickness, - specularColor, - shininess, - dashSize, - gapSize, - pointWidth, - alphaT, - anisotropy, - anisotropyB, - anisotropyT, -} from './core/PropertyNode.js'; -export { default as StackNode, stack } from './core/StackNode.js'; -export { default as TempNode } from './core/TempNode.js'; -export { - default as UniformGroupNode, - uniformGroup, - objectGroup, - renderGroup, - frameGroup, -} from './core/UniformGroupNode.js'; -export { default as UniformNode, uniform } from './core/UniformNode.js'; -export { default as VaryingNode, varying } from './core/VaryingNode.js'; -export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js'; - -import * as NodeUtils from './core/NodeUtils.js'; -export { NodeUtils }; - -// math -export { - default as MathNode, - PI, - PI2, - EPSILON, - INFINITY, - radians, - degrees, - exp, - exp2, - log, - log2, - sqrt, - inverseSqrt, - floor, - ceil, - normalize, - fract, - sin, - cos, - tan, - asin, - acos, - atan, - abs, - sign, - length, - lengthSq, - negate, - oneMinus, - dFdx, - dFdy, - round, - reciprocal, - trunc, - fwidth, - bitcast, - atan2, - min, - max, - mod, - step, - reflect, - distance, - difference, - dot, - cross, - pow, - pow2, - pow3, - pow4, - transformDirection, - mix, - clamp, - saturate, - refract, - smoothstep, - faceForward, - cbrt, - transpose, - all, - any, - equals, -} from './math/MathNode.js'; - -export { - default as OperatorNode, - add, - sub, - mul, - div, - remainder, - equal, - lessThan, - greaterThan, - lessThanEqual, - greaterThanEqual, - and, - or, - not, - xor, - bitAnd, - bitNot, - bitOr, - bitXor, - shiftLeft, - shiftRight, -} from './math/OperatorNode.js'; -export { default as CondNode, cond } from './math/CondNode.js'; -export { default as HashNode, hash } from './math/HashNode.js'; - -// math utils -export { parabola, gain, pcurve, sinc } from './math/MathUtils.js'; -export { triNoise3D } from './math/TriNoise3D.js'; - -// utils -export { default as ArrayElementNode } from './utils/ArrayElementNode.js'; -export { default as ConvertNode } from './utils/ConvertNode.js'; -export { default as DiscardNode, discard, Return } from './utils/DiscardNode.js'; -export { default as EquirectUVNode, equirectUV } from './utils/EquirectUVNode.js'; -export { default as FunctionOverloadingNode, overloadingFn } from './utils/FunctionOverloadingNode.js'; -export { default as JoinNode } from './utils/JoinNode.js'; -export { default as LoopNode, loop, Continue, Break } from './utils/LoopNode.js'; -export { default as MatcapUVNode, matcapUV } from './utils/MatcapUVNode.js'; -export { default as MaxMipLevelNode, maxMipLevel } from './utils/MaxMipLevelNode.js'; -export { default as OscNode, oscSine, oscSquare, oscTriangle, oscSawtooth } from './utils/OscNode.js'; -export { default as PackingNode, directionToColor, colorToDirection } from './utils/PackingNode.js'; -export { default as RemapNode, remap, remapClamp } from './utils/RemapNode.js'; -export { default as RotateUVNode, rotateUV } from './utils/RotateUVNode.js'; -export { default as RotateNode, rotate } from './utils/RotateNode.js'; -export { default as SetNode } from './utils/SetNode.js'; -export { default as SplitNode } from './utils/SplitNode.js'; -export { default as SpriteSheetUVNode, spritesheetUV } from './utils/SpriteSheetUVNode.js'; -export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js'; -export { default as TimerNode, timerLocal, timerGlobal, timerDelta, frameId } from './utils/TimerNode.js'; -export { - default as TriplanarTexturesNode, - triplanarTextures, - triplanarTexture, -} from './utils/TriplanarTexturesNode.js'; -export { default as ReflectorNode, reflector } from './utils/ReflectorNode.js'; - -// shadernode -export * from './shadernode/ShaderNode.js'; - -// accessors -export { TBNViewMatrix, parallaxDirection, parallaxUV, transformedBentNormalView } from './accessors/AccessorsUtils.js'; -export { default as UniformsNode, uniforms } from './accessors/UniformsNode.js'; -export * from './accessors/BitangentNode.js'; -export { - default as BufferAttributeNode, - bufferAttribute, - dynamicBufferAttribute, - instancedBufferAttribute, - instancedDynamicBufferAttribute, -} from './accessors/BufferAttributeNode.js'; -export { default as BufferNode, buffer } from './accessors/BufferNode.js'; -export * from './accessors/CameraNode.js'; -export { default as VertexColorNode, vertexColor } from './accessors/VertexColorNode.js'; -export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js'; -export { default as InstanceNode, instance } from './accessors/InstanceNode.js'; -export { default as BatchNode, batch } from './accessors/BatchNode.js'; -export { - default as MaterialNode, - materialAlphaTest, - materialColor, - materialShininess, - materialEmissive, - materialOpacity, - materialSpecular, - materialSpecularStrength, - materialReflectivity, - materialRoughness, - materialMetalness, - materialNormal, - materialClearcoat, - materialClearcoatRoughness, - materialClearcoatNormal, - materialRotation, - materialSheen, - materialSheenRoughness, - materialIridescence, - materialIridescenceIOR, - materialIridescenceThickness, - materialLineScale, - materialLineDashSize, - materialLineGapSize, - materialLineWidth, - materialLineDashOffset, - materialPointWidth, - materialAnisotropy, - materialAnisotropyVector, - materialDispersion, -} from './accessors/MaterialNode.js'; -export { default as MaterialReferenceNode, materialReference } from './accessors/MaterialReferenceNode.js'; -export { default as RendererReferenceNode, rendererReference } from './accessors/RendererReferenceNode.js'; -export { default as MorphNode, morphReference } from './accessors/MorphNode.js'; -export { default as TextureBicubicNode, textureBicubic } from './accessors/TextureBicubicNode.js'; -export { - default as ModelNode, - modelDirection, - modelViewMatrix, - modelNormalMatrix, - modelWorldMatrix, - modelPosition, - modelViewPosition, - modelScale, - modelWorldMatrixInverse, -} from './accessors/ModelNode.js'; -export { default as ModelViewProjectionNode, modelViewProjection } from './accessors/ModelViewProjectionNode.js'; -export * from './accessors/NormalNode.js'; -export { - default as Object3DNode, - objectDirection, - objectViewMatrix, - objectNormalMatrix, - objectWorldMatrix, - objectPosition, - objectScale, - objectViewPosition, -} from './accessors/Object3DNode.js'; -export { default as PointUVNode, pointUV } from './accessors/PointUVNode.js'; -export * from './accessors/PositionNode.js'; -export { default as ReferenceNode, reference, referenceBuffer } from './accessors/ReferenceNode.js'; -export * from './accessors/ReflectVectorNode.js'; -export { default as SkinningNode, skinning } from './accessors/SkinningNode.js'; -export { default as SceneNode, backgroundBlurriness, backgroundIntensity } from './accessors/SceneNode.js'; -export { default as StorageBufferNode, storage, storageObject } from './accessors/StorageBufferNode.js'; -export * from './accessors/TangentNode.js'; -export { default as TextureNode, texture, textureLoad, /*textureLevel,*/ sampler } from './accessors/TextureNode.js'; -export { default as StorageTextureNode, storageTexture, textureStore } from './accessors/StorageTextureNode.js'; -export { default as Texture3DNode, texture3D } from './accessors/Texture3DNode.js'; -export * from './accessors/UVNode.js'; -export { default as UserDataNode, userData } from './accessors/UserDataNode.js'; - -// display -export { default as BlendModeNode, burn, dodge, overlay, screen } from './display/BlendModeNode.js'; -export { default as BumpMapNode, bumpMap } from './display/BumpMapNode.js'; -export { - default as ColorAdjustmentNode, - saturation, - vibrance, - hue, - lumaCoeffs, - luminance, - threshold, -} from './display/ColorAdjustmentNode.js'; -export { - default as ColorSpaceNode, - linearToColorSpace, - colorSpaceToLinear, - linearTosRGB, - sRGBToLinear, -} from './display/ColorSpaceNode.js'; -export { default as FrontFacingNode, frontFacing, faceDirection } from './display/FrontFacingNode.js'; -export { default as NormalMapNode, normalMap } from './display/NormalMapNode.js'; -export { default as PosterizeNode, posterize } from './display/PosterizeNode.js'; -export { default as ToneMappingNode, toneMapping } from './display/ToneMappingNode.js'; -export { - default as ViewportNode, - viewport, - viewportCoordinate, - viewportResolution, - viewportTopLeft, - viewportBottomLeft, - viewportTopRight, - viewportBottomRight, -} from './display/ViewportNode.js'; -export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js'; -export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js'; -export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js'; -export { - default as ViewportDepthNode, - viewZToOrthographicDepth, - orthographicDepthToViewZ, - viewZToPerspectiveDepth, - perspectiveDepthToViewZ, - depth, - linearDepth, - viewportLinearDepth, -} from './display/ViewportDepthNode.js'; -export { default as GaussianBlurNode, gaussianBlur } from './display/GaussianBlurNode.js'; -export { default as AfterImageNode, afterImage } from './display/AfterImageNode.js'; -export { default as AnamorphicNode, anamorphic } from './display/AnamorphicNode.js'; -export { default as SobelOperatorNode, sobel } from './display/SobelOperatorNode.js'; -export { default as DepthOfFieldNode, dof } from './display/DepthOfFieldNode.js'; -export { default as DotScreenNode, dotScreen } from './display/DotScreenNode.js'; -export { default as RGBShiftNode, rgbShift } from './display/RGBShiftNode.js'; - -export { default as PassNode, pass, texturePass, depthPass } from './display/PassNode.js'; - -// code -export { default as ExpressionNode, expression } from './code/ExpressionNode.js'; -export { default as CodeNode, code, js, wgsl, glsl } from './code/CodeNode.js'; -export { default as FunctionCallNode, call } from './code/FunctionCallNode.js'; -export { default as FunctionNode, wgslFn, glslFn } from './code/FunctionNode.js'; -export { default as ScriptableNode, scriptable, global } from './code/ScriptableNode.js'; -export { default as ScriptableValueNode, scriptableValue } from './code/ScriptableValueNode.js'; - -// fog -export { default as FogNode, fog } from './fog/FogNode.js'; -export { default as FogRangeNode, rangeFog } from './fog/FogRangeNode.js'; -export { default as FogExp2Node, densityFog } from './fog/FogExp2Node.js'; - -// geometry -export { default as RangeNode, range } from './geometry/RangeNode.js'; - -// gpgpu -export { default as ComputeNode, compute } from './gpgpu/ComputeNode.js'; - -// lighting -export { default as LightNode, lightTargetDirection } from './lighting/LightNode.js'; -export { default as PointLightNode } from './lighting/PointLightNode.js'; -export { default as DirectionalLightNode } from './lighting/DirectionalLightNode.js'; -export { default as RectAreaLightNode } from './lighting/RectAreaLightNode.js'; -export { default as SpotLightNode } from './lighting/SpotLightNode.js'; -export { default as IESSpotLightNode } from './lighting/IESSpotLightNode.js'; -export { default as AmbientLightNode } from './lighting/AmbientLightNode.js'; -export { default as LightsNode, lights, lightsNode, addLightNode } from './lighting/LightsNode.js'; -export { default as LightingNode /* @TODO: lighting (abstract), light */ } from './lighting/LightingNode.js'; -export { default as LightingContextNode, lightingContext } from './lighting/LightingContextNode.js'; -export { default as HemisphereLightNode } from './lighting/HemisphereLightNode.js'; -export { default as EnvironmentNode } from './lighting/EnvironmentNode.js'; -export { default as IrradianceNode } from './lighting/IrradianceNode.js'; -export { default as AONode } from './lighting/AONode.js'; -export { default as AnalyticLightNode } from './lighting/AnalyticLightNode.js'; - -// pmrem -export { default as PMREMNode, pmremTexture } from './pmrem/PMREMNode.js'; -export * as PMREMUtils from './pmrem/PMREMUtils.js'; - -// procedural -export { default as CheckerNode, checker } from './procedural/CheckerNode.js'; - -// loaders -export { default as NodeLoader } from './loaders/NodeLoader.js'; -export { default as NodeObjectLoader } from './loaders/NodeObjectLoader.js'; -export { default as NodeMaterialLoader } from './loaders/NodeMaterialLoader.js'; - -// parsers -export { default as GLSLNodeParser } from './parsers/GLSLNodeParser.js'; // @TODO: Move to jsm/renderers/webgl. - -// materials -export * from './materials/Materials.js'; - -// materialX -export * from './materialx/MaterialXNodes.js'; - -// functions -export { default as BRDF_GGX } from './functions/BSDF/BRDF_GGX.js'; -export { default as BRDF_Lambert } from './functions/BSDF/BRDF_Lambert.js'; -export { default as D_GGX } from './functions/BSDF/D_GGX.js'; -export { default as DFGApprox } from './functions/BSDF/DFGApprox.js'; -export { default as F_Schlick } from './functions/BSDF/F_Schlick.js'; -export { default as Schlick_to_F0 } from './functions/BSDF/Schlick_to_F0.js'; -export { default as V_GGX_SmithCorrelated } from './functions/BSDF/V_GGX_SmithCorrelated.js'; - -export { getDistanceAttenuation } from './lighting/LightUtils.js'; - -export { default as getGeometryRoughness } from './functions/material/getGeometryRoughness.js'; -export { default as getRoughness } from './functions/material/getRoughness.js'; - -export { default as PhongLightingModel } from './functions/PhongLightingModel.js'; -export { default as PhysicalLightingModel } from './functions/PhysicalLightingModel.js'; diff --git a/examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts b/examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts deleted file mode 100644 index cc50dba65..000000000 --- a/examples-jsm/examples/nodes/accessors/BufferAttributeNode.ts +++ /dev/null @@ -1,131 +0,0 @@ -import InputNode from '../core/InputNode.js'; -import { addNodeClass } from '../core/Node.js'; -import { varying } from '../core/VaryingNode.js'; -import { nodeObject, addNodeElement } from '../shadernode/ShaderNode.js'; -import { InterleavedBufferAttribute, InterleavedBuffer, StaticDrawUsage, DynamicDrawUsage } from 'three'; - -class BufferAttributeNode extends InputNode { - constructor(value, bufferType = null, bufferStride = 0, bufferOffset = 0) { - super(value, bufferType); - - this.isBufferNode = true; - - this.bufferType = bufferType; - this.bufferStride = bufferStride; - this.bufferOffset = bufferOffset; - - this.usage = StaticDrawUsage; - this.instanced = false; - - this.attribute = null; - - this.global = true; - - if (value && value.isBufferAttribute === true) { - this.attribute = value; - this.usage = value.usage; - this.instanced = value.isInstancedBufferAttribute; - } - } - - getHash(builder) { - if (this.bufferStride === 0 && this.bufferOffset === 0) { - let bufferData = builder.globalCache.getData(this.value); - - if (bufferData === undefined) { - bufferData = { - node: this, - }; - - builder.globalCache.setData(this.value, bufferData); - } - - return bufferData.node.uuid; - } - - return this.uuid; - } - - getNodeType(builder) { - if (this.bufferType === null) { - this.bufferType = builder.getTypeFromAttribute(this.attribute); - } - - return this.bufferType; - } - - setup(builder) { - if (this.attribute !== null) return; - - const type = this.getNodeType(builder); - const array = this.value; - const itemSize = builder.getTypeLength(type); - const stride = this.bufferStride || itemSize; - const offset = this.bufferOffset; - - const buffer = array.isInterleavedBuffer === true ? array : new InterleavedBuffer(array, stride); - const bufferAttribute = new InterleavedBufferAttribute(buffer, itemSize, offset); - - buffer.setUsage(this.usage); - - this.attribute = bufferAttribute; - this.attribute.isInstancedBufferAttribute = this.instanced; // @TODO: Add a possible: InstancedInterleavedBufferAttribute - } - - generate(builder) { - const nodeType = this.getNodeType(builder); - - const nodeAttribute = builder.getBufferAttributeFromNode(this, nodeType); - const propertyName = builder.getPropertyName(nodeAttribute); - - let output = null; - - if (builder.shaderStage === 'vertex' || builder.shaderStage === 'compute') { - this.name = propertyName; - - output = propertyName; - } else { - const nodeVarying = varying(this); - - output = nodeVarying.build(builder, nodeType); - } - - return output; - } - - getInputType(/*builder*/) { - return 'bufferAttribute'; - } - - setUsage(value) { - this.usage = value; - - if (this.attribute && this.attribute.isBufferAttribute === true) { - this.attribute.usage = value; - } - - return this; - } - - setInstanced(value) { - this.instanced = value; - - return this; - } -} - -export default BufferAttributeNode; - -export const bufferAttribute = (array, type, stride, offset) => - nodeObject(new BufferAttributeNode(array, type, stride, offset)); -export const dynamicBufferAttribute = (array, type, stride, offset) => - bufferAttribute(array, type, stride, offset).setUsage(DynamicDrawUsage); - -export const instancedBufferAttribute = (array, type, stride, offset) => - bufferAttribute(array, type, stride, offset).setInstanced(true); -export const instancedDynamicBufferAttribute = (array, type, stride, offset) => - dynamicBufferAttribute(array, type, stride, offset).setInstanced(true); - -addNodeElement('toAttribute', bufferNode => bufferAttribute(bufferNode.value)); - -addNodeClass('BufferAttributeNode', BufferAttributeNode); diff --git a/examples-jsm/examples/nodes/accessors/TextureNode.ts b/examples-jsm/examples/nodes/accessors/TextureNode.ts deleted file mode 100644 index 7852696af..000000000 --- a/examples-jsm/examples/nodes/accessors/TextureNode.ts +++ /dev/null @@ -1,327 +0,0 @@ -import UniformNode, { uniform } from '../core/UniformNode.js'; -import { uv } from './UVNode.js'; -import { textureSize } from './TextureSizeNode.js'; -import { colorSpaceToLinear } from '../display/ColorSpaceNode.js'; -import { expression } from '../code/ExpressionNode.js'; -import { addNodeClass } from '../core/Node.js'; -import { maxMipLevel } from '../utils/MaxMipLevelNode.js'; -import { addNodeElement, nodeProxy, vec3, nodeObject } from '../shadernode/ShaderNode.js'; -import { NodeUpdateType } from '../core/constants.js'; - -class TextureNode extends UniformNode { - constructor(value, uvNode = null, levelNode = null) { - super(value); - - this.isTextureNode = true; - - this.uvNode = uvNode; - this.levelNode = levelNode; - this.compareNode = null; - this.depthNode = null; - this.gradNode = null; - - this.sampler = true; - this.updateMatrix = false; - this.updateType = NodeUpdateType.NONE; - - this.referenceNode = null; - - this._value = value; - - this.setUpdateMatrix(uvNode === null); - } - - set value(value) { - if (this.referenceNode) { - this.referenceNode.value = value; - } else { - this._value = value; - } - } - - get value() { - return this.referenceNode ? this.referenceNode.value : this._value; - } - - getUniformHash(/*builder*/) { - return this.value.uuid; - } - - getNodeType(/*builder*/) { - if (this.value.isDepthTexture === true) return 'float'; - - return 'vec4'; - } - - getInputType(/*builder*/) { - return 'texture'; - } - - getDefaultUV() { - return uv(this.value.channel); - } - - updateReference(/*state*/) { - return this.value; - } - - getTransformedUV(uvNode) { - const texture = this.value; - - return uniform(texture.matrix).mul(vec3(uvNode, 1)).xy; - } - - setUpdateMatrix(value) { - this.updateMatrix = value; - this.updateType = value ? NodeUpdateType.FRAME : NodeUpdateType.NONE; - - return this; - } - - setupUV(builder, uvNode) { - const texture = this.value; - - if ( - builder.isFlipY() && - (texture.isRenderTargetTexture === true || - texture.isFramebufferTexture === true || - texture.isDepthTexture === true) - ) { - uvNode = uvNode.setY(uvNode.y.oneMinus()); - } - - return uvNode; - } - - setup(builder) { - const properties = builder.getNodeProperties(this); - - // - - let uvNode = this.uvNode; - - if ((uvNode === null || builder.context.forceUVContext === true) && builder.context.getUV) { - uvNode = builder.context.getUV(this); - } - - if (!uvNode) uvNode = this.getDefaultUV(); - - if (this.updateMatrix === true) { - uvNode = this.getTransformedUV(uvNode); - } - - uvNode = this.setupUV(builder, uvNode); - - // - - let levelNode = this.levelNode; - - if (levelNode === null && builder.context.getTextureLevel) { - levelNode = builder.context.getTextureLevel(this); - } - - // - - properties.uvNode = uvNode; - properties.levelNode = levelNode; - properties.compareNode = this.compareNode; - properties.gradNode = this.gradNode; - properties.depthNode = this.depthNode; - } - - generateUV(builder, uvNode) { - return uvNode.build(builder, this.sampler === true ? 'vec2' : 'ivec2'); - } - - generateSnippet(builder, textureProperty, uvSnippet, levelSnippet, depthSnippet, compareSnippet, gradSnippet) { - const texture = this.value; - - let snippet; - - if (levelSnippet) { - snippet = builder.generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet, depthSnippet); - } else if (gradSnippet) { - snippet = builder.generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet, depthSnippet); - } else if (compareSnippet) { - snippet = builder.generateTextureCompare(texture, textureProperty, uvSnippet, compareSnippet, depthSnippet); - } else if (this.sampler === false) { - snippet = builder.generateTextureLoad(texture, textureProperty, uvSnippet, depthSnippet); - } else { - snippet = builder.generateTexture(texture, textureProperty, uvSnippet, depthSnippet); - } - - return snippet; - } - - generate(builder, output) { - const properties = builder.getNodeProperties(this); - - const texture = this.value; - - if (!texture || texture.isTexture !== true) { - throw new Error('TextureNode: Need a three.js texture.'); - } - - const textureProperty = super.generate(builder, 'property'); - - if (output === 'sampler') { - return textureProperty + '_sampler'; - } else if (builder.isReference(output)) { - return textureProperty; - } else { - const nodeData = builder.getDataFromNode(this); - - let propertyName = nodeData.propertyName; - - if (propertyName === undefined) { - const { uvNode, levelNode, compareNode, depthNode, gradNode } = properties; - - const uvSnippet = this.generateUV(builder, uvNode); - const levelSnippet = levelNode ? levelNode.build(builder, 'float') : null; - const depthSnippet = depthNode ? depthNode.build(builder, 'int') : null; - const compareSnippet = compareNode ? compareNode.build(builder, 'float') : null; - const gradSnippet = gradNode - ? [gradNode[0].build(builder, 'vec2'), gradNode[1].build(builder, 'vec2')] - : null; - - const nodeVar = builder.getVarFromNode(this); - - propertyName = builder.getPropertyName(nodeVar); - - const snippet = this.generateSnippet( - builder, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - compareSnippet, - gradSnippet, - ); - - builder.addLineFlowCode(`${propertyName} = ${snippet}`); - - nodeData.snippet = snippet; - nodeData.propertyName = propertyName; - } - - let snippet = propertyName; - const nodeType = this.getNodeType(builder); - - if (builder.needsColorSpaceToLinear(texture)) { - snippet = colorSpaceToLinear(expression(snippet, nodeType), texture.colorSpace) - .setup(builder) - .build(builder, nodeType); - } - - return builder.format(snippet, nodeType, output); - } - } - - setSampler(value) { - this.sampler = value; - - return this; - } - - getSampler() { - return this.sampler; - } - - // @TODO: Move to TSL - - uv(uvNode) { - const textureNode = this.clone(); - textureNode.uvNode = uvNode; - textureNode.referenceNode = this; - - return nodeObject(textureNode); - } - - blur(levelNode) { - const textureNode = this.clone(); - textureNode.levelNode = levelNode.mul(maxMipLevel(textureNode)); - textureNode.referenceNode = this; - - return nodeObject(textureNode); - } - - level(levelNode) { - const textureNode = this.clone(); - textureNode.levelNode = levelNode; - textureNode.referenceNode = this; - - return textureNode; - } - - size(levelNode) { - return textureSize(this, levelNode); - } - - compare(compareNode) { - const textureNode = this.clone(); - textureNode.compareNode = nodeObject(compareNode); - textureNode.referenceNode = this; - - return nodeObject(textureNode); - } - - grad(gradNodeX, gradNodeY) { - const textureNode = this.clone(); - textureNode.gradNode = [nodeObject(gradNodeX), nodeObject(gradNodeY)]; - - textureNode.referenceNode = this; - - return nodeObject(textureNode); - } - - depth(depthNode) { - const textureNode = this.clone(); - textureNode.depthNode = nodeObject(depthNode); - textureNode.referenceNode = this; - - return nodeObject(textureNode); - } - - // -- - - serialize(data) { - super.serialize(data); - - data.value = this.value.toJSON(data.meta).uuid; - } - - deserialize(data) { - super.deserialize(data); - - this.value = data.meta.textures[data.value]; - } - - update() { - const texture = this.value; - - if (texture.matrixAutoUpdate === true) { - texture.updateMatrix(); - } - } - - clone() { - const newNode = new this.constructor(this.value, this.uvNode, this.levelNode); - newNode.sampler = this.sampler; - - return newNode; - } -} - -export default TextureNode; - -export const texture = nodeProxy(TextureNode); -export const textureLoad = (...params) => texture(...params).setSampler(false); - -//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level ); - -export const sampler = aTexture => (aTexture.isNode === true ? aTexture : texture(aTexture)).convert('sampler'); - -addNodeElement('texture', texture); -//addNodeElement( 'textureLevel', textureLevel ); - -addNodeClass('TextureNode', TextureNode); diff --git a/examples-jsm/examples/nodes/code/CodeNode.ts b/examples-jsm/examples/nodes/code/CodeNode.ts deleted file mode 100644 index 063475643..000000000 --- a/examples-jsm/examples/nodes/code/CodeNode.ts +++ /dev/null @@ -1,66 +0,0 @@ -import Node, { addNodeClass } from '../core/Node.js'; -import { nodeProxy } from '../shadernode/ShaderNode.js'; - -class CodeNode extends Node { - constructor(code = '', includes = [], language = '') { - super('code'); - - this.isCodeNode = true; - - this.code = code; - this.language = language; - - this.includes = includes; - } - - isGlobal() { - return true; - } - - setIncludes(includes) { - this.includes = includes; - - return this; - } - - getIncludes(/*builder*/) { - return this.includes; - } - - generate(builder) { - const includes = this.getIncludes(builder); - - for (const include of includes) { - include.build(builder); - } - - const nodeCode = builder.getCodeFromNode(this, this.getNodeType(builder)); - nodeCode.code = this.code; - - return nodeCode.code; - } - - serialize(data) { - super.serialize(data); - - data.code = this.code; - data.language = this.language; - } - - deserialize(data) { - super.deserialize(data); - - this.code = data.code; - this.language = data.language; - } -} - -export default CodeNode; - -export const code = nodeProxy(CodeNode); - -export const js = (src, includes) => code(src, includes, 'js'); -export const wgsl = (src, includes) => code(src, includes, 'wgsl'); -export const glsl = (src, includes) => code(src, includes, 'glsl'); - -addNodeClass('CodeNode', CodeNode); diff --git a/examples-jsm/examples/nodes/code/FunctionNode.ts b/examples-jsm/examples/nodes/code/FunctionNode.ts deleted file mode 100644 index feeb5a55c..000000000 --- a/examples-jsm/examples/nodes/code/FunctionNode.ts +++ /dev/null @@ -1,100 +0,0 @@ -import CodeNode from './CodeNode.js'; -import { addNodeClass } from '../core/Node.js'; -import { nodeObject } from '../shadernode/ShaderNode.js'; - -class FunctionNode extends CodeNode { - constructor(code = '', includes = [], language = '') { - super(code, includes, language); - - this.keywords = {}; - } - - getNodeType(builder) { - return this.getNodeFunction(builder).type; - } - - getInputs(builder) { - return this.getNodeFunction(builder).inputs; - } - - getNodeFunction(builder) { - const nodeData = builder.getDataFromNode(this); - - let nodeFunction = nodeData.nodeFunction; - - if (nodeFunction === undefined) { - nodeFunction = builder.parser.parseFunction(this.code); - - nodeData.nodeFunction = nodeFunction; - } - - return nodeFunction; - } - - generate(builder, output) { - super.generate(builder); - - const nodeFunction = this.getNodeFunction(builder); - - const name = nodeFunction.name; - const type = nodeFunction.type; - - const nodeCode = builder.getCodeFromNode(this, type); - - if (name !== '') { - // use a custom property name - - nodeCode.name = name; - } - - const propertyName = builder.getPropertyName(nodeCode); - - let code = this.getNodeFunction(builder).getCode(propertyName); - - const keywords = this.keywords; - const keywordsProperties = Object.keys(keywords); - - if (keywordsProperties.length > 0) { - for (const property of keywordsProperties) { - const propertyRegExp = new RegExp(`\\b${property}\\b`, 'g'); - const nodeProperty = keywords[property].build(builder, 'property'); - - code = code.replace(propertyRegExp, nodeProperty); - } - } - - nodeCode.code = code + '\n'; - - if (output === 'property') { - return propertyName; - } else { - return builder.format(`${propertyName}()`, type, output); - } - } -} - -export default FunctionNode; - -const nativeFn = (code, includes = [], language = '') => { - for (let i = 0; i < includes.length; i++) { - const include = includes[i]; - - // TSL Function: glslFn, wgslFn - - if (typeof include === 'function') { - includes[i] = include.functionNode; - } - } - - const functionNode = nodeObject(new FunctionNode(code, includes, language)); - - const fn = (...params) => functionNode.call(...params); - fn.functionNode = functionNode; - - return fn; -}; - -export const glslFn = (code, includes) => nativeFn(code, includes, 'glsl'); -export const wgslFn = (code, includes) => nativeFn(code, includes, 'wgsl'); - -addNodeClass('FunctionNode', FunctionNode); diff --git a/examples-jsm/examples/nodes/core/ContextNode.ts b/examples-jsm/examples/nodes/core/ContextNode.ts deleted file mode 100644 index fcd488eba..000000000 --- a/examples-jsm/examples/nodes/core/ContextNode.ts +++ /dev/null @@ -1,55 +0,0 @@ -import Node, { addNodeClass } from './Node.js'; -import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js'; - -class ContextNode extends Node { - constructor(node, context = {}) { - super(); - - this.isContextNode = true; - - this.node = node; - this.context = context; - } - - getNodeType(builder) { - return this.node.getNodeType(builder); - } - - analyze(builder) { - this.node.build(builder); - } - - setup(builder) { - const previousContext = builder.getContext(); - - builder.setContext({ ...builder.context, ...this.context }); - - const node = this.node.build(builder); - - builder.setContext(previousContext); - - return node; - } - - generate(builder, output) { - const previousContext = builder.getContext(); - - builder.setContext({ ...builder.context, ...this.context }); - - const snippet = this.node.build(builder, output); - - builder.setContext(previousContext); - - return snippet; - } -} - -export default ContextNode; - -export const context = nodeProxy(ContextNode); -export const label = (node, name) => context(node, { label: name }); - -addNodeElement('context', context); -addNodeElement('label', label); - -addNodeClass('ContextNode', ContextNode); diff --git a/examples-jsm/examples/nodes/core/InputNode.ts b/examples-jsm/examples/nodes/core/InputNode.ts deleted file mode 100644 index 4d52ec26f..000000000 --- a/examples-jsm/examples/nodes/core/InputNode.ts +++ /dev/null @@ -1,65 +0,0 @@ -import Node, { addNodeClass } from './Node.js'; -import { getValueType, getValueFromType, arrayBufferToBase64 } from './NodeUtils.js'; - -class InputNode extends Node { - constructor(value, nodeType = null) { - super(nodeType); - - this.isInputNode = true; - - this.value = value; - this.precision = null; - } - - getNodeType(/*builder*/) { - if (this.nodeType === null) { - return getValueType(this.value); - } - - return this.nodeType; - } - - getInputType(builder) { - return this.getNodeType(builder); - } - - setPrecision(precision) { - this.precision = precision; - - return this; - } - - serialize(data) { - super.serialize(data); - - data.value = this.value; - - if (this.value && this.value.toArray) data.value = this.value.toArray(); - - data.valueType = getValueType(this.value); - data.nodeType = this.nodeType; - - if (data.valueType === 'ArrayBuffer') data.value = arrayBufferToBase64(data.value); - - data.precision = this.precision; - } - - deserialize(data) { - super.deserialize(data); - - this.nodeType = data.nodeType; - this.value = Array.isArray(data.value) ? getValueFromType(data.valueType, ...data.value) : data.value; - - this.precision = data.precision || null; - - if (this.value && this.value.fromArray) this.value = this.value.fromArray(data.value); - } - - generate(/*builder, output*/) { - console.warn('Abstract function.'); - } -} - -export default InputNode; - -addNodeClass('InputNode', InputNode); diff --git a/examples-jsm/examples/nodes/core/Node.ts b/examples-jsm/examples/nodes/core/Node.ts deleted file mode 100644 index 66444172d..000000000 --- a/examples-jsm/examples/nodes/core/Node.ts +++ /dev/null @@ -1,424 +0,0 @@ -import { EventDispatcher } from 'three'; -import { NodeUpdateType } from './constants.js'; -import { getNodeChildren, getCacheKey } from './NodeUtils.js'; -import { MathUtils } from 'three'; - -const NodeClasses = new Map(); - -let _nodeId = 0; - -class Node extends EventDispatcher { - constructor(nodeType = null) { - super(); - - this.nodeType = nodeType; - - this.updateType = NodeUpdateType.NONE; - this.updateBeforeType = NodeUpdateType.NONE; - this.updateAfterType = NodeUpdateType.NONE; - - this.uuid = MathUtils.generateUUID(); - - this.version = 0; - - this._cacheKey = null; - this._cacheKeyVersion = 0; - - this.global = false; - - this.isNode = true; - - Object.defineProperty(this, 'id', { value: _nodeId++ }); - } - - set needsUpdate(value) { - if (value === true) { - this.version++; - } - } - - get type() { - return this.constructor.type; - } - - onUpdate(callback, updateType) { - this.updateType = updateType; - this.update = callback.bind(this.getSelf()); - - return this; - } - - onFrameUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.FRAME); - } - - onRenderUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.RENDER); - } - - onObjectUpdate(callback) { - return this.onUpdate(callback, NodeUpdateType.OBJECT); - } - - onReference(callback) { - this.updateReference = callback.bind(this.getSelf()); - - return this; - } - - getSelf() { - // Returns non-node object. - - return this.self || this; - } - - updateReference(/*state*/) { - return this; - } - - isGlobal(/*builder*/) { - return this.global; - } - - *getChildren() { - for (const { childNode } of getNodeChildren(this)) { - yield childNode; - } - } - - dispose() { - this.dispatchEvent({ type: 'dispose' }); - } - - traverse(callback) { - callback(this); - - for (const childNode of this.getChildren()) { - childNode.traverse(callback); - } - } - - getCacheKey(force = false) { - force = force || this.version !== this._cacheKeyVersion; - - if (force === true || this._cacheKey === null) { - this._cacheKey = getCacheKey(this, force); - this._cacheKeyVersion = this.version; - } - - return this._cacheKey; - } - - getHash(/*builder*/) { - return this.uuid; - } - - getUpdateType() { - return this.updateType; - } - - getUpdateBeforeType() { - return this.updateBeforeType; - } - - getUpdateAfterType() { - return this.updateAfterType; - } - - getElementType(builder) { - const type = this.getNodeType(builder); - const elementType = builder.getElementType(type); - - return elementType; - } - - getNodeType(builder) { - const nodeProperties = builder.getNodeProperties(this); - - if (nodeProperties.outputNode) { - return nodeProperties.outputNode.getNodeType(builder); - } - - return this.nodeType; - } - - getShared(builder) { - const hash = this.getHash(builder); - const nodeFromHash = builder.getNodeFromHash(hash); - - return nodeFromHash || this; - } - - setup(builder) { - const nodeProperties = builder.getNodeProperties(this); - - let index = 0; - - for (const childNode of this.getChildren()) { - nodeProperties['node' + index++] = childNode; - } - - // return a outputNode if exists - return null; - } - - construct(builder) { - // @deprecated, r157 - - console.warn('THREE.Node: construct() is deprecated. Use setup() instead.'); - - return this.setup(builder); - } - - increaseUsage(builder) { - const nodeData = builder.getDataFromNode(this); - nodeData.usageCount = nodeData.usageCount === undefined ? 1 : nodeData.usageCount + 1; - - return nodeData.usageCount; - } - - analyze(builder) { - const usageCount = this.increaseUsage(builder); - - if (usageCount === 1) { - // node flow children - - const nodeProperties = builder.getNodeProperties(this); - - for (const childNode of Object.values(nodeProperties)) { - if (childNode && childNode.isNode === true) { - childNode.build(builder); - } - } - } - } - - generate(builder, output) { - const { outputNode } = builder.getNodeProperties(this); - - if (outputNode && outputNode.isNode === true) { - return outputNode.build(builder, output); - } - } - - updateBefore(/*frame*/) { - console.warn('Abstract function.'); - } - - updateAfter(/*frame*/) { - console.warn('Abstract function.'); - } - - update(/*frame*/) { - console.warn('Abstract function.'); - } - - build(builder, output = null) { - const refNode = this.getShared(builder); - - if (this !== refNode) { - return refNode.build(builder, output); - } - - builder.addNode(this); - builder.addChain(this); - - /* Build stages expected results: - - "setup" -> Node - - "analyze" -> null - - "generate" -> String - */ - let result = null; - - const buildStage = builder.getBuildStage(); - - if (buildStage === 'setup') { - this.updateReference(builder); - - const properties = builder.getNodeProperties(this); - - if (properties.initialized !== true) { - const stackNodesBeforeSetup = builder.stack.nodes.length; - - properties.initialized = true; - properties.outputNode = this.setup(builder); - - if (properties.outputNode !== null && builder.stack.nodes.length !== stackNodesBeforeSetup) { - properties.outputNode = builder.stack; - } - - for (const childNode of Object.values(properties)) { - if (childNode && childNode.isNode === true) { - childNode.build(builder); - } - } - } - } else if (buildStage === 'analyze') { - this.analyze(builder); - } else if (buildStage === 'generate') { - const isGenerateOnce = this.generate.length === 1; - - if (isGenerateOnce) { - const type = this.getNodeType(builder); - const nodeData = builder.getDataFromNode(this); - - result = nodeData.snippet; - - if (result === undefined) { - result = this.generate(builder) || ''; - - nodeData.snippet = result; - } - - result = builder.format(result, type, output); - } else { - result = this.generate(builder, output) || ''; - } - } - - builder.removeChain(this); - - return result; - } - - getSerializeChildren() { - return getNodeChildren(this); - } - - serialize(json) { - const nodeChildren = this.getSerializeChildren(); - - const inputNodes = {}; - - for (const { property, index, childNode } of nodeChildren) { - if (index !== undefined) { - if (inputNodes[property] === undefined) { - inputNodes[property] = Number.isInteger(index) ? [] : {}; - } - - inputNodes[property][index] = childNode.toJSON(json.meta).uuid; - } else { - inputNodes[property] = childNode.toJSON(json.meta).uuid; - } - } - - if (Object.keys(inputNodes).length > 0) { - json.inputNodes = inputNodes; - } - } - - deserialize(json) { - if (json.inputNodes !== undefined) { - const nodes = json.meta.nodes; - - for (const property in json.inputNodes) { - if (Array.isArray(json.inputNodes[property])) { - const inputArray = []; - - for (const uuid of json.inputNodes[property]) { - inputArray.push(nodes[uuid]); - } - - this[property] = inputArray; - } else if (typeof json.inputNodes[property] === 'object') { - const inputObject = {}; - - for (const subProperty in json.inputNodes[property]) { - const uuid = json.inputNodes[property][subProperty]; - - inputObject[subProperty] = nodes[uuid]; - } - - this[property] = inputObject; - } else { - const uuid = json.inputNodes[property]; - - this[property] = nodes[uuid]; - } - } - } - } - - toJSON(meta) { - const { uuid, type } = this; - const isRoot = meta === undefined || typeof meta === 'string'; - - if (isRoot) { - meta = { - textures: {}, - images: {}, - nodes: {}, - }; - } - - // serialize - - let data = meta.nodes[uuid]; - - if (data === undefined) { - data = { - uuid, - type, - meta, - metadata: { - version: 4.6, - type: 'Node', - generator: 'Node.toJSON', - }, - }; - - if (isRoot !== true) meta.nodes[data.uuid] = data; - - this.serialize(data); - - delete data.meta; - } - - // TODO: Copied from Object3D.toJSON - - function extractFromCache(cache) { - const values = []; - - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } - - return values; - } - - if (isRoot) { - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const nodes = extractFromCache(meta.nodes); - - if (textures.length > 0) data.textures = textures; - if (images.length > 0) data.images = images; - if (nodes.length > 0) data.nodes = nodes; - } - - return data; - } -} - -export default Node; - -export function addNodeClass(type, nodeClass) { - if (typeof nodeClass !== 'function' || !type) throw new Error(`Node class ${type} is not a class`); - if (NodeClasses.has(type)) { - console.warn(`Redefinition of node class ${type}`); - return; - } - - NodeClasses.set(type, nodeClass); - nodeClass.type = type; -} - -export function createNodeFromType(type) { - const Class = NodeClasses.get(type); - - if (Class !== undefined) { - return new Class(); - } -} diff --git a/examples-jsm/examples/nodes/core/NodeAttribute.ts b/examples-jsm/examples/nodes/core/NodeAttribute.ts deleted file mode 100644 index 190fe8c51..000000000 --- a/examples-jsm/examples/nodes/core/NodeAttribute.ts +++ /dev/null @@ -1,11 +0,0 @@ -class NodeAttribute { - constructor(name, type, node = null) { - this.isNodeAttribute = true; - - this.name = name; - this.type = type; - this.node = node; - } -} - -export default NodeAttribute; diff --git a/examples-jsm/examples/nodes/core/NodeBuilder.ts b/examples-jsm/examples/nodes/core/NodeBuilder.ts deleted file mode 100644 index 2559a675f..000000000 --- a/examples-jsm/examples/nodes/core/NodeBuilder.ts +++ /dev/null @@ -1,1119 +0,0 @@ -import NodeUniform from './NodeUniform.js'; -import NodeAttribute from './NodeAttribute.js'; -import NodeVarying from './NodeVarying.js'; -import NodeVar from './NodeVar.js'; -import NodeCode from './NodeCode.js'; -import NodeKeywords from './NodeKeywords.js'; -import NodeCache from './NodeCache.js'; -import ParameterNode from './ParameterNode.js'; -import FunctionNode from '../code/FunctionNode.js'; -import { createNodeMaterialFromType, default as NodeMaterial } from '../materials/NodeMaterial.js'; -import { NodeUpdateType, defaultBuildStages, shaderStages } from './constants.js'; - -import { - NumberNodeUniform, - Vector2NodeUniform, - Vector3NodeUniform, - Vector4NodeUniform, - ColorNodeUniform, - Matrix3NodeUniform, - Matrix4NodeUniform, -} from '../../renderers/common/nodes/NodeUniform.js'; - -import BindGroup from '../../renderers/common/BindGroup.js'; - -import { - REVISION, - RenderTarget, - Color, - Vector2, - Vector3, - Vector4, - IntType, - UnsignedIntType, - Float16BufferAttribute, - LinearFilter, - LinearMipmapNearestFilter, - NearestMipmapLinearFilter, - LinearMipmapLinearFilter, -} from 'three'; - -import { stack } from './StackNode.js'; -import { getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js'; - -import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; -import ChainMap from '../../renderers/common/ChainMap.js'; - -import PMREMGenerator from '../../renderers/common/extras/PMREMGenerator.js'; - -const rendererCache = new WeakMap(); - -const typeFromLength = new Map([ - [2, 'vec2'], - [3, 'vec3'], - [4, 'vec4'], - [9, 'mat3'], - [16, 'mat4'], -]); - -const typeFromArray = new Map([ - [Int8Array, 'int'], - [Int16Array, 'int'], - [Int32Array, 'int'], - [Uint8Array, 'uint'], - [Uint16Array, 'uint'], - [Uint32Array, 'uint'], - [Float32Array, 'float'], -]); - -const toFloat = value => { - value = Number(value); - - return value + (value % 1 ? '' : '.0'); -}; - -class NodeBuilder { - constructor(object, renderer, parser) { - this.object = object; - this.material = (object && object.material) || null; - this.geometry = (object && object.geometry) || null; - this.renderer = renderer; - this.parser = parser; - this.scene = null; - this.camera = null; - - this.nodes = []; - this.updateNodes = []; - this.updateBeforeNodes = []; - this.updateAfterNodes = []; - this.hashNodes = {}; - - this.lightsNode = null; - this.environmentNode = null; - this.fogNode = null; - - this.clippingContext = null; - - this.vertexShader = null; - this.fragmentShader = null; - this.computeShader = null; - - this.flowNodes = { vertex: [], fragment: [], compute: [] }; - this.flowCode = { vertex: '', fragment: '', compute: '' }; - this.uniforms = { vertex: [], fragment: [], compute: [], index: 0 }; - this.structs = { vertex: [], fragment: [], compute: [], index: 0 }; - this.bindings = { vertex: {}, fragment: {}, compute: {} }; - this.bindingsIndexes = {}; - this.bindGroups = null; - this.attributes = []; - this.bufferAttributes = []; - this.varyings = []; - this.codes = {}; - this.vars = {}; - this.flow = { code: '' }; - this.chaining = []; - this.stack = stack(); - this.stacks = []; - this.tab = '\t'; - - this.instanceBindGroups = true; - - this.currentFunctionNode = null; - - this.context = { - keywords: new NodeKeywords(), - material: this.material, - }; - - this.cache = new NodeCache(); - this.globalCache = this.cache; - - this.flowsData = new WeakMap(); - - this.shaderStage = null; - this.buildStage = null; - } - - getBingGroupsCache() { - let bindGroupsCache = rendererCache.get(this.renderer); - - if (bindGroupsCache === undefined) { - bindGroupsCache = new ChainMap(); - - rendererCache.set(this.renderer, bindGroupsCache); - } - - return bindGroupsCache; - } - - createRenderTarget(width, height, options) { - return new RenderTarget(width, height, options); - } - - createCubeRenderTarget(size, options) { - return new CubeRenderTarget(size, options); - } - - createPMREMGenerator() { - // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support - - return new PMREMGenerator(this.renderer); - } - - includes(node) { - return this.nodes.includes(node); - } - - _getBindGroup(groupName, bindings) { - const bindGroupsCache = this.getBingGroupsCache(); - - // cache individual uniforms group - - const bindingsArray = []; - - let sharedGroup = true; - - for (const binding of bindings) { - if (binding.groupNode.shared === true) { - // nodes is the chainmap key - const nodes = binding.getNodes(); - - let sharedBinding = bindGroupsCache.get(nodes); - - if (sharedBinding === undefined) { - bindGroupsCache.set(nodes, binding); - - sharedBinding = binding; - } - - bindingsArray.push(sharedBinding); - } else { - bindingsArray.push(binding); - - sharedGroup = false; - } - } - - // - - let bindGroup; - - if (sharedGroup) { - bindGroup = bindGroupsCache.get(bindingsArray); - - if (bindGroup === undefined) { - bindGroup = new BindGroup(groupName, bindingsArray); - bindGroupsCache.set(bindingsArray, bindGroup); - } - } else { - bindGroup = new BindGroup(groupName, bindingsArray); - } - - return bindGroup; - } - - getBindGroupArray(groupName, shaderStage) { - const bindings = this.bindings[shaderStage]; - - let bindGroup = bindings[groupName]; - - if (bindGroup === undefined) { - if (this.bindingsIndexes[groupName] === undefined) { - this.bindingsIndexes[groupName] = { binding: 0, group: Object.keys(this.bindingsIndexes).length }; - } - - bindings[groupName] = bindGroup = []; - } - - return bindGroup; - } - - getBindings() { - let bindingsGroups = this.bindGroups; - - if (bindingsGroups === null) { - const groups = {}; - const bindings = this.bindings; - - for (const shaderStage of shaderStages) { - for (const groupName in bindings[shaderStage]) { - const uniforms = bindings[shaderStage][groupName]; - - const groupUniforms = groups[groupName] || (groups[groupName] = []); - groupUniforms.push(...uniforms); - } - } - - bindingsGroups = []; - - for (const groupName in groups) { - const group = groups[groupName]; - - const bindingsGroup = this._getBindGroup(groupName, group); - - bindingsGroups.push(bindingsGroup); - } - - this.bindGroups = bindingsGroups; - } - - return bindingsGroups; - } - - setHashNode(node, hash) { - this.hashNodes[hash] = node; - } - - addNode(node) { - if (this.nodes.includes(node) === false) { - this.nodes.push(node); - - this.setHashNode(node, node.getHash(this)); - } - } - - buildUpdateNodes() { - for (const node of this.nodes) { - const updateType = node.getUpdateType(); - const updateBeforeType = node.getUpdateBeforeType(); - const updateAfterType = node.getUpdateAfterType(); - - if (updateType !== NodeUpdateType.NONE) { - this.updateNodes.push(node.getSelf()); - } - - if (updateBeforeType !== NodeUpdateType.NONE) { - this.updateBeforeNodes.push(node); - } - - if (updateAfterType !== NodeUpdateType.NONE) { - this.updateAfterNodes.push(node); - } - } - } - - get currentNode() { - return this.chaining[this.chaining.length - 1]; - } - - isFilteredTexture(texture) { - return ( - texture.magFilter === LinearFilter || - texture.magFilter === LinearMipmapNearestFilter || - texture.magFilter === NearestMipmapLinearFilter || - texture.magFilter === LinearMipmapLinearFilter || - texture.minFilter === LinearFilter || - texture.minFilter === LinearMipmapNearestFilter || - texture.minFilter === NearestMipmapLinearFilter || - texture.minFilter === LinearMipmapLinearFilter - ); - } - - addChain(node) { - /* - if ( this.chaining.indexOf( node ) !== - 1 ) { - - console.warn( 'Recursive node: ', node ); - - } - */ - - this.chaining.push(node); - } - - removeChain(node) { - const lastChain = this.chaining.pop(); - - if (lastChain !== node) { - throw new Error('NodeBuilder: Invalid node chaining!'); - } - } - - getMethod(method) { - return method; - } - - getNodeFromHash(hash) { - return this.hashNodes[hash]; - } - - addFlow(shaderStage, node) { - this.flowNodes[shaderStage].push(node); - - return node; - } - - setContext(context) { - this.context = context; - } - - getContext() { - return this.context; - } - - setCache(cache) { - this.cache = cache; - } - - getCache() { - return this.cache; - } - - getCacheFromNode(node, parent = true) { - const data = this.getDataFromNode(node); - if (data.cache === undefined) data.cache = new NodeCache(parent ? this.getCache() : null); - - return data.cache; - } - - isAvailable(/*name*/) { - return false; - } - - getVertexIndex() { - console.warn('Abstract function.'); - } - - getInstanceIndex() { - console.warn('Abstract function.'); - } - - getFrontFacing() { - console.warn('Abstract function.'); - } - - getFragCoord() { - console.warn('Abstract function.'); - } - - isFlipY() { - return false; - } - - generateTexture(/* texture, textureProperty, uvSnippet */) { - console.warn('Abstract function.'); - } - - generateTextureLod(/* texture, textureProperty, uvSnippet, levelSnippet */) { - console.warn('Abstract function.'); - } - - generateConst(type, value = null) { - if (value === null) { - if (type === 'float' || type === 'int' || type === 'uint') value = 0; - else if (type === 'bool') value = false; - else if (type === 'color') value = new Color(); - else if (type === 'vec2') value = new Vector2(); - else if (type === 'vec3') value = new Vector3(); - else if (type === 'vec4') value = new Vector4(); - } - - if (type === 'float') return toFloat(value); - if (type === 'int') return `${Math.round(value)}`; - if (type === 'uint') return value >= 0 ? `${Math.round(value)}u` : '0u'; - if (type === 'bool') return value ? 'true' : 'false'; - if (type === 'color') - return `${this.getType('vec3')}( ${toFloat(value.r)}, ${toFloat(value.g)}, ${toFloat(value.b)} )`; - - const typeLength = this.getTypeLength(type); - - const componentType = this.getComponentType(type); - - const generateConst = value => this.generateConst(componentType, value); - - if (typeLength === 2) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)} )`; - } else if (typeLength === 3) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)} )`; - } else if (typeLength === 4) { - return `${this.getType(type)}( ${generateConst(value.x)}, ${generateConst(value.y)}, ${generateConst(value.z)}, ${generateConst(value.w)} )`; - } else if (typeLength > 4 && value && (value.isMatrix3 || value.isMatrix4)) { - return `${this.getType(type)}( ${value.elements.map(generateConst).join(', ')} )`; - } else if (typeLength > 4) { - return `${this.getType(type)}()`; - } - - throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); - } - - getType(type) { - if (type === 'color') return 'vec3'; - - return type; - } - - hasGeometryAttribute(name) { - return this.geometry && this.geometry.getAttribute(name) !== undefined; - } - - getAttribute(name, type) { - const attributes = this.attributes; - - // find attribute - - for (const attribute of attributes) { - if (attribute.name === name) { - return attribute; - } - } - - // create a new if no exist - - const attribute = new NodeAttribute(name, type); - - attributes.push(attribute); - - return attribute; - } - - getPropertyName(node /*, shaderStage*/) { - return node.name; - } - - isVector(type) { - return /vec\d/.test(type); - } - - isMatrix(type) { - return /mat\d/.test(type); - } - - isReference(type) { - return ( - type === 'void' || - type === 'property' || - type === 'sampler' || - type === 'texture' || - type === 'cubeTexture' || - type === 'storageTexture' || - type === 'depthTexture' || - type === 'texture3D' - ); - } - - needsColorSpaceToLinear(/*texture*/) { - return false; - } - - getComponentTypeFromTexture(texture) { - const type = texture.type; - - if (texture.isDataTexture) { - if (type === IntType) return 'int'; - if (type === UnsignedIntType) return 'uint'; - } - - return 'float'; - } - - getElementType(type) { - if (type === 'mat2') return 'vec2'; - if (type === 'mat3') return 'vec3'; - if (type === 'mat4') return 'vec4'; - - return this.getComponentType(type); - } - - getComponentType(type) { - type = this.getVectorType(type); - - if (type === 'float' || type === 'bool' || type === 'int' || type === 'uint') return type; - - const componentType = /(b|i|u|)(vec|mat)([2-4])/.exec(type); - - if (componentType === null) return null; - - if (componentType[1] === 'b') return 'bool'; - if (componentType[1] === 'i') return 'int'; - if (componentType[1] === 'u') return 'uint'; - - return 'float'; - } - - getVectorType(type) { - if (type === 'color') return 'vec3'; - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') - return 'vec4'; - - return type; - } - - getTypeFromLength(length, componentType = 'float') { - if (length === 1) return componentType; - - const baseType = typeFromLength.get(length); - const prefix = componentType === 'float' ? '' : componentType[0]; - - return prefix + baseType; - } - - getTypeFromArray(array) { - return typeFromArray.get(array.constructor); - } - - getTypeFromAttribute(attribute) { - let dataAttribute = attribute; - - if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; - - const array = dataAttribute.array; - const itemSize = attribute.itemSize; - const normalized = attribute.normalized; - - let arrayType; - - if (!(attribute instanceof Float16BufferAttribute) && normalized !== true) { - arrayType = this.getTypeFromArray(array); - } - - return this.getTypeFromLength(itemSize, arrayType); - } - - getTypeLength(type) { - const vecType = this.getVectorType(type); - const vecNum = /vec([2-4])/.exec(vecType); - - if (vecNum !== null) return Number(vecNum[1]); - if (vecType === 'float' || vecType === 'bool' || vecType === 'int' || vecType === 'uint') return 1; - if (/mat2/.test(type) === true) return 4; - if (/mat3/.test(type) === true) return 9; - if (/mat4/.test(type) === true) return 16; - - return 0; - } - - getVectorFromMatrix(type) { - return type.replace('mat', 'vec'); - } - - changeComponentType(type, newComponentType) { - return this.getTypeFromLength(this.getTypeLength(type), newComponentType); - } - - getIntegerType(type) { - const componentType = this.getComponentType(type); - - if (componentType === 'int' || componentType === 'uint') return type; - - return this.changeComponentType(type, 'int'); - } - - addStack() { - this.stack = stack(this.stack); - - this.stacks.push(getCurrentStack() || this.stack); - setCurrentStack(this.stack); - - return this.stack; - } - - removeStack() { - const lastStack = this.stack; - this.stack = lastStack.parent; - - setCurrentStack(this.stacks.pop()); - - return lastStack; - } - - getDataFromNode(node, shaderStage = this.shaderStage, cache = null) { - cache = cache === null ? (node.isGlobal(this) ? this.globalCache : this.cache) : cache; - - let nodeData = cache.getData(node); - - if (nodeData === undefined) { - nodeData = {}; - - cache.setData(node, nodeData); - } - - if (nodeData[shaderStage] === undefined) nodeData[shaderStage] = {}; - - return nodeData[shaderStage]; - } - - getNodeProperties(node, shaderStage = 'any') { - const nodeData = this.getDataFromNode(node, shaderStage); - - return nodeData.properties || (nodeData.properties = { outputNode: null }); - } - - getBufferAttributeFromNode(node, type) { - const nodeData = this.getDataFromNode(node); - - let bufferAttribute = nodeData.bufferAttribute; - - if (bufferAttribute === undefined) { - const index = this.uniforms.index++; - - bufferAttribute = new NodeAttribute('nodeAttribute' + index, type, node); - - this.bufferAttributes.push(bufferAttribute); - - nodeData.bufferAttribute = bufferAttribute; - } - - return bufferAttribute; - } - - getStructTypeFromNode(node, shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node, shaderStage); - - if (nodeData.structType === undefined) { - const index = this.structs.index++; - - node.name = `StructType${index}`; - this.structs[shaderStage].push(node); - - nodeData.structType = node; - } - - return node; - } - - getUniformFromNode(node, type, shaderStage = this.shaderStage, name = null) { - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - let nodeUniform = nodeData.uniform; - - if (nodeUniform === undefined) { - const index = this.uniforms.index++; - - nodeUniform = new NodeUniform(name || 'nodeUniform' + index, type, node); - - this.uniforms[shaderStage].push(nodeUniform); - - nodeData.uniform = nodeUniform; - } - - return nodeUniform; - } - - getVarFromNode(node, name = null, type = node.getNodeType(this), shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node, shaderStage); - - let nodeVar = nodeData.variable; - - if (nodeVar === undefined) { - const vars = this.vars[shaderStage] || (this.vars[shaderStage] = []); - - if (name === null) name = 'nodeVar' + vars.length; - - nodeVar = new NodeVar(name, type); - - vars.push(nodeVar); - - nodeData.variable = nodeVar; - } - - return nodeVar; - } - - getVaryingFromNode(node, name = null, type = node.getNodeType(this)) { - const nodeData = this.getDataFromNode(node, 'any'); - - let nodeVarying = nodeData.varying; - - if (nodeVarying === undefined) { - const varyings = this.varyings; - const index = varyings.length; - - if (name === null) name = 'nodeVarying' + index; - - nodeVarying = new NodeVarying(name, type); - - varyings.push(nodeVarying); - - nodeData.varying = nodeVarying; - } - - return nodeVarying; - } - - getCodeFromNode(node, type, shaderStage = this.shaderStage) { - const nodeData = this.getDataFromNode(node); - - let nodeCode = nodeData.code; - - if (nodeCode === undefined) { - const codes = this.codes[shaderStage] || (this.codes[shaderStage] = []); - const index = codes.length; - - nodeCode = new NodeCode('nodeCode' + index, type); - - codes.push(nodeCode); - - nodeData.code = nodeCode; - } - - return nodeCode; - } - - addLineFlowCode(code) { - if (code === '') return this; - - code = this.tab + code; - - if (!/;\s*$/.test(code)) { - code = code + ';\n'; - } - - this.flow.code += code; - - return this; - } - - addFlowCode(code) { - this.flow.code += code; - - return this; - } - - addFlowTab() { - this.tab += '\t'; - - return this; - } - - removeFlowTab() { - this.tab = this.tab.slice(0, -1); - - return this; - } - - getFlowData(node /*, shaderStage*/) { - return this.flowsData.get(node); - } - - flowNode(node) { - const output = node.getNodeType(this); - - const flowData = this.flowChildNode(node, output); - - this.flowsData.set(node, flowData); - - return flowData; - } - - buildFunctionNode(shaderNode) { - const fn = new FunctionNode(); - - const previous = this.currentFunctionNode; - - this.currentFunctionNode = fn; - - fn.code = this.buildFunctionCode(shaderNode); - - this.currentFunctionNode = previous; - - return fn; - } - - flowShaderNode(shaderNode) { - const layout = shaderNode.layout; - - let inputs; - - if (shaderNode.isArrayInput) { - inputs = []; - - for (const input of layout.inputs) { - inputs.push(new ParameterNode(input.type, input.name)); - } - } else { - inputs = {}; - - for (const input of layout.inputs) { - inputs[input.name] = new ParameterNode(input.type, input.name); - } - } - - // - - shaderNode.layout = null; - - const callNode = shaderNode.call(inputs); - const flowData = this.flowStagesNode(callNode, layout.type); - - shaderNode.layout = layout; - - return flowData; - } - - flowStagesNode(node, output = null) { - const previousFlow = this.flow; - const previousVars = this.vars; - const previousCache = this.cache; - const previousBuildStage = this.buildStage; - const previousStack = this.stack; - - const flow = { - code: '', - }; - - this.flow = flow; - this.vars = {}; - this.cache = new NodeCache(); - this.stack = stack(); - - for (const buildStage of defaultBuildStages) { - this.setBuildStage(buildStage); - - flow.result = node.build(this, output); - } - - flow.vars = this.getVars(this.shaderStage); - - this.flow = previousFlow; - this.vars = previousVars; - this.cache = previousCache; - this.stack = previousStack; - - this.setBuildStage(previousBuildStage); - - return flow; - } - - getFunctionOperator() { - return null; - } - - flowChildNode(node, output = null) { - const previousFlow = this.flow; - - const flow = { - code: '', - }; - - this.flow = flow; - - flow.result = node.build(this, output); - - this.flow = previousFlow; - - return flow; - } - - flowNodeFromShaderStage(shaderStage, node, output = null, propertyName = null) { - const previousShaderStage = this.shaderStage; - - this.setShaderStage(shaderStage); - - const flowData = this.flowChildNode(node, output); - - if (propertyName !== null) { - flowData.code += `${this.tab + propertyName} = ${flowData.result};\n`; - } - - this.flowCode[shaderStage] = this.flowCode[shaderStage] + flowData.code; - - this.setShaderStage(previousShaderStage); - - return flowData; - } - - getAttributesArray() { - return this.attributes.concat(this.bufferAttributes); - } - - getAttributes(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getVaryings(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getVar(type, name) { - return `${this.getType(type)} ${name}`; - } - - getVars(shaderStage) { - let snippet = ''; - - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippet += `${this.getVar(variable.type, variable.name)}; `; - } - } - - return snippet; - } - - getUniforms(/*shaderStage*/) { - console.warn('Abstract function.'); - } - - getCodes(shaderStage) { - const codes = this.codes[shaderStage]; - - let code = ''; - - if (codes !== undefined) { - for (const nodeCode of codes) { - code += nodeCode.code + '\n'; - } - } - - return code; - } - - getHash() { - return this.vertexShader + this.fragmentShader + this.computeShader; - } - - setShaderStage(shaderStage) { - this.shaderStage = shaderStage; - } - - getShaderStage() { - return this.shaderStage; - } - - setBuildStage(buildStage) { - this.buildStage = buildStage; - } - - getBuildStage() { - return this.buildStage; - } - - buildCode() { - console.warn('Abstract function.'); - } - - build() { - const { object, material } = this; - - if (material !== null) { - NodeMaterial.fromMaterial(material).build(this); - } else { - this.addFlow('compute', object); - } - - // setup() -> stage 1: create possible new nodes and returns an output reference node - // analyze() -> stage 2: analyze nodes to possible optimization and validation - // generate() -> stage 3: generate shader - - for (const buildStage of defaultBuildStages) { - this.setBuildStage(buildStage); - - if (this.context.vertex && this.context.vertex.isNode) { - this.flowNodeFromShaderStage('vertex', this.context.vertex); - } - - for (const shaderStage of shaderStages) { - this.setShaderStage(shaderStage); - - const flowNodes = this.flowNodes[shaderStage]; - - for (const node of flowNodes) { - if (buildStage === 'generate') { - this.flowNode(node); - } else { - node.build(this); - } - } - } - } - - this.setBuildStage(null); - this.setShaderStage(null); - - // stage 4: build code for a specific output - - this.buildCode(); - this.buildUpdateNodes(); - - return this; - } - - getNodeUniform(uniformNode, type) { - if (type === 'float' || type === 'int' || type === 'uint') return new NumberNodeUniform(uniformNode); - if (type === 'vec2' || type === 'ivec2' || type === 'uvec2') return new Vector2NodeUniform(uniformNode); - if (type === 'vec3' || type === 'ivec3' || type === 'uvec3') return new Vector3NodeUniform(uniformNode); - if (type === 'vec4' || type === 'ivec4' || type === 'uvec4') return new Vector4NodeUniform(uniformNode); - if (type === 'color') return new ColorNodeUniform(uniformNode); - if (type === 'mat3') return new Matrix3NodeUniform(uniformNode); - if (type === 'mat4') return new Matrix4NodeUniform(uniformNode); - - throw new Error(`Uniform "${type}" not declared.`); - } - - createNodeMaterial(type = 'NodeMaterial') { - // TODO: Move Materials.js to outside of the Nodes.js in order to remove this function and improve tree-shaking support - - return createNodeMaterialFromType(type); - } - - format(snippet, fromType, toType) { - fromType = this.getVectorType(fromType); - toType = this.getVectorType(toType); - - if (fromType === toType || toType === null || this.isReference(toType)) { - return snippet; - } - - const fromTypeLength = this.getTypeLength(fromType); - const toTypeLength = this.getTypeLength(toType); - - if (fromTypeLength > 4) { - // fromType is matrix-like - - // @TODO: ignore for now - - return snippet; - } - - if (toTypeLength > 4 || toTypeLength === 0) { - // toType is matrix-like or unknown - - // @TODO: ignore for now - - return snippet; - } - - if (fromTypeLength === toTypeLength) { - return `${this.getType(toType)}( ${snippet} )`; - } - - if (fromTypeLength > toTypeLength) { - return this.format( - `${snippet}.${'xyz'.slice(0, toTypeLength)}`, - this.getTypeFromLength(toTypeLength, this.getComponentType(fromType)), - toType, - ); - } - - if (toTypeLength === 4 && fromTypeLength > 1) { - // toType is vec4-like - - return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec3')}, 1.0 )`; - } - - if (fromTypeLength === 2) { - // fromType is vec2-like and toType is vec3-like - - return `${this.getType(toType)}( ${this.format(snippet, fromType, 'vec2')}, 0.0 )`; - } - - if (fromTypeLength === 1 && toTypeLength > 1 && fromType !== this.getComponentType(toType)) { - // fromType is float-like - - // convert a number value to vector type, e.g: - // vec3( 1u ) -> vec3( float( 1u ) ) - - snippet = `${this.getType(this.getComponentType(toType))}( ${snippet} )`; - } - - return `${this.getType(toType)}( ${snippet} )`; // fromType is float-like - } - - getSignature() { - return `// Three.js r${REVISION} - Node System\n`; - } -} - -export default NodeBuilder; diff --git a/examples-jsm/examples/nodes/core/NodeCache.ts b/examples-jsm/examples/nodes/core/NodeCache.ts deleted file mode 100644 index ad72d50c5..000000000 --- a/examples-jsm/examples/nodes/core/NodeCache.ts +++ /dev/null @@ -1,26 +0,0 @@ -let id = 0; - -class NodeCache { - constructor(parent = null) { - this.id = id++; - this.nodesData = new WeakMap(); - - this.parent = parent; - } - - getData(node) { - let data = this.nodesData.get(node); - - if (data === undefined && this.parent !== null) { - data = this.parent.getData(node); - } - - return data; - } - - setData(node, data) { - this.nodesData.set(node, data); - } -} - -export default NodeCache; diff --git a/examples-jsm/examples/nodes/core/NodeCode.ts b/examples-jsm/examples/nodes/core/NodeCode.ts deleted file mode 100644 index 2ee509037..000000000 --- a/examples-jsm/examples/nodes/core/NodeCode.ts +++ /dev/null @@ -1,11 +0,0 @@ -class NodeCode { - constructor(name, type, code = '') { - this.name = name; - this.type = type; - this.code = code; - - Object.defineProperty(this, 'isNodeCode', { value: true }); - } -} - -export default NodeCode; diff --git a/examples-jsm/examples/nodes/core/NodeFrame.ts b/examples-jsm/examples/nodes/core/NodeFrame.ts deleted file mode 100644 index ee64620ca..000000000 --- a/examples-jsm/examples/nodes/core/NodeFrame.ts +++ /dev/null @@ -1,127 +0,0 @@ -import { NodeUpdateType } from './constants.js'; - -class NodeFrame { - constructor() { - this.time = 0; - this.deltaTime = 0; - - this.frameId = 0; - this.renderId = 0; - - this.startTime = null; - - this.updateMap = new WeakMap(); - this.updateBeforeMap = new WeakMap(); - this.updateAfterMap = new WeakMap(); - - this.renderer = null; - this.material = null; - this.camera = null; - this.object = null; - this.scene = null; - } - - _getMaps(referenceMap, nodeRef) { - let maps = referenceMap.get(nodeRef); - - if (maps === undefined) { - maps = { - renderMap: new WeakMap(), - frameMap: new WeakMap(), - }; - - referenceMap.set(nodeRef, maps); - } - - return maps; - } - - updateBeforeNode(node) { - const updateType = node.getUpdateBeforeType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateBeforeMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.updateBefore(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateBeforeMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.updateBefore(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.updateBefore(this); - } - } - - updateAfterNode(node) { - const updateType = node.getUpdateAfterType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateAfterMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.updateAfter(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateAfterMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.updateAfter(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.updateAfter(this); - } - } - - updateNode(node) { - const updateType = node.getUpdateType(); - const reference = node.updateReference(this); - - if (updateType === NodeUpdateType.FRAME) { - const { frameMap } = this._getMaps(this.updateMap, reference); - - if (frameMap.get(reference) !== this.frameId) { - if (node.update(this) !== false) { - frameMap.set(reference, this.frameId); - } - } - } else if (updateType === NodeUpdateType.RENDER) { - const { renderMap } = this._getMaps(this.updateMap, reference); - - if (renderMap.get(reference) !== this.renderId) { - if (node.update(this) !== false) { - renderMap.set(reference, this.renderId); - } - } - } else if (updateType === NodeUpdateType.OBJECT) { - node.update(this); - } - } - - update() { - this.frameId++; - - if (this.lastTime === undefined) this.lastTime = performance.now(); - - this.deltaTime = (performance.now() - this.lastTime) / 1000; - - this.lastTime = performance.now(); - - this.time += this.deltaTime; - } -} - -export default NodeFrame; diff --git a/examples-jsm/examples/nodes/core/NodeFunction.ts b/examples-jsm/examples/nodes/core/NodeFunction.ts deleted file mode 100644 index d05afb5e6..000000000 --- a/examples-jsm/examples/nodes/core/NodeFunction.ts +++ /dev/null @@ -1,16 +0,0 @@ -class NodeFunction { - constructor(type, inputs, name = '', precision = '') { - this.type = type; - this.inputs = inputs; - this.name = name; - this.precision = precision; - } - - getCode(/*name = this.name*/) { - console.warn('Abstract function.'); - } -} - -NodeFunction.isNodeFunction = true; - -export default NodeFunction; diff --git a/examples-jsm/examples/nodes/core/NodeKeywords.ts b/examples-jsm/examples/nodes/core/NodeKeywords.ts deleted file mode 100644 index 1f468321b..000000000 --- a/examples-jsm/examples/nodes/core/NodeKeywords.ts +++ /dev/null @@ -1,58 +0,0 @@ -class NodeKeywords { - constructor() { - this.keywords = []; - this.nodes = {}; - this.keywordsCallback = {}; - } - - getNode(name) { - let node = this.nodes[name]; - - if (node === undefined && this.keywordsCallback[name] !== undefined) { - node = this.keywordsCallback[name](name); - - this.nodes[name] = node; - } - - return node; - } - - addKeyword(name, callback) { - this.keywords.push(name); - this.keywordsCallback[name] = callback; - - return this; - } - - parse(code) { - const keywordNames = this.keywords; - - const regExp = new RegExp(`\\b${keywordNames.join('\\b|\\b')}\\b`, 'g'); - - const codeKeywords = code.match(regExp); - - const keywordNodes = []; - - if (codeKeywords !== null) { - for (const keyword of codeKeywords) { - const node = this.getNode(keyword); - - if (node !== undefined && keywordNodes.indexOf(node) === -1) { - keywordNodes.push(node); - } - } - } - - return keywordNodes; - } - - include(builder, code) { - const keywordNodes = this.parse(code); - - for (const keywordNode of keywordNodes) { - keywordNode.build(builder); - } - } -} - -export default NodeKeywords; diff --git a/examples-jsm/examples/nodes/core/NodeParser.ts b/examples-jsm/examples/nodes/core/NodeParser.ts deleted file mode 100644 index 9849452f1..000000000 --- a/examples-jsm/examples/nodes/core/NodeParser.ts +++ /dev/null @@ -1,7 +0,0 @@ -class NodeParser { - parseFunction(/*source*/) { - console.warn('Abstract function.'); - } -} - -export default NodeParser; diff --git a/examples-jsm/examples/nodes/core/NodeUniform.ts b/examples-jsm/examples/nodes/core/NodeUniform.ts deleted file mode 100644 index ca43958fc..000000000 --- a/examples-jsm/examples/nodes/core/NodeUniform.ts +++ /dev/null @@ -1,27 +0,0 @@ -class NodeUniform { - constructor(name, type, node) { - this.isNodeUniform = true; - - this.name = name; - this.type = type; - this.node = node.getSelf(); - } - - get value() { - return this.node.value; - } - - set value(val) { - this.node.value = val; - } - - get id() { - return this.node.id; - } - - get groupNode() { - return this.node.groupNode; - } -} - -export default NodeUniform; diff --git a/examples-jsm/examples/nodes/core/NodeUtils.ts b/examples-jsm/examples/nodes/core/NodeUtils.ts deleted file mode 100644 index 16a5f3246..000000000 --- a/examples-jsm/examples/nodes/core/NodeUtils.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three'; - -export function getCacheKey(object, force = false) { - let cacheKey = '{'; - - if (object.isNode === true) { - cacheKey += object.id; - } - - for (const { property, childNode } of getNodeChildren(object)) { - cacheKey += ',' + property.slice(0, -4) + ':' + childNode.getCacheKey(force); - } - - cacheKey += '}'; - - return cacheKey; -} - -export function* getNodeChildren(node, toJSON = false) { - for (const property in node) { - // Ignore private properties. - if (property.startsWith('_') === true) continue; - - const object = node[property]; - - if (Array.isArray(object) === true) { - for (let i = 0; i < object.length; i++) { - const child = object[i]; - - if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { - yield { property, index: i, childNode: child }; - } - } - } else if (object && object.isNode === true) { - yield { property, childNode: object }; - } else if (typeof object === 'object') { - for (const subProperty in object) { - const child = object[subProperty]; - - if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { - yield { property, index: subProperty, childNode: child }; - } - } - } - } -} - -export function getValueType(value) { - if (value === undefined || value === null) return null; - - const typeOf = typeof value; - - if (value.isNode === true) { - return 'node'; - } else if (typeOf === 'number') { - return 'float'; - } else if (typeOf === 'boolean') { - return 'bool'; - } else if (typeOf === 'string') { - return 'string'; - } else if (typeOf === 'function') { - return 'shader'; - } else if (value.isVector2 === true) { - return 'vec2'; - } else if (value.isVector3 === true) { - return 'vec3'; - } else if (value.isVector4 === true) { - return 'vec4'; - } else if (value.isMatrix3 === true) { - return 'mat3'; - } else if (value.isMatrix4 === true) { - return 'mat4'; - } else if (value.isColor === true) { - return 'color'; - } else if (value instanceof ArrayBuffer) { - return 'ArrayBuffer'; - } - - return null; -} - -export function getValueFromType(type, ...params) { - const last4 = type ? type.slice(-4) : undefined; - - if (params.length === 1) { - // ensure same behaviour as in NodeBuilder.format() - - if (last4 === 'vec2') params = [params[0], params[0]]; - else if (last4 === 'vec3') params = [params[0], params[0], params[0]]; - else if (last4 === 'vec4') params = [params[0], params[0], params[0], params[0]]; - } - - if (type === 'color') { - return new Color(...params); - } else if (last4 === 'vec2') { - return new Vector2(...params); - } else if (last4 === 'vec3') { - return new Vector3(...params); - } else if (last4 === 'vec4') { - return new Vector4(...params); - } else if (last4 === 'mat3') { - return new Matrix3(...params); - } else if (last4 === 'mat4') { - return new Matrix4(...params); - } else if (type === 'bool') { - return params[0] || false; - } else if (type === 'float' || type === 'int' || type === 'uint') { - return params[0] || 0; - } else if (type === 'string') { - return params[0] || ''; - } else if (type === 'ArrayBuffer') { - return base64ToArrayBuffer(params[0]); - } - - return null; -} - -export function arrayBufferToBase64(arrayBuffer) { - let chars = ''; - - const array = new Uint8Array(arrayBuffer); - - for (let i = 0; i < array.length; i++) { - chars += String.fromCharCode(array[i]); - } - - return btoa(chars); -} - -export function base64ToArrayBuffer(base64) { - return Uint8Array.from(atob(base64), c => c.charCodeAt(0)).buffer; -} diff --git a/examples-jsm/examples/nodes/core/NodeVar.ts b/examples-jsm/examples/nodes/core/NodeVar.ts deleted file mode 100644 index e6e935b31..000000000 --- a/examples-jsm/examples/nodes/core/NodeVar.ts +++ /dev/null @@ -1,10 +0,0 @@ -class NodeVar { - constructor(name, type) { - this.isNodeVar = true; - - this.name = name; - this.type = type; - } -} - -export default NodeVar; diff --git a/examples-jsm/examples/nodes/core/NodeVarying.ts b/examples-jsm/examples/nodes/core/NodeVarying.ts deleted file mode 100644 index a14823628..000000000 --- a/examples-jsm/examples/nodes/core/NodeVarying.ts +++ /dev/null @@ -1,13 +0,0 @@ -import NodeVar from './NodeVar.js'; - -class NodeVarying extends NodeVar { - constructor(name, type) { - super(name, type); - - this.needsInterpolation = false; - - this.isNodeVarying = true; - } -} - -export default NodeVarying; diff --git a/examples-jsm/examples/nodes/core/StackNode.ts b/examples-jsm/examples/nodes/core/StackNode.ts deleted file mode 100644 index d93226072..000000000 --- a/examples-jsm/examples/nodes/core/StackNode.ts +++ /dev/null @@ -1,71 +0,0 @@ -import Node, { addNodeClass } from './Node.js'; -import { cond } from '../math/CondNode.js'; -import { ShaderNode, nodeProxy, getCurrentStack, setCurrentStack } from '../shadernode/ShaderNode.js'; - -class StackNode extends Node { - constructor(parent = null) { - super(); - - this.nodes = []; - this.outputNode = null; - - this.parent = parent; - - this._currentCond = null; - - this.isStackNode = true; - } - - getNodeType(builder) { - return this.outputNode ? this.outputNode.getNodeType(builder) : 'void'; - } - - add(node) { - this.nodes.push(node); - - return this; - } - - if(boolNode, method) { - const methodNode = new ShaderNode(method); - this._currentCond = cond(boolNode, methodNode); - - return this.add(this._currentCond); - } - - elseif(boolNode, method) { - const methodNode = new ShaderNode(method); - const ifNode = cond(boolNode, methodNode); - - this._currentCond.elseNode = ifNode; - this._currentCond = ifNode; - - return this; - } - - else(method) { - this._currentCond.elseNode = new ShaderNode(method); - - return this; - } - - build(builder, ...params) { - const previousStack = getCurrentStack(); - - setCurrentStack(this); - - for (const node of this.nodes) { - node.build(builder, 'void'); - } - - setCurrentStack(previousStack); - - return this.outputNode ? this.outputNode.build(builder, ...params) : super.build(builder, ...params); - } -} - -export default StackNode; - -export const stack = nodeProxy(StackNode); - -addNodeClass('StackNode', StackNode); diff --git a/examples-jsm/examples/nodes/core/StructTypeNode.ts b/examples-jsm/examples/nodes/core/StructTypeNode.ts deleted file mode 100644 index 697187999..000000000 --- a/examples-jsm/examples/nodes/core/StructTypeNode.ts +++ /dev/null @@ -1,18 +0,0 @@ -import Node, { addNodeClass } from './Node.js'; - -class StructTypeNode extends Node { - constructor(types) { - super(); - - this.types = types; - this.isStructTypeNode = true; - } - - getMemberTypes() { - return this.types; - } -} - -export default StructTypeNode; - -addNodeClass('StructTypeNode', StructTypeNode); diff --git a/examples-jsm/examples/nodes/core/UniformGroupNode.ts b/examples-jsm/examples/nodes/core/UniformGroupNode.ts deleted file mode 100644 index f8bb2b37d..000000000 --- a/examples-jsm/examples/nodes/core/UniformGroupNode.ts +++ /dev/null @@ -1,30 +0,0 @@ -import Node from './Node.js'; -import { addNodeClass } from './Node.js'; - -class UniformGroupNode extends Node { - constructor(name, shared = false) { - super('string'); - - this.name = name; - this.version = 0; - - this.shared = shared; - - this.isUniformGroup = true; - } - - set needsUpdate(value) { - if (value === true) this.version++; - } -} - -export const uniformGroup = name => new UniformGroupNode(name); -export const sharedUniformGroup = name => new UniformGroupNode(name, true); - -export const frameGroup = sharedUniformGroup('frame'); -export const renderGroup = sharedUniformGroup('render'); -export const objectGroup = uniformGroup('object'); - -export default UniformGroupNode; - -addNodeClass('UniformGroupNode', UniformGroupNode); diff --git a/examples-jsm/examples/nodes/core/UniformNode.ts b/examples-jsm/examples/nodes/core/UniformNode.ts deleted file mode 100644 index 41e523c4f..000000000 --- a/examples-jsm/examples/nodes/core/UniformNode.ts +++ /dev/null @@ -1,90 +0,0 @@ -import InputNode from './InputNode.js'; -import { objectGroup } from './UniformGroupNode.js'; -import { addNodeClass } from './Node.js'; -import { nodeObject, getConstNodeType } from '../shadernode/ShaderNode.js'; - -class UniformNode extends InputNode { - constructor(value, nodeType = null) { - super(value, nodeType); - - this.isUniformNode = true; - - this.name = ''; - this.groupNode = objectGroup; - } - - label(name) { - this.name = name; - - return this; - } - - setGroup(group) { - this.groupNode = group; - - return this; - } - - getGroup() { - return this.groupNode; - } - - getUniformHash(builder) { - return this.getHash(builder); - } - - onUpdate(callback, updateType) { - const self = this.getSelf(); - - callback = callback.bind(self); - - return super.onUpdate(frame => { - const value = callback(frame, self); - - if (value !== undefined) { - this.value = value; - } - }, updateType); - } - - generate(builder, output) { - const type = this.getNodeType(builder); - - const hash = this.getUniformHash(builder); - - let sharedNode = builder.getNodeFromHash(hash); - - if (sharedNode === undefined) { - builder.setHashNode(this, hash); - - sharedNode = this; - } - - const sharedNodeType = sharedNode.getInputType(builder); - - const nodeUniform = builder.getUniformFromNode( - sharedNode, - sharedNodeType, - builder.shaderStage, - this.name || builder.context.label, - ); - const propertyName = builder.getPropertyName(nodeUniform); - - if (builder.context.label !== undefined) delete builder.context.label; - - return builder.format(propertyName, type, output); - } -} - -export default UniformNode; - -export const uniform = (arg1, arg2) => { - const nodeType = getConstNodeType(arg2 || arg1); - - // @TODO: get ConstNode from .traverse() in the future - const value = arg1 && arg1.isNode === true ? (arg1.node && arg1.node.value) || arg1.value : arg1; - - return nodeObject(new UniformNode(value, nodeType)); -}; - -addNodeClass('UniformNode', UniformNode); diff --git a/examples-jsm/examples/nodes/core/constants.ts b/examples-jsm/examples/nodes/core/constants.ts deleted file mode 100644 index 3b01a9a6d..000000000 --- a/examples-jsm/examples/nodes/core/constants.ts +++ /dev/null @@ -1,28 +0,0 @@ -export const NodeShaderStage = { - VERTEX: 'vertex', - FRAGMENT: 'fragment', -}; - -export const NodeUpdateType = { - NONE: 'none', - FRAME: 'frame', - RENDER: 'render', - OBJECT: 'object', -}; - -export const NodeType = { - BOOLEAN: 'bool', - INTEGER: 'int', - FLOAT: 'float', - VECTOR2: 'vec2', - VECTOR3: 'vec3', - VECTOR4: 'vec4', - MATRIX2: 'mat2', - MATRIX3: 'mat3', - MATRIX4: 'mat4', -}; - -export const defaultShaderStages = ['fragment', 'vertex']; -export const defaultBuildStages = ['setup', 'analyze', 'generate']; -export const shaderStages = [...defaultShaderStages, 'compute']; -export const vectorComponents = ['x', 'y', 'z', 'w']; diff --git a/examples-jsm/examples/nodes/fog/FogNode.ts b/examples-jsm/examples/nodes/fog/FogNode.ts deleted file mode 100644 index 9417df5a5..000000000 --- a/examples-jsm/examples/nodes/fog/FogNode.ts +++ /dev/null @@ -1,38 +0,0 @@ -import Node, { addNodeClass } from '../core/Node.js'; -import { positionView } from '../accessors/PositionNode.js'; -import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js'; - -class FogNode extends Node { - constructor(colorNode, factorNode) { - super('float'); - - this.isFogNode = true; - - this.colorNode = colorNode; - this.factorNode = factorNode; - } - - getViewZNode(builder) { - let viewZ; - - const getViewZ = builder.context.getViewZ; - - if (getViewZ !== undefined) { - viewZ = getViewZ(this); - } - - return (viewZ || positionView.z).negate(); - } - - setup() { - return this.factorNode; - } -} - -export default FogNode; - -export const fog = nodeProxy(FogNode); - -addNodeElement('fog', fog); - -addNodeClass('FogNode', FogNode); diff --git a/examples-jsm/examples/nodes/gpgpu/ComputeNode.ts b/examples-jsm/examples/nodes/gpgpu/ComputeNode.ts deleted file mode 100644 index ab2925a55..000000000 --- a/examples-jsm/examples/nodes/gpgpu/ComputeNode.ts +++ /dev/null @@ -1,67 +0,0 @@ -import Node, { addNodeClass } from '../core/Node.js'; -import { NodeUpdateType } from '../core/constants.js'; -import { addNodeElement, nodeObject } from '../shadernode/ShaderNode.js'; - -class ComputeNode extends Node { - constructor(computeNode, count, workgroupSize = [64]) { - super('void'); - - this.isComputeNode = true; - - this.computeNode = computeNode; - - this.count = count; - this.workgroupSize = workgroupSize; - this.dispatchCount = 0; - - this.version = 1; - this.updateBeforeType = NodeUpdateType.OBJECT; - - this.updateDispatchCount(); - } - - dispose() { - this.dispatchEvent({ type: 'dispose' }); - } - - set needsUpdate(value) { - if (value === true) this.version++; - } - - updateDispatchCount() { - const { count, workgroupSize } = this; - - let size = workgroupSize[0]; - - for (let i = 1; i < workgroupSize.length; i++) size *= workgroupSize[i]; - - this.dispatchCount = Math.ceil(count / size); - } - - onInit() {} - - updateBefore({ renderer }) { - renderer.compute(this); - } - - generate(builder) { - const { shaderStage } = builder; - - if (shaderStage === 'compute') { - const snippet = this.computeNode.build(builder, 'void'); - - if (snippet !== '') { - builder.addLineFlowCode(snippet); - } - } - } -} - -export default ComputeNode; - -export const compute = (node, count, workgroupSize) => - nodeObject(new ComputeNode(nodeObject(node), count, workgroupSize)); - -addNodeElement('compute', compute); - -addNodeClass('ComputeNode', ComputeNode); diff --git a/examples-jsm/examples/nodes/lighting/EnvironmentNode.ts b/examples-jsm/examples/nodes/lighting/EnvironmentNode.ts deleted file mode 100644 index 31ddc8b09..000000000 --- a/examples-jsm/examples/nodes/lighting/EnvironmentNode.ts +++ /dev/null @@ -1,119 +0,0 @@ -import LightingNode from './LightingNode.js'; -import { cache } from '../core/CacheNode.js'; -import { context } from '../core/ContextNode.js'; -import { roughness, clearcoatRoughness } from '../core/PropertyNode.js'; -import { cameraViewMatrix } from '../accessors/CameraNode.js'; -import { - transformedClearcoatNormalView, - transformedNormalView, - transformedNormalWorld, -} from '../accessors/NormalNode.js'; -import { positionViewDirection } from '../accessors/PositionNode.js'; -import { addNodeClass } from '../core/Node.js'; -import { float } from '../shadernode/ShaderNode.js'; -import { reference } from '../accessors/ReferenceNode.js'; -import { transformedBentNormalView } from '../accessors/AccessorsUtils.js'; -import { pmremTexture } from '../pmrem/PMREMNode.js'; - -const envNodeCache = new WeakMap(); - -class EnvironmentNode extends LightingNode { - constructor(envNode = null) { - super(); - - this.envNode = envNode; - } - - setup(builder) { - let envNode = this.envNode; - - if (envNode.isTextureNode) { - let cacheEnvNode = envNodeCache.get(envNode.value); - - if (cacheEnvNode === undefined) { - cacheEnvNode = pmremTexture(envNode.value); - - envNodeCache.set(envNode.value, cacheEnvNode); - } - - envNode = cacheEnvNode; - } - - // - - const { material } = builder; - - const envMap = material.envMap; - const intensity = envMap - ? reference('envMapIntensity', 'float', builder.material) - : reference('environmentIntensity', 'float', builder.scene); // @TODO: Add materialEnvIntensity in MaterialNode - - const useAnisotropy = material.useAnisotropy === true || material.anisotropy > 0; - const radianceNormalView = useAnisotropy ? transformedBentNormalView : transformedNormalView; - - const radiance = context(envNode, createRadianceContext(roughness, radianceNormalView)).mul(intensity); - const irradiance = context(envNode, createIrradianceContext(transformedNormalWorld)) - .mul(Math.PI) - .mul(intensity); - - const isolateRadiance = cache(radiance); - const isolateIrradiance = cache(irradiance); - - // - - builder.context.radiance.addAssign(isolateRadiance); - - builder.context.iblIrradiance.addAssign(isolateIrradiance); - - // - - const clearcoatRadiance = builder.context.lightingModel.clearcoatRadiance; - - if (clearcoatRadiance) { - const clearcoatRadianceContext = context( - envNode, - createRadianceContext(clearcoatRoughness, transformedClearcoatNormalView), - ).mul(intensity); - const isolateClearcoatRadiance = cache(clearcoatRadianceContext); - - clearcoatRadiance.addAssign(isolateClearcoatRadiance); - } - } -} - -const createRadianceContext = (roughnessNode, normalViewNode) => { - let reflectVec = null; - - return { - getUV: () => { - if (reflectVec === null) { - reflectVec = positionViewDirection.negate().reflect(normalViewNode); - - // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. - reflectVec = roughnessNode.mul(roughnessNode).mix(reflectVec, normalViewNode).normalize(); - - reflectVec = reflectVec.transformDirection(cameraViewMatrix); - } - - return reflectVec; - }, - getTextureLevel: () => { - return roughnessNode; - }, - }; -}; - -const createIrradianceContext = normalWorldNode => { - return { - getUV: () => { - return normalWorldNode; - }, - getTextureLevel: () => { - return float(1.0); - }, - }; -}; - -export default EnvironmentNode; - -addNodeClass('EnvironmentNode', EnvironmentNode); diff --git a/examples-jsm/examples/nodes/lighting/LightingContextNode.ts b/examples-jsm/examples/nodes/lighting/LightingContextNode.ts deleted file mode 100644 index 02a8b51f8..000000000 --- a/examples-jsm/examples/nodes/lighting/LightingContextNode.ts +++ /dev/null @@ -1,58 +0,0 @@ -import ContextNode from '../core/ContextNode.js'; -import { addNodeClass } from '../core/Node.js'; -import { addNodeElement, nodeProxy, float, vec3 } from '../shadernode/ShaderNode.js'; - -class LightingContextNode extends ContextNode { - constructor(node, lightingModel = null, backdropNode = null, backdropAlphaNode = null) { - super(node); - - this.lightingModel = lightingModel; - this.backdropNode = backdropNode; - this.backdropAlphaNode = backdropAlphaNode; - - this._context = null; - } - - getContext() { - const { backdropNode, backdropAlphaNode } = this; - - const directDiffuse = vec3().temp('directDiffuse'), - directSpecular = vec3().temp('directSpecular'), - indirectDiffuse = vec3().temp('indirectDiffuse'), - indirectSpecular = vec3().temp('indirectSpecular'); - - const reflectedLight = { - directDiffuse, - directSpecular, - indirectDiffuse, - indirectSpecular, - }; - - const context = { - radiance: vec3().temp('radiance'), - irradiance: vec3().temp('irradiance'), - iblIrradiance: vec3().temp('iblIrradiance'), - ambientOcclusion: float(1).temp('ambientOcclusion'), - reflectedLight, - backdrop: backdropNode, - backdropAlpha: backdropAlphaNode, - }; - - return context; - } - - setup(builder) { - this.context = this._context || (this._context = this.getContext()); - this.context.lightingModel = this.lightingModel || builder.context.lightingModel; - - return super.setup(builder); - } -} - -export default LightingContextNode; - -export const lightingContext = nodeProxy(LightingContextNode); - -addNodeElement('lightingContext', lightingContext); - -addNodeClass('LightingContextNode', LightingContextNode); diff --git a/examples-jsm/examples/nodes/lighting/LightsNode.ts b/examples-jsm/examples/nodes/lighting/LightsNode.ts deleted file mode 100644 index 96e5c60ab..000000000 --- a/examples-jsm/examples/nodes/lighting/LightsNode.ts +++ /dev/null @@ -1,170 +0,0 @@ -import Node from '../core/Node.js'; -import AnalyticLightNode from './AnalyticLightNode.js'; -import { nodeObject, nodeProxy, vec3 } from '../shadernode/ShaderNode.js'; - -const LightNodes = new WeakMap(); - -const sortLights = lights => { - return lights.sort((a, b) => a.id - b.id); -}; - -class LightsNode extends Node { - constructor(lightNodes = []) { - super('vec3'); - - this.totalDiffuseNode = vec3().temp('totalDiffuse'); - this.totalSpecularNode = vec3().temp('totalSpecular'); - - this.outgoingLightNode = vec3().temp('outgoingLight'); - - this.lightNodes = lightNodes; - - this._hash = null; - } - - get hasLight() { - return this.lightNodes.length > 0; - } - - getHash() { - if (this._hash === null) { - const hash = []; - - for (const lightNode of this.lightNodes) { - hash.push(lightNode.getHash()); - } - - this._hash = 'lights-' + hash.join(','); - } - - return this._hash; - } - - analyze(builder) { - const properties = builder.getDataFromNode(this); - - for (const node of properties.nodes) { - node.build(builder); - } - } - - setup(builder) { - const context = builder.context; - const lightingModel = context.lightingModel; - - let outgoingLightNode = this.outgoingLightNode; - - if (lightingModel) { - const { lightNodes, totalDiffuseNode, totalSpecularNode } = this; - - context.outgoingLight = outgoingLightNode; - - const stack = builder.addStack(); - - // - - const properties = builder.getDataFromNode(this); - properties.nodes = stack.nodes; - - // - - lightingModel.start(context, stack, builder); - - // lights - - for (const lightNode of lightNodes) { - lightNode.build(builder); - } - - // - - lightingModel.indirectDiffuse(context, stack, builder); - lightingModel.indirectSpecular(context, stack, builder); - lightingModel.ambientOcclusion(context, stack, builder); - - // - - const { backdrop, backdropAlpha } = context; - const { directDiffuse, directSpecular, indirectDiffuse, indirectSpecular } = context.reflectedLight; - - let totalDiffuse = directDiffuse.add(indirectDiffuse); - - if (backdrop !== null) { - if (backdropAlpha !== null) { - totalDiffuse = vec3(backdropAlpha.mix(totalDiffuse, backdrop)); - } else { - totalDiffuse = vec3(backdrop); - } - - context.material.transparent = true; - } - - totalDiffuseNode.assign(totalDiffuse); - totalSpecularNode.assign(directSpecular.add(indirectSpecular)); - - outgoingLightNode.assign(totalDiffuseNode.add(totalSpecularNode)); - - // - - lightingModel.finish(context, stack, builder); - - // - - outgoingLightNode = outgoingLightNode.bypass(builder.removeStack()); - } - - return outgoingLightNode; - } - - _getLightNodeById(id) { - for (const lightNode of this.lightNodes) { - if (lightNode.isAnalyticLightNode && lightNode.light.id === id) { - return lightNode; - } - } - - return null; - } - - fromLights(lights = []) { - const lightNodes = []; - - lights = sortLights(lights); - - for (const light of lights) { - let lightNode = this._getLightNodeById(light.id); - - if (lightNode === null) { - const lightClass = light.constructor; - const lightNodeClass = LightNodes.has(lightClass) ? LightNodes.get(lightClass) : AnalyticLightNode; - - lightNode = nodeObject(new lightNodeClass(light)); - } - - lightNodes.push(lightNode); - } - - this.lightNodes = lightNodes; - this._hash = null; - - return this; - } -} - -export default LightsNode; - -export const lights = lights => nodeObject(new LightsNode().fromLights(lights)); -export const lightsNode = nodeProxy(LightsNode); - -export function addLightNode(lightClass, lightNodeClass) { - if (LightNodes.has(lightClass)) { - console.warn(`Redefinition of light node ${lightNodeClass.type}`); - return; - } - - if (typeof lightClass !== 'function') throw new Error(`Light ${lightClass.name} is not a class`); - if (typeof lightNodeClass !== 'function' || !lightNodeClass.type) - throw new Error(`Light node ${lightNodeClass.type} is not a class`); - - LightNodes.set(lightClass, lightNodeClass); -} diff --git a/examples-jsm/examples/nodes/materials/NodeMaterial.ts b/examples-jsm/examples/nodes/materials/NodeMaterial.ts deleted file mode 100644 index d0c7c6cd9..000000000 --- a/examples-jsm/examples/nodes/materials/NodeMaterial.ts +++ /dev/null @@ -1,514 +0,0 @@ -import { Material, NormalBlending } from 'three'; -import { getNodeChildren, getCacheKey } from '../core/NodeUtils.js'; -import { attribute } from '../core/AttributeNode.js'; -import { output, diffuseColor, varyingProperty } from '../core/PropertyNode.js'; -import { - materialAlphaTest, - materialColor, - materialOpacity, - materialEmissive, - materialNormal, -} from '../accessors/MaterialNode.js'; -import { modelViewProjection } from '../accessors/ModelViewProjectionNode.js'; -import { transformedNormalView, normalLocal } from '../accessors/NormalNode.js'; -import { instance } from '../accessors/InstanceNode.js'; -import { batch } from '../accessors/BatchNode.js'; -import { materialReference } from '../accessors/MaterialReferenceNode.js'; -import { positionLocal, positionView } from '../accessors/PositionNode.js'; -import { skinningReference } from '../accessors/SkinningNode.js'; -import { morphReference } from '../accessors/MorphNode.js'; -import { texture } from '../accessors/TextureNode.js'; -import { cubeTexture } from '../accessors/CubeTextureNode.js'; -import { lightsNode } from '../lighting/LightsNode.js'; -import { mix } from '../math/MathNode.js'; -import { float, vec3, vec4 } from '../shadernode/ShaderNode.js'; -import AONode from '../lighting/AONode.js'; -import { lightingContext } from '../lighting/LightingContextNode.js'; -import EnvironmentNode from '../lighting/EnvironmentNode.js'; -import IrradianceNode from '../lighting/IrradianceNode.js'; -import { depth } from '../display/ViewportDepthNode.js'; -import { cameraLogDepth } from '../accessors/CameraNode.js'; -import { clipping, clippingAlpha } from '../accessors/ClippingNode.js'; -import { faceDirection } from '../display/FrontFacingNode.js'; - -const NodeMaterials = new Map(); - -class NodeMaterial extends Material { - constructor() { - super(); - - this.isNodeMaterial = true; - - this.type = this.constructor.type; - - this.forceSinglePass = false; - - this.fog = true; - this.lights = true; - this.normals = true; - - this.lightsNode = null; - this.envNode = null; - this.aoNode = null; - - this.colorNode = null; - this.normalNode = null; - this.opacityNode = null; - this.backdropNode = null; - this.backdropAlphaNode = null; - this.alphaTestNode = null; - - this.positionNode = null; - - this.depthNode = null; - this.shadowNode = null; - this.shadowPositionNode = null; - - this.outputNode = null; - - this.fragmentNode = null; - this.vertexNode = null; - } - - customProgramCacheKey() { - return this.type + getCacheKey(this); - } - - build(builder) { - this.setup(builder); - } - - setup(builder) { - // < VERTEX STAGE > - - builder.addStack(); - - builder.stack.outputNode = this.vertexNode || this.setupPosition(builder); - - builder.addFlow('vertex', builder.removeStack()); - - // < FRAGMENT STAGE > - - builder.addStack(); - - let resultNode; - - const clippingNode = this.setupClipping(builder); - - if (this.depthWrite === true) this.setupDepth(builder); - - if (this.fragmentNode === null) { - if (this.normals === true) this.setupNormal(builder); - - this.setupDiffuseColor(builder); - this.setupVariants(builder); - - const outgoingLightNode = this.setupLighting(builder); - - if (clippingNode !== null) builder.stack.add(clippingNode); - - // force unsigned floats - useful for RenderTargets - - const basicOutput = vec4(outgoingLightNode, diffuseColor.a).max(0); - - resultNode = this.setupOutput(builder, basicOutput); - - // OUTPUT NODE - - output.assign(resultNode); - - // - - if (this.outputNode !== null) resultNode = this.outputNode; - } else { - let fragmentNode = this.fragmentNode; - - if (fragmentNode.isOutputStructNode !== true) { - fragmentNode = vec4(fragmentNode); - } - - resultNode = this.setupOutput(builder, fragmentNode); - } - - builder.stack.outputNode = resultNode; - - builder.addFlow('fragment', builder.removeStack()); - } - - setupClipping(builder) { - if (builder.clippingContext === null) return null; - - const { globalClippingCount, localClippingCount } = builder.clippingContext; - - let result = null; - - if (globalClippingCount || localClippingCount) { - if (this.alphaToCoverage) { - // to be added to flow when the color/alpha value has been determined - result = clippingAlpha(); - } else { - builder.stack.add(clipping()); - } - } - - return result; - } - - setupDepth(builder) { - const { renderer } = builder; - - // Depth - - let depthNode = this.depthNode; - - if (depthNode === null && renderer.logarithmicDepthBuffer === true) { - const fragDepth = modelViewProjection().w.add(1); - - depthNode = fragDepth.log2().mul(cameraLogDepth).mul(0.5); - } - - if (depthNode !== null) { - depth.assign(depthNode).append(); - } - } - - setupPosition(builder) { - const { object } = builder; - const geometry = object.geometry; - - builder.addStack(); - - // Vertex - - if (geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color) { - morphReference(object).append(); - } - - if (object.isSkinnedMesh === true) { - skinningReference(object).append(); - } - - if (this.displacementMap) { - const displacementMap = materialReference('displacementMap', 'texture'); - const displacementScale = materialReference('displacementScale', 'float'); - const displacementBias = materialReference('displacementBias', 'float'); - - positionLocal.addAssign( - normalLocal.normalize().mul(displacementMap.x.mul(displacementScale).add(displacementBias)), - ); - } - - if (object.isBatchedMesh) { - batch(object).append(); - } - - if (object.instanceMatrix && object.instanceMatrix.isInstancedBufferAttribute === true) { - instance(object).append(); - } - - if (this.positionNode !== null) { - positionLocal.assign(this.positionNode); - } - - const mvp = modelViewProjection(); - - builder.context.vertex = builder.removeStack(); - builder.context.mvp = mvp; - - return mvp; - } - - setupDiffuseColor({ object, geometry }) { - let colorNode = this.colorNode ? vec4(this.colorNode) : materialColor; - - // VERTEX COLORS - - if (this.vertexColors === true && geometry.hasAttribute('color')) { - colorNode = vec4(colorNode.xyz.mul(attribute('color', 'vec3')), colorNode.a); - } - - // Instanced colors - - if (object.instanceColor) { - const instanceColor = varyingProperty('vec3', 'vInstanceColor'); - - colorNode = instanceColor.mul(colorNode); - } - - // COLOR - - diffuseColor.assign(colorNode); - - // OPACITY - - const opacityNode = this.opacityNode ? float(this.opacityNode) : materialOpacity; - diffuseColor.a.assign(diffuseColor.a.mul(opacityNode)); - - // ALPHA TEST - - if (this.alphaTestNode !== null || this.alphaTest > 0) { - const alphaTestNode = this.alphaTestNode !== null ? float(this.alphaTestNode) : materialAlphaTest; - - diffuseColor.a.lessThanEqual(alphaTestNode).discard(); - } - - if (this.transparent === false && this.blending === NormalBlending && this.alphaToCoverage === false) { - diffuseColor.a.assign(1.0); - } - } - - setupVariants(/*builder*/) { - // Interface function. - } - - setupNormal() { - // NORMAL VIEW - - if (this.flatShading === true) { - const normalNode = positionView.dFdx().cross(positionView.dFdy()).normalize(); - - transformedNormalView.assign(normalNode.mul(faceDirection)); - } else { - const normalNode = this.normalNode ? vec3(this.normalNode) : materialNormal; - - transformedNormalView.assign(normalNode.mul(faceDirection)); - } - } - - getEnvNode(builder) { - let node = null; - - if (this.envNode) { - node = this.envNode; - } else if (this.envMap) { - node = this.envMap.isCubeTexture ? cubeTexture(this.envMap) : texture(this.envMap); - } else if (builder.environmentNode) { - node = builder.environmentNode; - } - - return node; - } - - setupLights(builder) { - const envNode = this.getEnvNode(builder); - - // - - const materialLightsNode = []; - - if (envNode) { - materialLightsNode.push(new EnvironmentNode(envNode)); - } - - if (builder.material.lightMap) { - materialLightsNode.push(new IrradianceNode(materialReference('lightMap', 'texture'))); - } - - if (this.aoNode !== null || builder.material.aoMap) { - const aoNode = this.aoNode !== null ? this.aoNode : texture(builder.material.aoMap); - - materialLightsNode.push(new AONode(aoNode)); - } - - let lightsN = this.lightsNode || builder.lightsNode; - - if (materialLightsNode.length > 0) { - lightsN = lightsNode([...lightsN.lightNodes, ...materialLightsNode]); - } - - return lightsN; - } - - setupLightingModel(/*builder*/) { - // Interface function. - } - - setupLighting(builder) { - const { material } = builder; - const { backdropNode, backdropAlphaNode, emissiveNode } = this; - - // OUTGOING LIGHT - - const lights = this.lights === true || this.lightsNode !== null; - - const lightsNode = lights ? this.setupLights(builder) : null; - - let outgoingLightNode = diffuseColor.rgb; - - if (lightsNode && lightsNode.hasLight !== false) { - const lightingModel = this.setupLightingModel(builder); - - outgoingLightNode = lightingContext(lightsNode, lightingModel, backdropNode, backdropAlphaNode); - } else if (backdropNode !== null) { - outgoingLightNode = vec3( - backdropAlphaNode !== null ? mix(outgoingLightNode, backdropNode, backdropAlphaNode) : backdropNode, - ); - } - - // EMISSIVE - - if ( - (emissiveNode && emissiveNode.isNode === true) || - (material.emissive && material.emissive.isColor === true) - ) { - outgoingLightNode = outgoingLightNode.add(vec3(emissiveNode ? emissiveNode : materialEmissive)); - } - - return outgoingLightNode; - } - - setupOutput(builder, outputNode) { - // FOG - - if (this.fog === true) { - const fogNode = builder.fogNode; - - if (fogNode) outputNode = vec4(fogNode.mix(outputNode.rgb, fogNode.colorNode), outputNode.a); - } - - return outputNode; - } - - setDefaultValues(material) { - // This approach is to reuse the native refreshUniforms* - // and turn available the use of features like transmission and environment in core - - for (const property in material) { - const value = material[property]; - - if (this[property] === undefined) { - this[property] = value; - - if (value && value.clone) this[property] = value.clone(); - } - } - - const descriptors = Object.getOwnPropertyDescriptors(material.constructor.prototype); - - for (const key in descriptors) { - if ( - Object.getOwnPropertyDescriptor(this.constructor.prototype, key) === undefined && - descriptors[key].get !== undefined - ) { - Object.defineProperty(this.constructor.prototype, key, descriptors[key]); - } - } - } - - toJSON(meta) { - const isRoot = meta === undefined || typeof meta === 'string'; - - if (isRoot) { - meta = { - textures: {}, - images: {}, - nodes: {}, - }; - } - - const data = Material.prototype.toJSON.call(this, meta); - const nodeChildren = getNodeChildren(this); - - data.inputNodes = {}; - - for (const { property, childNode } of nodeChildren) { - data.inputNodes[property] = childNode.toJSON(meta).uuid; - } - - // TODO: Copied from Object3D.toJSON - - function extractFromCache(cache) { - const values = []; - - for (const key in cache) { - const data = cache[key]; - delete data.metadata; - values.push(data); - } - - return values; - } - - if (isRoot) { - const textures = extractFromCache(meta.textures); - const images = extractFromCache(meta.images); - const nodes = extractFromCache(meta.nodes); - - if (textures.length > 0) data.textures = textures; - if (images.length > 0) data.images = images; - if (nodes.length > 0) data.nodes = nodes; - } - - return data; - } - - copy(source) { - this.lightsNode = source.lightsNode; - this.envNode = source.envNode; - - this.colorNode = source.colorNode; - this.normalNode = source.normalNode; - this.opacityNode = source.opacityNode; - this.backdropNode = source.backdropNode; - this.backdropAlphaNode = source.backdropAlphaNode; - this.alphaTestNode = source.alphaTestNode; - - this.positionNode = source.positionNode; - - this.depthNode = source.depthNode; - this.shadowNode = source.shadowNode; - this.shadowPositionNode = source.shadowPositionNode; - - this.outputNode = source.outputNode; - - this.fragmentNode = source.fragmentNode; - this.vertexNode = source.vertexNode; - - return super.copy(source); - } - - static fromMaterial(material) { - if (material.isNodeMaterial === true) { - // is already a node material - - return material; - } - - const type = material.type.replace('Material', 'NodeMaterial'); - - const nodeMaterial = createNodeMaterialFromType(type); - - if (nodeMaterial === undefined) { - throw new Error(`NodeMaterial: Material "${material.type}" is not compatible.`); - } - - for (const key in material) { - nodeMaterial[key] = material[key]; - } - - return nodeMaterial; - } -} - -export default NodeMaterial; - -export function addNodeMaterial(type, nodeMaterial) { - if (typeof nodeMaterial !== 'function' || !type) throw new Error(`Node material ${type} is not a class`); - if (NodeMaterials.has(type)) { - console.warn(`Redefinition of node material ${type}`); - return; - } - - NodeMaterials.set(type, nodeMaterial); - nodeMaterial.type = type; -} - -export function createNodeMaterialFromType(type) { - const Material = NodeMaterials.get(type); - - if (Material !== undefined) { - return new Material(); - } -} - -addNodeMaterial('NodeMaterial', NodeMaterial); diff --git a/examples-jsm/examples/nodes/shadernode/ShaderNode.ts b/examples-jsm/examples/nodes/shadernode/ShaderNode.ts deleted file mode 100644 index 288ffa3d8..000000000 --- a/examples-jsm/examples/nodes/shadernode/ShaderNode.ts +++ /dev/null @@ -1,532 +0,0 @@ -import Node, { addNodeClass } from '../core/Node.js'; -import ArrayElementNode from '../utils/ArrayElementNode.js'; -import ConvertNode from '../utils/ConvertNode.js'; -import JoinNode from '../utils/JoinNode.js'; -import SplitNode from '../utils/SplitNode.js'; -import SetNode from '../utils/SetNode.js'; -import ConstNode from '../core/ConstNode.js'; -import { getValueFromType, getValueType } from '../core/NodeUtils.js'; - -// - -let currentStack = null; - -const NodeElements = new Map(); // @TODO: Currently only a few nodes are added, probably also add others - -export function addNodeElement(name, nodeElement) { - if (NodeElements.has(name)) { - console.warn(`Redefinition of node element ${name}`); - return; - } - - if (typeof nodeElement !== 'function') throw new Error(`Node element ${name} is not a function`); - - NodeElements.set(name, nodeElement); -} - -const parseSwizzle = props => props.replace(/r|s/g, 'x').replace(/g|t/g, 'y').replace(/b|p/g, 'z').replace(/a|q/g, 'w'); - -const shaderNodeHandler = { - setup(NodeClosure, params) { - const inputs = params.shift(); - - return NodeClosure(nodeObjects(inputs), ...params); - }, - - get(node, prop, nodeObj) { - if (typeof prop === 'string' && node[prop] === undefined) { - if (node.isStackNode !== true && prop === 'assign') { - return (...params) => { - currentStack.assign(nodeObj, ...params); - - return nodeObj; - }; - } else if (NodeElements.has(prop)) { - const nodeElement = NodeElements.get(prop); - - return node.isStackNode - ? (...params) => nodeObj.add(nodeElement(...params)) - : (...params) => nodeElement(nodeObj, ...params); - } else if (prop === 'self') { - return node; - } else if (prop.endsWith('Assign') && NodeElements.has(prop.slice(0, prop.length - 'Assign'.length))) { - const nodeElement = NodeElements.get(prop.slice(0, prop.length - 'Assign'.length)); - - return node.isStackNode - ? (...params) => nodeObj.assign(params[0], nodeElement(...params)) - : (...params) => nodeObj.assign(nodeElement(nodeObj, ...params)); - } else if (/^[xyzwrgbastpq]{1,4}$/.test(prop) === true) { - // accessing properties ( swizzle ) - - prop = parseSwizzle(prop); - - return nodeObject(new SplitNode(nodeObj, prop)); - } else if (/^set[XYZWRGBASTPQ]{1,4}$/.test(prop) === true) { - // set properties ( swizzle ) - - prop = parseSwizzle(prop.slice(3).toLowerCase()); - - // sort to xyzw sequence - - prop = prop.split('').sort().join(''); - - return value => nodeObject(new SetNode(node, prop, value)); - } else if (prop === 'width' || prop === 'height' || prop === 'depth') { - // accessing property - - if (prop === 'width') prop = 'x'; - else if (prop === 'height') prop = 'y'; - else if (prop === 'depth') prop = 'z'; - - return nodeObject(new SplitNode(node, prop)); - } else if (/^\d+$/.test(prop) === true) { - // accessing array - - return nodeObject(new ArrayElementNode(nodeObj, new ConstNode(Number(prop), 'uint'))); - } - } - - return Reflect.get(node, prop, nodeObj); - }, - - set(node, prop, value, nodeObj) { - if (typeof prop === 'string' && node[prop] === undefined) { - // setting properties - - if ( - /^[xyzwrgbastpq]{1,4}$/.test(prop) === true || - prop === 'width' || - prop === 'height' || - prop === 'depth' || - /^\d+$/.test(prop) === true - ) { - nodeObj[prop].assign(value); - - return true; - } - } - - return Reflect.set(node, prop, value, nodeObj); - }, -}; - -const nodeObjectsCacheMap = new WeakMap(); -const nodeBuilderFunctionsCacheMap = new WeakMap(); - -const ShaderNodeObject = function (obj, altType = null) { - const type = getValueType(obj); - - if (type === 'node') { - let nodeObject = nodeObjectsCacheMap.get(obj); - - if (nodeObject === undefined) { - nodeObject = new Proxy(obj, shaderNodeHandler); - - nodeObjectsCacheMap.set(obj, nodeObject); - nodeObjectsCacheMap.set(nodeObject, nodeObject); - } - - return nodeObject; - } else if ( - (altType === null && (type === 'float' || type === 'boolean')) || - (type && type !== 'shader' && type !== 'string') - ) { - return nodeObject(getConstNode(obj, altType)); - } else if (type === 'shader') { - return tslFn(obj); - } - - return obj; -}; - -const ShaderNodeObjects = function (objects, altType = null) { - for (const name in objects) { - objects[name] = nodeObject(objects[name], altType); - } - - return objects; -}; - -const ShaderNodeArray = function (array, altType = null) { - const len = array.length; - - for (let i = 0; i < len; i++) { - array[i] = nodeObject(array[i], altType); - } - - return array; -}; - -const ShaderNodeProxy = function (NodeClass, scope = null, factor = null, settings = null) { - const assignNode = node => nodeObject(settings !== null ? Object.assign(node, settings) : node); - - if (scope === null) { - return (...params) => { - return assignNode(new NodeClass(...nodeArray(params))); - }; - } else if (factor !== null) { - factor = nodeObject(factor); - - return (...params) => { - return assignNode(new NodeClass(scope, ...nodeArray(params), factor)); - }; - } else { - return (...params) => { - return assignNode(new NodeClass(scope, ...nodeArray(params))); - }; - } -}; - -const ShaderNodeImmutable = function (NodeClass, ...params) { - return nodeObject(new NodeClass(...nodeArray(params))); -}; - -class ShaderCallNodeInternal extends Node { - constructor(shaderNode, inputNodes) { - super(); - - this.shaderNode = shaderNode; - this.inputNodes = inputNodes; - } - - getNodeType(builder) { - const properties = builder.getNodeProperties(this); - - if (properties.outputNode === null) { - properties.outputNode = this.setupOutput(builder); - } - - return properties.outputNode.getNodeType(builder); - } - - call(builder) { - const { shaderNode, inputNodes } = this; - - if (shaderNode.layout) { - let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get(builder.constructor); - - if (functionNodesCacheMap === undefined) { - functionNodesCacheMap = new WeakMap(); - - nodeBuilderFunctionsCacheMap.set(builder.constructor, functionNodesCacheMap); - } - - let functionNode = functionNodesCacheMap.get(shaderNode); - - if (functionNode === undefined) { - functionNode = nodeObject(builder.buildFunctionNode(shaderNode)); - - functionNodesCacheMap.set(shaderNode, functionNode); - } - - if (builder.currentFunctionNode !== null) { - builder.currentFunctionNode.includes.push(functionNode); - } - - return nodeObject(functionNode.call(inputNodes)); - } - - const jsFunc = shaderNode.jsFunc; - const outputNode = - inputNodes !== null ? jsFunc(inputNodes, builder.stack, builder) : jsFunc(builder.stack, builder); - - return nodeObject(outputNode); - } - - setup(builder) { - const { outputNode } = builder.getNodeProperties(this); - - return outputNode || this.setupOutput(builder); - } - - setupOutput(builder) { - builder.addStack(); - - builder.stack.outputNode = this.call(builder); - - return builder.removeStack(); - } - - generate(builder, output) { - const { outputNode } = builder.getNodeProperties(this); - - if (outputNode === null) { - // TSL: It's recommended to use `tslFn` in setup() pass. - - return this.call(builder).build(builder, output); - } - - return super.generate(builder, output); - } -} - -class ShaderNodeInternal extends Node { - constructor(jsFunc) { - super(); - - this.jsFunc = jsFunc; - this.layout = null; - - this.global = true; - } - - get isArrayInput() { - return /^\((\s+)?\[/.test(this.jsFunc.toString()); - } - - setLayout(layout) { - this.layout = layout; - - return this; - } - - call(inputs = null) { - nodeObjects(inputs); - - return nodeObject(new ShaderCallNodeInternal(this, inputs)); - } - - setup() { - return this.call(); - } -} - -const bools = [false, true]; -const uints = [0, 1, 2, 3]; -const ints = [-1, -2]; -const floats = [ - 0.5, - 1.5, - 1 / 3, - 1e-6, - 1e6, - Math.PI, - Math.PI * 2, - 1 / Math.PI, - 2 / Math.PI, - 1 / (Math.PI * 2), - Math.PI / 2, -]; - -const boolsCacheMap = new Map(); -for (const bool of bools) boolsCacheMap.set(bool, new ConstNode(bool)); - -const uintsCacheMap = new Map(); -for (const uint of uints) uintsCacheMap.set(uint, new ConstNode(uint, 'uint')); - -const intsCacheMap = new Map([...uintsCacheMap].map(el => new ConstNode(el.value, 'int'))); -for (const int of ints) intsCacheMap.set(int, new ConstNode(int, 'int')); - -const floatsCacheMap = new Map([...intsCacheMap].map(el => new ConstNode(el.value))); -for (const float of floats) floatsCacheMap.set(float, new ConstNode(float)); -for (const float of floats) floatsCacheMap.set(-float, new ConstNode(-float)); - -const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; - -const constNodesCacheMap = new Map([...boolsCacheMap, ...floatsCacheMap]); - -const getConstNode = (value, type) => { - if (constNodesCacheMap.has(value)) { - return constNodesCacheMap.get(value); - } else if (value.isNode === true) { - return value; - } else { - return new ConstNode(value, type); - } -}; - -const safeGetNodeType = node => { - try { - return node.getNodeType(); - } catch (_) { - return undefined; - } -}; - -const ConvertType = function (type, cacheMap = null) { - return (...params) => { - if ( - params.length === 0 || - (!['bool', 'float', 'int', 'uint'].includes(type) && params.every(param => typeof param !== 'object')) - ) { - params = [getValueFromType(type, ...params)]; - } - - if (params.length === 1 && cacheMap !== null && cacheMap.has(params[0])) { - return nodeObject(cacheMap.get(params[0])); - } - - if (params.length === 1) { - const node = getConstNode(params[0], type); - if (safeGetNodeType(node) === type) return nodeObject(node); - return nodeObject(new ConvertNode(node, type)); - } - - const nodes = params.map(param => getConstNode(param)); - return nodeObject(new JoinNode(nodes, type)); - }; -}; - -// exports - -export const defined = value => value && value.value; - -// utils - -export const getConstNodeType = value => - value !== undefined && value !== null - ? value.nodeType || value.convertTo || (typeof value === 'string' ? value : null) - : null; - -// shader node base - -export function ShaderNode(jsFunc) { - return new Proxy(new ShaderNodeInternal(jsFunc), shaderNodeHandler); -} - -export const nodeObject = (val, altType = null) => /* new */ ShaderNodeObject(val, altType); -export const nodeObjects = (val, altType = null) => new ShaderNodeObjects(val, altType); -export const nodeArray = (val, altType = null) => new ShaderNodeArray(val, altType); -export const nodeProxy = (...params) => new ShaderNodeProxy(...params); -export const nodeImmutable = (...params) => new ShaderNodeImmutable(...params); - -export const tslFn = jsFunc => { - const shaderNode = new ShaderNode(jsFunc); - - const fn = (...params) => { - let inputs; - - nodeObjects(params); - - if (params[0] && params[0].isNode) { - inputs = [...params]; - } else { - inputs = params[0]; - } - - return shaderNode.call(inputs); - }; - - fn.shaderNode = shaderNode; - fn.setLayout = layout => { - shaderNode.setLayout(layout); - - return fn; - }; - - return fn; -}; - -addNodeClass('ShaderNode', ShaderNode); - -// - -addNodeElement('toGlobal', node => { - node.global = true; - - return node; -}); - -// - -export const setCurrentStack = stack => { - if (currentStack === stack) { - //throw new Error( 'Stack already defined.' ); - } - - currentStack = stack; -}; - -export const getCurrentStack = () => currentStack; - -export const If = (...params) => currentStack.if(...params); - -export function append(node) { - if (currentStack) currentStack.add(node); - - return node; -} - -addNodeElement('append', append); - -// types -// @TODO: Maybe export from ConstNode.js? - -export const color = new ConvertType('color'); - -export const float = new ConvertType('float', cacheMaps.float); -export const int = new ConvertType('int', cacheMaps.ints); -export const uint = new ConvertType('uint', cacheMaps.uint); -export const bool = new ConvertType('bool', cacheMaps.bool); - -export const vec2 = new ConvertType('vec2'); -export const ivec2 = new ConvertType('ivec2'); -export const uvec2 = new ConvertType('uvec2'); -export const bvec2 = new ConvertType('bvec2'); - -export const vec3 = new ConvertType('vec3'); -export const ivec3 = new ConvertType('ivec3'); -export const uvec3 = new ConvertType('uvec3'); -export const bvec3 = new ConvertType('bvec3'); - -export const vec4 = new ConvertType('vec4'); -export const ivec4 = new ConvertType('ivec4'); -export const uvec4 = new ConvertType('uvec4'); -export const bvec4 = new ConvertType('bvec4'); - -export const mat2 = new ConvertType('mat2'); -export const imat2 = new ConvertType('imat2'); -export const umat2 = new ConvertType('umat2'); -export const bmat2 = new ConvertType('bmat2'); - -export const mat3 = new ConvertType('mat3'); -export const imat3 = new ConvertType('imat3'); -export const umat3 = new ConvertType('umat3'); -export const bmat3 = new ConvertType('bmat3'); - -export const mat4 = new ConvertType('mat4'); -export const imat4 = new ConvertType('imat4'); -export const umat4 = new ConvertType('umat4'); -export const bmat4 = new ConvertType('bmat4'); - -export const string = (value = '') => nodeObject(new ConstNode(value, 'string')); -export const arrayBuffer = value => nodeObject(new ConstNode(value, 'ArrayBuffer')); - -addNodeElement('toColor', color); -addNodeElement('toFloat', float); -addNodeElement('toInt', int); -addNodeElement('toUint', uint); -addNodeElement('toBool', bool); -addNodeElement('toVec2', vec2); -addNodeElement('toIvec2', ivec2); -addNodeElement('toUvec2', uvec2); -addNodeElement('toBvec2', bvec2); -addNodeElement('toVec3', vec3); -addNodeElement('toIvec3', ivec3); -addNodeElement('toUvec3', uvec3); -addNodeElement('toBvec3', bvec3); -addNodeElement('toVec4', vec4); -addNodeElement('toIvec4', ivec4); -addNodeElement('toUvec4', uvec4); -addNodeElement('toBvec4', bvec4); -addNodeElement('toMat2', mat2); -addNodeElement('toImat2', imat2); -addNodeElement('toUmat2', umat2); -addNodeElement('toBmat2', bmat2); -addNodeElement('toMat3', mat3); -addNodeElement('toImat3', imat3); -addNodeElement('toUmat3', umat3); -addNodeElement('toBmat3', bmat3); -addNodeElement('toMat4', mat4); -addNodeElement('toImat4', imat4); -addNodeElement('toUmat4', umat4); -addNodeElement('toBmat4', bmat4); - -// basic nodes -// HACK - we cannot export them from the corresponding files because of the cyclic dependency -export const element = nodeProxy(ArrayElementNode); -export const convert = (node, types) => nodeObject(new ConvertNode(nodeObject(node), types)); -export const split = (node, channels) => nodeObject(new SplitNode(nodeObject(node), channels)); - -addNodeElement('element', element); -addNodeElement('convert', convert); diff --git a/examples-jsm/examples/renderers/common/Animation.ts b/examples-jsm/examples/renderers/common/Animation.ts deleted file mode 100644 index 0b00319a1..000000000 --- a/examples-jsm/examples/renderers/common/Animation.ts +++ /dev/null @@ -1,38 +0,0 @@ -class Animation { - constructor(nodes, info) { - this.nodes = nodes; - this.info = info; - - this.animationLoop = null; - this.requestId = null; - - this._init(); - } - - _init() { - const update = (time, frame) => { - this.requestId = self.requestAnimationFrame(update); - - if (this.info.autoReset === true) this.info.reset(); - - this.nodes.nodeFrame.update(); - - this.info.frame = this.nodes.nodeFrame.frameId; - - if (this.animationLoop !== null) this.animationLoop(time, frame); - }; - - update(); - } - - dispose() { - self.cancelAnimationFrame(this.requestId); - this.requestId = null; - } - - setAnimationLoop(callback) { - this.animationLoop = callback; - } -} - -export default Animation; diff --git a/examples-jsm/examples/renderers/common/Attributes.ts b/examples-jsm/examples/renderers/common/Attributes.ts deleted file mode 100644 index 295535406..000000000 --- a/examples-jsm/examples/renderers/common/Attributes.ts +++ /dev/null @@ -1,53 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; -import { DynamicDrawUsage } from 'three'; - -class Attributes extends DataMap { - constructor(backend) { - super(); - - this.backend = backend; - } - - delete(attribute) { - const attributeData = super.delete(attribute); - - if (attributeData !== undefined) { - this.backend.destroyAttribute(attribute); - } - - return attributeData; - } - - update(attribute, type) { - const data = this.get(attribute); - - if (data.version === undefined) { - if (type === AttributeType.VERTEX) { - this.backend.createAttribute(attribute); - } else if (type === AttributeType.INDEX) { - this.backend.createIndexAttribute(attribute); - } else if (type === AttributeType.STORAGE) { - this.backend.createStorageAttribute(attribute); - } - - data.version = this._getBufferAttribute(attribute).version; - } else { - const bufferAttribute = this._getBufferAttribute(attribute); - - if (data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage) { - this.backend.updateAttribute(attribute); - - data.version = bufferAttribute.version; - } - } - } - - _getBufferAttribute(attribute) { - if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; - - return attribute; - } -} - -export default Attributes; diff --git a/examples-jsm/examples/renderers/common/Backend.ts b/examples-jsm/examples/renderers/common/Backend.ts deleted file mode 100644 index efa5649d5..000000000 --- a/examples-jsm/examples/renderers/common/Backend.ts +++ /dev/null @@ -1,165 +0,0 @@ -let vector2 = null; -let vector4 = null; -let color4 = null; - -import Color4 from './Color4.js'; -import { Vector2, Vector4, REVISION, createCanvasElement } from 'three'; - -class Backend { - constructor(parameters = {}) { - this.parameters = Object.assign({}, parameters); - this.data = new WeakMap(); - this.renderer = null; - this.domElement = null; - } - - async init(renderer) { - this.renderer = renderer; - } - - // render context - - begin(renderContext) {} - - finish(renderContext) {} - - // render object - - draw(renderObject, info) {} - - // program - - createProgram(program) {} - - destroyProgram(program) {} - - // bindings - - createBindings(renderObject) {} - - // pipeline - - createRenderPipeline(renderObject) {} - - createComputePipeline(computeNode, pipeline) {} - - destroyPipeline(pipeline) {} - - // cache key - - needsRenderUpdate(renderObject) {} // return Boolean ( fast test ) - - getRenderCacheKey(renderObject) {} // return String - - // node builder - - createNodeBuilder(renderObject) {} // return NodeBuilder (ADD IT) - - // textures - - createSampler(texture) {} - - createDefaultTexture(texture) {} - - createTexture(texture) {} - - copyTextureToBuffer(texture, x, y, width, height) {} - - // attributes - - createAttribute(attribute) {} - - createIndexAttribute(attribute) {} - - updateAttribute(attribute) {} - - destroyAttribute(attribute) {} - - // canvas - - getContext() {} - - updateSize() {} - - // utils - - resolveTimestampAsync(renderContext, type) {} - - hasFeatureAsync(name) {} // return Boolean - - hasFeature(name) {} // return Boolean - - getInstanceCount(renderObject) { - const { object, geometry } = renderObject; - - return geometry.isInstancedBufferGeometry ? geometry.instanceCount : object.count > 1 ? object.count : 1; - } - - getDrawingBufferSize() { - vector2 = vector2 || new Vector2(); - - return this.renderer.getDrawingBufferSize(vector2); - } - - getScissor() { - vector4 = vector4 || new Vector4(); - - return this.renderer.getScissor(vector4); - } - - setScissorTest(boolean) {} - - getClearColor() { - const renderer = this.renderer; - - color4 = color4 || new Color4(); - - renderer.getClearColor(color4); - - color4.getRGB(color4, this.renderer.currentColorSpace); - - return color4; - } - - getDomElement() { - let domElement = this.domElement; - - if (domElement === null) { - domElement = this.parameters.canvas !== undefined ? this.parameters.canvas : createCanvasElement(); - - // OffscreenCanvas does not have setAttribute, see #22811 - if ('setAttribute' in domElement) domElement.setAttribute('data-engine', `three.js r${REVISION} webgpu`); - - this.domElement = domElement; - } - - return domElement; - } - - // resource properties - - set(object, value) { - this.data.set(object, value); - } - - get(object) { - let map = this.data.get(object); - - if (map === undefined) { - map = {}; - this.data.set(object, map); - } - - return map; - } - - has(object) { - return this.data.has(object); - } - - delete(object) { - this.data.delete(object); - } -} - -export default Backend; diff --git a/examples-jsm/examples/renderers/common/Background.ts b/examples-jsm/examples/renderers/common/Background.ts deleted file mode 100644 index b7902dd40..000000000 --- a/examples-jsm/examples/renderers/common/Background.ts +++ /dev/null @@ -1,118 +0,0 @@ -import DataMap from './DataMap.js'; -import Color4 from './Color4.js'; -import { Mesh, SphereGeometry, BackSide, LinearSRGBColorSpace } from 'three'; -import { - vec4, - context, - normalWorld, - backgroundBlurriness, - backgroundIntensity, - NodeMaterial, - modelViewProjection, -} from '../../nodes/Nodes.js'; - -const _clearColor = new Color4(); - -class Background extends DataMap { - constructor(renderer, nodes) { - super(); - - this.renderer = renderer; - this.nodes = nodes; - } - - update(scene, renderList, renderContext) { - const renderer = this.renderer; - const background = this.nodes.getBackgroundNode(scene) || scene.background; - - let forceClear = false; - - if (background === null) { - // no background settings, use clear color configuration from the renderer - - renderer._clearColor.getRGB(_clearColor, LinearSRGBColorSpace); - _clearColor.a = renderer._clearColor.a; - } else if (background.isColor === true) { - // background is an opaque color - - background.getRGB(_clearColor, LinearSRGBColorSpace); - _clearColor.a = 1; - - forceClear = true; - } else if (background.isNode === true) { - const sceneData = this.get(scene); - const backgroundNode = background; - - _clearColor.copy(renderer._clearColor); - - let backgroundMesh = sceneData.backgroundMesh; - - if (backgroundMesh === undefined) { - const backgroundMeshNode = context(vec4(backgroundNode).mul(backgroundIntensity), { - // @TODO: Add Texture2D support using node context - getUV: () => normalWorld, - getTextureLevel: () => backgroundBlurriness, - }); - - let viewProj = modelViewProjection(); - viewProj = viewProj.setZ(viewProj.w); - - const nodeMaterial = new NodeMaterial(); - nodeMaterial.side = BackSide; - nodeMaterial.depthTest = false; - nodeMaterial.depthWrite = false; - nodeMaterial.fog = false; - nodeMaterial.vertexNode = viewProj; - nodeMaterial.fragmentNode = backgroundMeshNode; - - sceneData.backgroundMeshNode = backgroundMeshNode; - sceneData.backgroundMesh = backgroundMesh = new Mesh(new SphereGeometry(1, 32, 32), nodeMaterial); - backgroundMesh.frustumCulled = false; - - backgroundMesh.onBeforeRender = function (renderer, scene, camera) { - this.matrixWorld.copyPosition(camera.matrixWorld); - }; - } - - const backgroundCacheKey = backgroundNode.getCacheKey(); - - if (sceneData.backgroundCacheKey !== backgroundCacheKey) { - sceneData.backgroundMeshNode.node = vec4(backgroundNode).mul(backgroundIntensity); - - backgroundMesh.material.needsUpdate = true; - - sceneData.backgroundCacheKey = backgroundCacheKey; - } - - renderList.unshift(backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null); - } else { - console.error('THREE.Renderer: Unsupported background configuration.', background); - } - - // - - if (renderer.autoClear === true || forceClear === true) { - _clearColor.multiplyScalar(_clearColor.a); - - const clearColorValue = renderContext.clearColorValue; - - clearColorValue.r = _clearColor.r; - clearColorValue.g = _clearColor.g; - clearColorValue.b = _clearColor.b; - clearColorValue.a = _clearColor.a; - - renderContext.depthClearValue = renderer._clearDepth; - renderContext.stencilClearValue = renderer._clearStencil; - - renderContext.clearColor = renderer.autoClearColor === true; - renderContext.clearDepth = renderer.autoClearDepth === true; - renderContext.clearStencil = renderer.autoClearStencil === true; - } else { - renderContext.clearColor = false; - renderContext.clearDepth = false; - renderContext.clearStencil = false; - } - } -} - -export default Background; diff --git a/examples-jsm/examples/renderers/common/BindGroup.ts b/examples-jsm/examples/renderers/common/BindGroup.ts deleted file mode 100644 index 6b7ffa217..000000000 --- a/examples-jsm/examples/renderers/common/BindGroup.ts +++ /dev/null @@ -1,12 +0,0 @@ -let _id = 0; - -class BindGroup { - constructor(name = '', bindings = []) { - this.name = name; - this.bindings = bindings; - - this.id = _id++; - } -} - -export default BindGroup; diff --git a/examples-jsm/examples/renderers/common/Binding.ts b/examples-jsm/examples/renderers/common/Binding.ts deleted file mode 100644 index a12f3563b..000000000 --- a/examples-jsm/examples/renderers/common/Binding.ts +++ /dev/null @@ -1,17 +0,0 @@ -class Binding { - constructor(name = '') { - this.name = name; - - this.visibility = 0; - } - - setVisibility(visibility) { - this.visibility |= visibility; - } - - clone() { - return Object.assign(new this.constructor(), this); - } -} - -export default Binding; diff --git a/examples-jsm/examples/renderers/common/Bindings.ts b/examples-jsm/examples/renderers/common/Bindings.ts deleted file mode 100644 index 51aa31f0d..000000000 --- a/examples-jsm/examples/renderers/common/Bindings.ts +++ /dev/null @@ -1,161 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; - -class Bindings extends DataMap { - constructor(backend, nodes, textures, attributes, pipelines, info) { - super(); - - this.backend = backend; - this.textures = textures; - this.pipelines = pipelines; - this.attributes = attributes; - this.nodes = nodes; - this.info = info; - - this.pipelines.bindings = this; // assign bindings to pipelines - } - - getForRender(renderObject) { - const bindings = renderObject.getBindings(); - - for (const bindGroup of bindings) { - const groupData = this.get(bindGroup); - - if (groupData.bindGroup === undefined) { - // each object defines an array of bindings (ubos, textures, samplers etc.) - - this._init(bindGroup); - - this.backend.createBindings(bindGroup, bindings); - - groupData.bindGroup = bindGroup; - } - } - - return bindings; - } - - getForCompute(computeNode) { - const bindings = this.nodes.getForCompute(computeNode).bindings; - - for (const bindGroup of bindings) { - const groupData = this.get(bindGroup); - - if (groupData.bindGroup === undefined) { - this._init(bindGroup); - - this.backend.createBindings(bindGroup, bindings); - - groupData.bindGroup = bindGroup; - } - } - - return bindings; - } - - updateForCompute(computeNode) { - this._updateBindings(computeNode, this.getForCompute(computeNode)); - } - - updateForRender(renderObject) { - this._updateBindings(renderObject, this.getForRender(renderObject)); - } - - _updateBindings(object, bindings) { - for (const bindGroup of bindings) { - this._update(object, bindGroup, bindings); - } - } - - _init(bindGroup) { - for (const binding of bindGroup.bindings) { - if (binding.isSampledTexture) { - this.textures.updateTexture(binding.texture); - } else if (binding.isStorageBuffer) { - const attribute = binding.attribute; - - this.attributes.update(attribute, AttributeType.STORAGE); - } - } - } - - _update(object, bindGroup, bindings) { - const { backend } = this; - - let needsBindingsUpdate = false; - - // iterate over all bindings and check if buffer updates or a new binding group is required - - for (const binding of bindGroup.bindings) { - if (binding.isNodeUniformsGroup) { - const updated = this.nodes.updateGroup(binding); - - if (!updated) continue; - } - - if (binding.isUniformBuffer) { - const updated = binding.update(); - - if (updated) { - backend.updateBinding(binding); - } - } else if (binding.isSampler) { - binding.update(); - } else if (binding.isSampledTexture) { - const texture = binding.texture; - - if (binding.needsBindingsUpdate) needsBindingsUpdate = true; - - const updated = binding.update(); - - if (updated) { - this.textures.updateTexture(binding.texture); - } - - const textureData = backend.get(binding.texture); - - if ( - backend.isWebGPUBackend === true && - textureData.texture === undefined && - textureData.externalTexture === undefined - ) { - // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend - console.error( - 'Bindings._update: binding should be available:', - binding, - updated, - binding.texture, - binding.textureNode.value, - ); - - this.textures.updateTexture(binding.texture); - needsBindingsUpdate = true; - } - - if (texture.isStorageTexture === true) { - const textureData = this.get(texture); - - if (binding.store === true) { - textureData.needsMipmap = true; - } else if ( - texture.generateMipmaps === true && - this.textures.needsMipmaps(texture) && - textureData.needsMipmap === true - ) { - this.backend.generateMipmaps(texture); - - textureData.needsMipmap = false; - } - } - } - } - - if (needsBindingsUpdate === true) { - const pipeline = this.pipelines.getForRender(object); - - this.backend.updateBindings(bindGroup, bindings, pipeline); - } - } -} - -export default Bindings; diff --git a/examples-jsm/examples/renderers/common/Buffer.ts b/examples-jsm/examples/renderers/common/Buffer.ts deleted file mode 100644 index 17013c6dc..000000000 --- a/examples-jsm/examples/renderers/common/Buffer.ts +++ /dev/null @@ -1,28 +0,0 @@ -import Binding from './Binding.js'; -import { getFloatLength } from './BufferUtils.js'; - -class Buffer extends Binding { - constructor(name, buffer = null) { - super(name); - - this.isBuffer = true; - - this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT; - - this._buffer = buffer; - } - - get byteLength() { - return getFloatLength(this._buffer.byteLength); - } - - get buffer() { - return this._buffer; - } - - update() { - return true; - } -} - -export default Buffer; diff --git a/examples-jsm/examples/renderers/common/BufferUtils.ts b/examples-jsm/examples/renderers/common/BufferUtils.ts deleted file mode 100644 index 99ddcb48b..000000000 --- a/examples-jsm/examples/renderers/common/BufferUtils.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { GPU_CHUNK_BYTES } from './Constants.js'; - -function getFloatLength(floatLength) { - // ensure chunk size alignment (STD140 layout) - - return floatLength + ((GPU_CHUNK_BYTES - (floatLength % GPU_CHUNK_BYTES)) % GPU_CHUNK_BYTES); -} - -function getVectorLength(count, vectorLength = 4) { - const strideLength = getStrideLength(vectorLength); - - const floatLength = strideLength * count; - - return getFloatLength(floatLength); -} - -function getStrideLength(vectorLength) { - const strideLength = 4; - - return vectorLength + ((strideLength - (vectorLength % strideLength)) % strideLength); -} - -export { getFloatLength, getVectorLength, getStrideLength }; diff --git a/examples-jsm/examples/renderers/common/ChainMap.ts b/examples-jsm/examples/renderers/common/ChainMap.ts deleted file mode 100644 index b17e7080f..000000000 --- a/examples-jsm/examples/renderers/common/ChainMap.ts +++ /dev/null @@ -1,43 +0,0 @@ -export default class ChainMap { - constructor() { - this.weakMap = new WeakMap(); - } - - get(keys) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - map = map.get(keys[i]); - - if (map === undefined) return undefined; - } - - return map.get(keys[keys.length - 1]); - } - - set(keys, value) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - - if (map.has(key) === false) map.set(key, new WeakMap()); - - map = map.get(key); - } - - return map.set(keys[keys.length - 1], value); - } - - delete(keys) { - let map = this.weakMap; - - for (let i = 0; i < keys.length; i++) { - map = map.get(keys[i]); - - if (map === undefined) return false; - } - - return map.delete(keys[keys.length - 1]); - } -} diff --git a/examples-jsm/examples/renderers/common/ClippingContext.ts b/examples-jsm/examples/renderers/common/ClippingContext.ts deleted file mode 100644 index 312e0b779..000000000 --- a/examples-jsm/examples/renderers/common/ClippingContext.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { Matrix3, Plane, Vector4 } from 'three'; - -const _plane = new Plane(); - -let _clippingContextVersion = 0; - -class ClippingContext { - constructor() { - this.version = ++_clippingContextVersion; - - this.globalClippingCount = 0; - - this.localClippingCount = 0; - this.localClippingEnabled = false; - this.localClipIntersection = false; - - this.planes = []; - - this.parentVersion = 0; - this.viewNormalMatrix = new Matrix3(); - } - - projectPlanes(source, offset) { - const l = source.length; - const planes = this.planes; - - for (let i = 0; i < l; i++) { - _plane.copy(source[i]).applyMatrix4(this.viewMatrix, this.viewNormalMatrix); - - const v = planes[offset + i]; - const normal = _plane.normal; - - v.x = -normal.x; - v.y = -normal.y; - v.z = -normal.z; - v.w = _plane.constant; - } - } - - updateGlobal(renderer, camera) { - const rendererClippingPlanes = renderer.clippingPlanes; - this.viewMatrix = camera.matrixWorldInverse; - - this.viewNormalMatrix.getNormalMatrix(this.viewMatrix); - - let update = false; - - if (Array.isArray(rendererClippingPlanes) && rendererClippingPlanes.length !== 0) { - const l = rendererClippingPlanes.length; - - if (l !== this.globalClippingCount) { - const planes = []; - - for (let i = 0; i < l; i++) { - planes.push(new Vector4()); - } - - this.globalClippingCount = l; - this.planes = planes; - - update = true; - } - - this.projectPlanes(rendererClippingPlanes, 0); - } else if (this.globalClippingCount !== 0) { - this.globalClippingCount = 0; - this.planes = []; - update = true; - } - - if (renderer.localClippingEnabled !== this.localClippingEnabled) { - this.localClippingEnabled = renderer.localClippingEnabled; - update = true; - } - - if (update) this.version = _clippingContextVersion++; - } - - update(parent, material) { - let update = false; - - if (this !== parent && parent.version !== this.parentVersion) { - this.globalClippingCount = material.isShadowNodeMaterial ? 0 : parent.globalClippingCount; - this.localClippingEnabled = parent.localClippingEnabled; - this.planes = Array.from(parent.planes); - this.parentVersion = parent.version; - this.viewMatrix = parent.viewMatrix; - this.viewNormalMatrix = parent.viewNormalMatrix; - - update = true; - } - - if (this.localClippingEnabled) { - const localClippingPlanes = material.clippingPlanes; - - if (Array.isArray(localClippingPlanes) && localClippingPlanes.length !== 0) { - const l = localClippingPlanes.length; - const planes = this.planes; - const offset = this.globalClippingCount; - - if (update || l !== this.localClippingCount) { - planes.length = offset + l; - - for (let i = 0; i < l; i++) { - planes[offset + i] = new Vector4(); - } - - this.localClippingCount = l; - update = true; - } - - this.projectPlanes(localClippingPlanes, offset); - } else if (this.localClippingCount !== 0) { - this.localClippingCount = 0; - update = true; - } - - if (this.localClipIntersection !== material.clipIntersection) { - this.localClipIntersection = material.clipIntersection; - update = true; - } - } - - if (update) this.version = _clippingContextVersion++; - } -} - -export default ClippingContext; diff --git a/examples-jsm/examples/renderers/common/Color4.ts b/examples-jsm/examples/renderers/common/Color4.ts deleted file mode 100644 index c681cc908..000000000 --- a/examples-jsm/examples/renderers/common/Color4.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Color } from 'three'; - -class Color4 extends Color { - constructor(r, g, b, a = 1) { - super(r, g, b); - - this.a = a; - } - - set(r, g, b, a = 1) { - this.a = a; - - return super.set(r, g, b); - } - - copy(color) { - if (color.a !== undefined) this.a = color.a; - - return super.copy(color); - } - - clone() { - return new this.constructor(this.r, this.g, this.b, this.a); - } -} - -export default Color4; diff --git a/examples-jsm/examples/renderers/common/ComputePipeline.ts b/examples-jsm/examples/renderers/common/ComputePipeline.ts deleted file mode 100644 index 0fd3ca531..000000000 --- a/examples-jsm/examples/renderers/common/ComputePipeline.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Pipeline from './Pipeline.js'; - -class ComputePipeline extends Pipeline { - constructor(cacheKey, computeProgram) { - super(cacheKey); - - this.computeProgram = computeProgram; - - this.isComputePipeline = true; - } -} - -export default ComputePipeline; diff --git a/examples-jsm/examples/renderers/common/Constants.ts b/examples-jsm/examples/renderers/common/Constants.ts deleted file mode 100644 index 0d0c35a25..000000000 --- a/examples-jsm/examples/renderers/common/Constants.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const AttributeType = { - VERTEX: 1, - INDEX: 2, - STORAGE: 4, -}; - -// size of a chunk in bytes (STD140 layout) - -export const GPU_CHUNK_BYTES = 16; - -// @TODO: Move to src/constants.js - -export const BlendColorFactor = 211; -export const OneMinusBlendColorFactor = 212; diff --git a/examples-jsm/examples/renderers/common/CubeRenderTarget.ts b/examples-jsm/examples/renderers/common/CubeRenderTarget.ts deleted file mode 100644 index 74d04912b..000000000 --- a/examples-jsm/examples/renderers/common/CubeRenderTarget.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { - WebGLCubeRenderTarget, - Scene, - CubeCamera, - BoxGeometry, - Mesh, - BackSide, - NoBlending, - LinearFilter, - LinearMipmapLinearFilter, -} from 'three'; -import { equirectUV } from '../../nodes/utils/EquirectUVNode.js'; -import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js'; -import { positionWorldDirection } from '../../nodes/accessors/PositionNode.js'; -import { createNodeMaterialFromType } from '../../nodes/materials/NodeMaterial.js'; - -// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget - -class CubeRenderTarget extends WebGLCubeRenderTarget { - constructor(size = 1, options = {}) { - super(size, options); - - this.isCubeRenderTarget = true; - } - - fromEquirectangularTexture(renderer, texture) { - const currentMinFilter = texture.minFilter; - const currentGenerateMipmaps = texture.generateMipmaps; - - texture.generateMipmaps = true; - - this.texture.type = texture.type; - this.texture.colorSpace = texture.colorSpace; - - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; - - const geometry = new BoxGeometry(5, 5, 5); - - const uvNode = equirectUV(positionWorldDirection); - - const material = createNodeMaterialFromType('MeshBasicNodeMaterial'); - material.colorNode = TSL_Texture(texture, uvNode, 0); - material.side = BackSide; - material.blending = NoBlending; - - const mesh = new Mesh(geometry, material); - - const scene = new Scene(); - scene.add(mesh); - - // Avoid blurred poles - if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter; - - const camera = new CubeCamera(1, 10, this); - camera.update(renderer, scene); - - texture.minFilter = currentMinFilter; - texture.currentGenerateMipmaps = currentGenerateMipmaps; - - mesh.geometry.dispose(); - mesh.material.dispose(); - - return this; - } -} - -export default CubeRenderTarget; diff --git a/examples-jsm/examples/renderers/common/DataMap.ts b/examples-jsm/examples/renderers/common/DataMap.ts deleted file mode 100644 index 006bc2950..000000000 --- a/examples-jsm/examples/renderers/common/DataMap.ts +++ /dev/null @@ -1,38 +0,0 @@ -class DataMap { - constructor() { - this.data = new WeakMap(); - } - - get(object) { - let map = this.data.get(object); - - if (map === undefined) { - map = {}; - this.data.set(object, map); - } - - return map; - } - - delete(object) { - let map; - - if (this.data.has(object)) { - map = this.data.get(object); - - this.data.delete(object); - } - - return map; - } - - has(object) { - return this.data.has(object); - } - - dispose() { - this.data = new WeakMap(); - } -} - -export default DataMap; diff --git a/examples-jsm/examples/renderers/common/Geometries.ts b/examples-jsm/examples/renderers/common/Geometries.ts deleted file mode 100644 index ca0cd225d..000000000 --- a/examples-jsm/examples/renderers/common/Geometries.ts +++ /dev/null @@ -1,182 +0,0 @@ -import DataMap from './DataMap.js'; -import { AttributeType } from './Constants.js'; -import { Uint32BufferAttribute, Uint16BufferAttribute } from 'three'; - -function arrayNeedsUint32(array) { - // assumes larger values usually on last - - for (let i = array.length - 1; i >= 0; --i) { - if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565 - } - - return false; -} - -function getWireframeVersion(geometry) { - return geometry.index !== null ? geometry.index.version : geometry.attributes.position.version; -} - -function getWireframeIndex(geometry) { - const indices = []; - - const geometryIndex = geometry.index; - const geometryPosition = geometry.attributes.position; - - if (geometryIndex !== null) { - const array = geometryIndex.array; - - for (let i = 0, l = array.length; i < l; i += 3) { - const a = array[i + 0]; - const b = array[i + 1]; - const c = array[i + 2]; - - indices.push(a, b, b, c, c, a); - } - } else { - const array = geometryPosition.array; - - for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) { - const a = i + 0; - const b = i + 1; - const c = i + 2; - - indices.push(a, b, b, c, c, a); - } - } - - const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1); - attribute.version = getWireframeVersion(geometry); - - return attribute; -} - -class Geometries extends DataMap { - constructor(attributes, info) { - super(); - - this.attributes = attributes; - this.info = info; - - this.wireframes = new WeakMap(); - - this.attributeCall = new WeakMap(); - } - - has(renderObject) { - const geometry = renderObject.geometry; - - return super.has(geometry) && this.get(geometry).initialized === true; - } - - updateForRender(renderObject) { - if (this.has(renderObject) === false) this.initGeometry(renderObject); - - this.updateAttributes(renderObject); - } - - initGeometry(renderObject) { - const geometry = renderObject.geometry; - const geometryData = this.get(geometry); - - geometryData.initialized = true; - - this.info.memory.geometries++; - - const onDispose = () => { - this.info.memory.geometries--; - - const index = geometry.index; - const geometryAttributes = renderObject.getAttributes(); - - if (index !== null) { - this.attributes.delete(index); - } - - for (const geometryAttribute of geometryAttributes) { - this.attributes.delete(geometryAttribute); - } - - const wireframeAttribute = this.wireframes.get(geometry); - - if (wireframeAttribute !== undefined) { - this.attributes.delete(wireframeAttribute); - } - - geometry.removeEventListener('dispose', onDispose); - }; - - geometry.addEventListener('dispose', onDispose); - } - - updateAttributes(renderObject) { - const attributes = renderObject.getAttributes(); - - for (const attribute of attributes) { - if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) { - this.updateAttribute(attribute, AttributeType.STORAGE); - } else { - this.updateAttribute(attribute, AttributeType.VERTEX); - } - } - - const index = this.getIndex(renderObject); - - if (index !== null) { - this.updateAttribute(index, AttributeType.INDEX); - } - } - - updateAttribute(attribute, type) { - const callId = this.info.render.calls; - - if (!attribute.isInterleavedBufferAttribute) { - if (this.attributeCall.get(attribute) !== callId) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute, callId); - } - } else { - if (this.attributeCall.get(attribute) === undefined) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute, callId); - } else if (this.attributeCall.get(attribute.data) !== callId) { - this.attributes.update(attribute, type); - - this.attributeCall.set(attribute.data, callId); - - this.attributeCall.set(attribute, callId); - } - } - } - - getIndex(renderObject) { - const { geometry, material } = renderObject; - - let index = geometry.index; - - if (material.wireframe === true) { - const wireframes = this.wireframes; - - let wireframeAttribute = wireframes.get(geometry); - - if (wireframeAttribute === undefined) { - wireframeAttribute = getWireframeIndex(geometry); - - wireframes.set(geometry, wireframeAttribute); - } else if (wireframeAttribute.version !== getWireframeVersion(geometry)) { - this.attributes.delete(wireframeAttribute); - - wireframeAttribute = getWireframeIndex(geometry); - - wireframes.set(geometry, wireframeAttribute); - } - - index = wireframeAttribute; - } - - return index; - } -} - -export default Geometries; diff --git a/examples-jsm/examples/renderers/common/Info.ts b/examples-jsm/examples/renderers/common/Info.ts deleted file mode 100644 index 4ede75de7..000000000 --- a/examples-jsm/examples/renderers/common/Info.ts +++ /dev/null @@ -1,95 +0,0 @@ -class Info { - constructor() { - this.autoReset = true; - - this.frame = 0; - this.calls = 0; - - this.render = { - calls: 0, - frameCalls: 0, - drawCalls: 0, - triangles: 0, - points: 0, - lines: 0, - timestamp: 0, - previousFrameCalls: 0, - timestampCalls: 0, - }; - - this.compute = { - calls: 0, - frameCalls: 0, - timestamp: 0, - previousFrameCalls: 0, - timestampCalls: 0, - }; - - this.memory = { - geometries: 0, - textures: 0, - }; - } - - update(object, count, instanceCount) { - this.render.drawCalls++; - - if (object.isMesh || object.isSprite) { - this.render.triangles += instanceCount * (count / 3); - } else if (object.isPoints) { - this.render.points += instanceCount * count; - } else if (object.isLineSegments) { - this.render.lines += instanceCount * (count / 2); - } else if (object.isLine) { - this.render.lines += instanceCount * (count - 1); - } else { - console.error('THREE.WebGPUInfo: Unknown object type.'); - } - } - - updateTimestamp(type, time) { - if (this[type].timestampCalls === 0) { - this[type].timestamp = 0; - } - - this[type].timestamp += time; - - this[type].timestampCalls++; - - if (this[type].timestampCalls >= this[type].previousFrameCalls) { - this[type].timestampCalls = 0; - } - } - - reset() { - const previousRenderFrameCalls = this.render.frameCalls; - this.render.previousFrameCalls = previousRenderFrameCalls; - - const previousComputeFrameCalls = this.compute.frameCalls; - this.compute.previousFrameCalls = previousComputeFrameCalls; - - this.render.drawCalls = 0; - this.render.frameCalls = 0; - this.compute.frameCalls = 0; - - this.render.triangles = 0; - this.render.points = 0; - this.render.lines = 0; - } - - dispose() { - this.reset(); - - this.calls = 0; - - this.render.calls = 0; - this.compute.calls = 0; - - this.render.timestamp = 0; - this.compute.timestamp = 0; - this.memory.geometries = 0; - this.memory.textures = 0; - } -} - -export default Info; diff --git a/examples-jsm/examples/renderers/common/Pipeline.ts b/examples-jsm/examples/renderers/common/Pipeline.ts deleted file mode 100644 index 16017455a..000000000 --- a/examples-jsm/examples/renderers/common/Pipeline.ts +++ /dev/null @@ -1,9 +0,0 @@ -class Pipeline { - constructor(cacheKey) { - this.cacheKey = cacheKey; - - this.usedTimes = 0; - } -} - -export default Pipeline; diff --git a/examples-jsm/examples/renderers/common/Pipelines.ts b/examples-jsm/examples/renderers/common/Pipelines.ts deleted file mode 100644 index 68c8f223c..000000000 --- a/examples-jsm/examples/renderers/common/Pipelines.ts +++ /dev/null @@ -1,270 +0,0 @@ -import DataMap from './DataMap.js'; -import RenderPipeline from './RenderPipeline.js'; -import ComputePipeline from './ComputePipeline.js'; -import ProgrammableStage from './ProgrammableStage.js'; - -class Pipelines extends DataMap { - constructor(backend, nodes) { - super(); - - this.backend = backend; - this.nodes = nodes; - - this.bindings = null; // set by the bindings - - this.caches = new Map(); - this.programs = { - vertex: new Map(), - fragment: new Map(), - compute: new Map(), - }; - } - - getForCompute(computeNode, bindings) { - const { backend } = this; - - const data = this.get(computeNode); - - if (this._needsComputeUpdate(computeNode)) { - const previousPipeline = data.pipeline; - - if (previousPipeline) { - previousPipeline.usedTimes--; - previousPipeline.computeProgram.usedTimes--; - } - - // get shader - - const nodeBuilderState = this.nodes.getForCompute(computeNode); - - // programmable stage - - let stageCompute = this.programs.compute.get(nodeBuilderState.computeShader); - - if (stageCompute === undefined) { - if (previousPipeline && previousPipeline.computeProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.computeProgram); - - stageCompute = new ProgrammableStage( - nodeBuilderState.computeShader, - 'compute', - nodeBuilderState.transforms, - nodeBuilderState.nodeAttributes, - ); - this.programs.compute.set(nodeBuilderState.computeShader, stageCompute); - - backend.createProgram(stageCompute); - } - - // determine compute pipeline - - const cacheKey = this._getComputeCacheKey(computeNode, stageCompute); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); - - pipeline = this._getComputePipeline(computeNode, stageCompute, cacheKey, bindings); - } - - // keep track of all used times - - pipeline.usedTimes++; - stageCompute.usedTimes++; - - // - - data.version = computeNode.version; - data.pipeline = pipeline; - } - - return data.pipeline; - } - - getForRender(renderObject, promises = null) { - const { backend } = this; - - const data = this.get(renderObject); - - if (this._needsRenderUpdate(renderObject)) { - const previousPipeline = data.pipeline; - - if (previousPipeline) { - previousPipeline.usedTimes--; - previousPipeline.vertexProgram.usedTimes--; - previousPipeline.fragmentProgram.usedTimes--; - } - - // get shader - - const nodeBuilderState = renderObject.getNodeBuilderState(); - - // programmable stages - - let stageVertex = this.programs.vertex.get(nodeBuilderState.vertexShader); - - if (stageVertex === undefined) { - if (previousPipeline && previousPipeline.vertexProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.vertexProgram); - - stageVertex = new ProgrammableStage(nodeBuilderState.vertexShader, 'vertex'); - this.programs.vertex.set(nodeBuilderState.vertexShader, stageVertex); - - backend.createProgram(stageVertex); - } - - let stageFragment = this.programs.fragment.get(nodeBuilderState.fragmentShader); - - if (stageFragment === undefined) { - if (previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0) - this._releaseProgram(previousPipeline.fragmentProgram); - - stageFragment = new ProgrammableStage(nodeBuilderState.fragmentShader, 'fragment'); - this.programs.fragment.set(nodeBuilderState.fragmentShader, stageFragment); - - backend.createProgram(stageFragment); - } - - // determine render pipeline - - const cacheKey = this._getRenderCacheKey(renderObject, stageVertex, stageFragment); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - if (previousPipeline && previousPipeline.usedTimes === 0) this._releasePipeline(previousPipeline); - - pipeline = this._getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises); - } else { - renderObject.pipeline = pipeline; - } - - // keep track of all used times - - pipeline.usedTimes++; - stageVertex.usedTimes++; - stageFragment.usedTimes++; - - // - - data.pipeline = pipeline; - } - - return data.pipeline; - } - - delete(object) { - const pipeline = this.get(object).pipeline; - - if (pipeline) { - // pipeline - - pipeline.usedTimes--; - - if (pipeline.usedTimes === 0) this._releasePipeline(pipeline); - - // programs - - if (pipeline.isComputePipeline) { - pipeline.computeProgram.usedTimes--; - - if (pipeline.computeProgram.usedTimes === 0) this._releaseProgram(pipeline.computeProgram); - } else { - pipeline.fragmentProgram.usedTimes--; - pipeline.vertexProgram.usedTimes--; - - if (pipeline.vertexProgram.usedTimes === 0) this._releaseProgram(pipeline.vertexProgram); - if (pipeline.fragmentProgram.usedTimes === 0) this._releaseProgram(pipeline.fragmentProgram); - } - } - - return super.delete(object); - } - - dispose() { - super.dispose(); - - this.caches = new Map(); - this.programs = { - vertex: new Map(), - fragment: new Map(), - compute: new Map(), - }; - } - - updateForRender(renderObject) { - this.getForRender(renderObject); - } - - _getComputePipeline(computeNode, stageCompute, cacheKey, bindings) { - // check for existing pipeline - - cacheKey = cacheKey || this._getComputeCacheKey(computeNode, stageCompute); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - pipeline = new ComputePipeline(cacheKey, stageCompute); - - this.caches.set(cacheKey, pipeline); - - this.backend.createComputePipeline(pipeline, bindings); - } - - return pipeline; - } - - _getRenderPipeline(renderObject, stageVertex, stageFragment, cacheKey, promises) { - // check for existing pipeline - - cacheKey = cacheKey || this._getRenderCacheKey(renderObject, stageVertex, stageFragment); - - let pipeline = this.caches.get(cacheKey); - - if (pipeline === undefined) { - pipeline = new RenderPipeline(cacheKey, stageVertex, stageFragment); - - this.caches.set(cacheKey, pipeline); - - renderObject.pipeline = pipeline; - - this.backend.createRenderPipeline(renderObject, promises); - } - - return pipeline; - } - - _getComputeCacheKey(computeNode, stageCompute) { - return computeNode.id + ',' + stageCompute.id; - } - - _getRenderCacheKey(renderObject, stageVertex, stageFragment) { - return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey(renderObject); - } - - _releasePipeline(pipeline) { - this.caches.delete(pipeline.cacheKey); - } - - _releaseProgram(program) { - const code = program.code; - const stage = program.stage; - - this.programs[stage].delete(code); - } - - _needsComputeUpdate(computeNode) { - const data = this.get(computeNode); - - return data.pipeline === undefined || data.version !== computeNode.version; - } - - _needsRenderUpdate(renderObject) { - const data = this.get(renderObject); - - return data.pipeline === undefined || this.backend.needsRenderUpdate(renderObject); - } -} - -export default Pipelines; diff --git a/examples-jsm/examples/renderers/common/ProgrammableStage.ts b/examples-jsm/examples/renderers/common/ProgrammableStage.ts deleted file mode 100644 index a684e4443..000000000 --- a/examples-jsm/examples/renderers/common/ProgrammableStage.ts +++ /dev/null @@ -1,16 +0,0 @@ -let _id = 0; - -class ProgrammableStage { - constructor(code, type, transforms = null, attributes = null) { - this.id = _id++; - - this.code = code; - this.stage = type; - this.transforms = transforms; - this.attributes = attributes; - - this.usedTimes = 0; - } -} - -export default ProgrammableStage; diff --git a/examples-jsm/examples/renderers/common/RenderBundle.ts b/examples-jsm/examples/renderers/common/RenderBundle.ts deleted file mode 100644 index e59e49378..000000000 --- a/examples-jsm/examples/renderers/common/RenderBundle.ts +++ /dev/null @@ -1,12 +0,0 @@ -class RenderBundle { - constructor(scene, camera) { - this.scene = scene; - this.camera = camera; - } - - clone() { - return Object.assign(new this.constructor(), this); - } -} - -export default RenderBundle; diff --git a/examples-jsm/examples/renderers/common/RenderBundles.ts b/examples-jsm/examples/renderers/common/RenderBundles.ts deleted file mode 100644 index 291403652..000000000 --- a/examples-jsm/examples/renderers/common/RenderBundles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderBundle from './RenderBundle.js'; - -class RenderBundles { - constructor() { - this.lists = new ChainMap(); - } - - get(scene, camera) { - const lists = this.lists; - const keys = [scene, camera]; - - let list = lists.get(keys); - - if (list === undefined) { - list = new RenderBundle(scene, camera); - lists.set(keys, list); - } - - return list; - } - - dispose() { - this.lists = new ChainMap(); - } -} - -export default RenderBundles; diff --git a/examples-jsm/examples/renderers/common/RenderContext.ts b/examples-jsm/examples/renderers/common/RenderContext.ts deleted file mode 100644 index 3b43028eb..000000000 --- a/examples-jsm/examples/renderers/common/RenderContext.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Vector4 } from 'three'; - -let id = 0; - -class RenderContext { - constructor() { - this.id = id++; - - this.color = true; - this.clearColor = true; - this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 }; - - this.depth = true; - this.clearDepth = true; - this.clearDepthValue = 1; - - this.stencil = false; - this.clearStencil = true; - this.clearStencilValue = 1; - - this.viewport = false; - this.viewportValue = new Vector4(); - - this.scissor = false; - this.scissorValue = new Vector4(); - - this.textures = null; - this.depthTexture = null; - this.activeCubeFace = 0; - this.sampleCount = 1; - - this.width = 0; - this.height = 0; - - this.isRenderContext = true; - } -} - -export default RenderContext; diff --git a/examples-jsm/examples/renderers/common/RenderContexts.ts b/examples-jsm/examples/renderers/common/RenderContexts.ts deleted file mode 100644 index 630a2e42d..000000000 --- a/examples-jsm/examples/renderers/common/RenderContexts.ts +++ /dev/null @@ -1,47 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderContext from './RenderContext.js'; - -class RenderContexts { - constructor() { - this.chainMaps = {}; - } - - get(scene, camera, renderTarget = null) { - const chainKey = [scene, camera]; - - let attachmentState; - - if (renderTarget === null) { - attachmentState = 'default'; - } else { - const format = renderTarget.texture.format; - const count = renderTarget.count; - - attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`; - } - - const chainMap = this.getChainMap(attachmentState); - - let renderState = chainMap.get(chainKey); - - if (renderState === undefined) { - renderState = new RenderContext(); - - chainMap.set(chainKey, renderState); - } - - if (renderTarget !== null) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; - - return renderState; - } - - getChainMap(attachmentState) { - return this.chainMaps[attachmentState] || (this.chainMaps[attachmentState] = new ChainMap()); - } - - dispose() { - this.chainMaps = {}; - } -} - -export default RenderContexts; diff --git a/examples-jsm/examples/renderers/common/RenderList.ts b/examples-jsm/examples/renderers/common/RenderList.ts deleted file mode 100644 index a72a91dfd..000000000 --- a/examples-jsm/examples/renderers/common/RenderList.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { LightsNode } from '../../nodes/Nodes.js'; - -function painterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.material.id !== b.material.id) { - return a.material.id - b.material.id; - } else if (a.z !== b.z) { - return a.z - b.z; - } else { - return a.id - b.id; - } -} - -function reversePainterSortStable(a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.z !== b.z) { - return b.z - a.z; - } else { - return a.id - b.id; - } -} - -class RenderList { - constructor() { - this.renderItems = []; - this.renderItemsIndex = 0; - - this.opaque = []; - this.transparent = []; - this.bundles = []; - - this.lightsNode = new LightsNode([]); - this.lightsArray = []; - - this.occlusionQueryCount = 0; - } - - begin() { - this.renderItemsIndex = 0; - - this.opaque.length = 0; - this.transparent.length = 0; - this.bundles.length = 0; - - this.lightsArray.length = 0; - - this.occlusionQueryCount = 0; - - return this; - } - - getNextRenderItem(object, geometry, material, groupOrder, z, group) { - let renderItem = this.renderItems[this.renderItemsIndex]; - - if (renderItem === undefined) { - renderItem = { - id: object.id, - object: object, - geometry: geometry, - material: material, - groupOrder: groupOrder, - renderOrder: object.renderOrder, - z: z, - group: group, - }; - - this.renderItems[this.renderItemsIndex] = renderItem; - } else { - renderItem.id = object.id; - renderItem.object = object; - renderItem.geometry = geometry; - renderItem.material = material; - renderItem.groupOrder = groupOrder; - renderItem.renderOrder = object.renderOrder; - renderItem.z = z; - renderItem.group = group; - } - - this.renderItemsIndex++; - - return renderItem; - } - - push(object, geometry, material, groupOrder, z, group) { - const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); - - if (object.occlusionTest === true) this.occlusionQueryCount++; - - (material.transparent === true || material.transmission > 0 ? this.transparent : this.opaque).push(renderItem); - } - - unshift(object, geometry, material, groupOrder, z, group) { - const renderItem = this.getNextRenderItem(object, geometry, material, groupOrder, z, group); - - (material.transparent === true ? this.transparent : this.opaque).unshift(renderItem); - } - - pushBundle(group) { - this.bundles.push(group); - } - - pushLight(light) { - this.lightsArray.push(light); - } - - getLightsNode() { - return this.lightsNode.fromLights(this.lightsArray); - } - - sort(customOpaqueSort, customTransparentSort) { - if (this.opaque.length > 1) this.opaque.sort(customOpaqueSort || painterSortStable); - if (this.transparent.length > 1) this.transparent.sort(customTransparentSort || reversePainterSortStable); - } - - finish() { - // update lights - - this.lightsNode.fromLights(this.lightsArray); - - // Clear references from inactive renderItems in the list - - for (let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i++) { - const renderItem = this.renderItems[i]; - - if (renderItem.id === null) break; - - renderItem.id = null; - renderItem.object = null; - renderItem.geometry = null; - renderItem.material = null; - renderItem.groupOrder = null; - renderItem.renderOrder = null; - renderItem.z = null; - renderItem.group = null; - } - } -} - -export default RenderList; diff --git a/examples-jsm/examples/renderers/common/RenderLists.ts b/examples-jsm/examples/renderers/common/RenderLists.ts deleted file mode 100644 index 3fc3134e6..000000000 --- a/examples-jsm/examples/renderers/common/RenderLists.ts +++ /dev/null @@ -1,28 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderList from './RenderList.js'; - -class RenderLists { - constructor() { - this.lists = new ChainMap(); - } - - get(scene, camera) { - const lists = this.lists; - const keys = [scene, camera]; - - let list = lists.get(keys); - - if (list === undefined) { - list = new RenderList(); - lists.set(keys, list); - } - - return list; - } - - dispose() { - this.lists = new ChainMap(); - } -} - -export default RenderLists; diff --git a/examples-jsm/examples/renderers/common/RenderObject.ts b/examples-jsm/examples/renderers/common/RenderObject.ts deleted file mode 100644 index 91ba0f2a4..000000000 --- a/examples-jsm/examples/renderers/common/RenderObject.ts +++ /dev/null @@ -1,215 +0,0 @@ -import ClippingContext from './ClippingContext.js'; - -let id = 0; - -function getKeys(obj) { - const keys = Object.keys(obj); - - let proto = Object.getPrototypeOf(obj); - - while (proto) { - const descriptors = Object.getOwnPropertyDescriptors(proto); - - for (const key in descriptors) { - if (descriptors[key] !== undefined) { - const descriptor = descriptors[key]; - - if (descriptor && typeof descriptor.get === 'function') { - keys.push(key); - } - } - } - - proto = Object.getPrototypeOf(proto); - } - - return keys; -} - -export default class RenderObject { - constructor(nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext) { - this._nodes = nodes; - this._geometries = geometries; - - this.id = id++; - - this.renderer = renderer; - this.object = object; - this.material = material; - this.scene = scene; - this.camera = camera; - this.lightsNode = lightsNode; - this.context = renderContext; - - this.geometry = object.geometry; - this.version = material.version; - - this.drawRange = null; - - this.attributes = null; - this.pipeline = null; - this.vertexBuffers = null; - - this.updateClipping(renderContext.clippingContext); - - this.clippingContextVersion = this.clippingContext.version; - - this.initialNodesCacheKey = this.getNodesCacheKey(); - this.initialCacheKey = this.getCacheKey(); - - this._nodeBuilderState = null; - this._bindings = null; - - this.onDispose = null; - - this.isRenderObject = true; - - this.onMaterialDispose = () => { - this.dispose(); - }; - - this.material.addEventListener('dispose', this.onMaterialDispose); - } - - updateClipping(parent) { - const material = this.material; - - let clippingContext = this.clippingContext; - - if (Array.isArray(material.clippingPlanes)) { - if (clippingContext === parent || !clippingContext) { - clippingContext = new ClippingContext(); - this.clippingContext = clippingContext; - } - - clippingContext.update(parent, material); - } else if (this.clippingContext !== parent) { - this.clippingContext = parent; - } - } - - get clippingNeedsUpdate() { - if (this.clippingContext.version === this.clippingContextVersion) return false; - - this.clippingContextVersion = this.clippingContext.version; - - return true; - } - - getNodeBuilderState() { - return this._nodeBuilderState || (this._nodeBuilderState = this._nodes.getForRender(this)); - } - - getBindings() { - return this._bindings || (this._bindings = this.getNodeBuilderState().createBindings()); - } - - getIndex() { - return this._geometries.getIndex(this); - } - - getChainArray() { - return [this.object, this.material, this.context, this.lightsNode]; - } - - getAttributes() { - if (this.attributes !== null) return this.attributes; - - const nodeAttributes = this.getNodeBuilderState().nodeAttributes; - const geometry = this.geometry; - - const attributes = []; - const vertexBuffers = new Set(); - - for (const nodeAttribute of nodeAttributes) { - const attribute = - nodeAttribute.node && nodeAttribute.node.attribute - ? nodeAttribute.node.attribute - : geometry.getAttribute(nodeAttribute.name); - - if (attribute === undefined) continue; - - attributes.push(attribute); - - const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute; - vertexBuffers.add(bufferAttribute); - } - - this.attributes = attributes; - this.vertexBuffers = Array.from(vertexBuffers.values()); - - return attributes; - } - - getVertexBuffers() { - if (this.vertexBuffers === null) this.getAttributes(); - - return this.vertexBuffers; - } - - getMaterialCacheKey() { - const { object, material } = this; - - let cacheKey = material.customProgramCacheKey(); - - for (const property of getKeys(material)) { - if (/^(is[A-Z]|_)|^(visible|version|uuid|name|opacity|userData)$/.test(property)) continue; - - let value = material[property]; - - if (value !== null) { - const type = typeof value; - - if (type === 'number') - value = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc - else if (type === 'object') value = '{}'; - } - - cacheKey += /*property + ':' +*/ value + ','; - } - - cacheKey += this.clippingContextVersion + ','; - - if (object.skeleton) { - cacheKey += object.skeleton.bones.length + ','; - } - - if (object.morphTargetInfluences) { - cacheKey += object.morphTargetInfluences.length + ','; - } - - if (object.isBatchedMesh) { - cacheKey += object._matricesTexture.uuid + ','; - - if (object._colorsTexture !== null) { - cacheKey += object._colorsTexture.uuid + ','; - } - } - - if (object.count > 1) { - cacheKey += object.count + ','; - } - - return cacheKey; - } - - get needsUpdate() { - return this.initialNodesCacheKey !== this.getNodesCacheKey() || this.clippingNeedsUpdate; - } - - getNodesCacheKey() { - // Environment Nodes Cache Key - - return this._nodes.getCacheKey(this.scene, this.lightsNode); - } - - getCacheKey() { - return this.getMaterialCacheKey() + ',' + this.getNodesCacheKey(); - } - - dispose() { - this.material.removeEventListener('dispose', this.onMaterialDispose); - - this.onDispose(); - } -} diff --git a/examples-jsm/examples/renderers/common/RenderObjects.ts b/examples-jsm/examples/renderers/common/RenderObjects.ts deleted file mode 100644 index 76dc482e4..000000000 --- a/examples-jsm/examples/renderers/common/RenderObjects.ts +++ /dev/null @@ -1,100 +0,0 @@ -import ChainMap from './ChainMap.js'; -import RenderObject from './RenderObject.js'; - -class RenderObjects { - constructor(renderer, nodes, geometries, pipelines, bindings, info) { - this.renderer = renderer; - this.nodes = nodes; - this.geometries = geometries; - this.pipelines = pipelines; - this.bindings = bindings; - this.info = info; - - this.chainMaps = {}; - } - - get(object, material, scene, camera, lightsNode, renderContext, passId) { - const chainMap = this.getChainMap(passId); - const chainArray = [object, material, renderContext, lightsNode]; - - let renderObject = chainMap.get(chainArray); - - if (renderObject === undefined) { - renderObject = this.createRenderObject( - this.nodes, - this.geometries, - this.renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - passId, - ); - - chainMap.set(chainArray, renderObject); - } else { - renderObject.updateClipping(renderContext.clippingContext); - - if (renderObject.version !== material.version || renderObject.needsUpdate) { - if (renderObject.initialCacheKey !== renderObject.getCacheKey()) { - renderObject.dispose(); - - renderObject = this.get(object, material, scene, camera, lightsNode, renderContext, passId); - } else { - renderObject.version = material.version; - } - } - } - - return renderObject; - } - - getChainMap(passId = 'default') { - return this.chainMaps[passId] || (this.chainMaps[passId] = new ChainMap()); - } - - dispose() { - this.chainMaps = {}; - } - - createRenderObject( - nodes, - geometries, - renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - passId, - ) { - const chainMap = this.getChainMap(passId); - - const renderObject = new RenderObject( - nodes, - geometries, - renderer, - object, - material, - scene, - camera, - lightsNode, - renderContext, - ); - - renderObject.onDispose = () => { - this.pipelines.delete(renderObject); - this.bindings.delete(renderObject); - this.nodes.delete(renderObject); - - chainMap.delete(renderObject.getChainArray()); - }; - - return renderObject; - } -} - -export default RenderObjects; diff --git a/examples-jsm/examples/renderers/common/RenderPipeline.ts b/examples-jsm/examples/renderers/common/RenderPipeline.ts deleted file mode 100644 index 0ec34b043..000000000 --- a/examples-jsm/examples/renderers/common/RenderPipeline.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Pipeline from './Pipeline.js'; - -class RenderPipeline extends Pipeline { - constructor(cacheKey, vertexProgram, fragmentProgram) { - super(cacheKey); - - this.vertexProgram = vertexProgram; - this.fragmentProgram = fragmentProgram; - } -} - -export default RenderPipeline; diff --git a/examples-jsm/examples/renderers/common/Renderer.ts b/examples-jsm/examples/renderers/common/Renderer.ts deleted file mode 100644 index b45a68734..000000000 --- a/examples-jsm/examples/renderers/common/Renderer.ts +++ /dev/null @@ -1,1347 +0,0 @@ -import Animation from './Animation.js'; -import RenderObjects from './RenderObjects.js'; -import Attributes from './Attributes.js'; -import Geometries from './Geometries.js'; -import Info from './Info.js'; -import Pipelines from './Pipelines.js'; -import Bindings from './Bindings.js'; -import RenderLists from './RenderLists.js'; -import RenderContexts from './RenderContexts.js'; -import Textures from './Textures.js'; -import Background from './Background.js'; -import Nodes from './nodes/Nodes.js'; -import Color4 from './Color4.js'; -import ClippingContext from './ClippingContext.js'; -import { - Scene, - Frustum, - Matrix4, - Vector2, - Vector3, - Vector4, - DoubleSide, - BackSide, - FrontSide, - SRGBColorSpace, - NoColorSpace, - NoToneMapping, - LinearFilter, - LinearSRGBColorSpace, - RenderTarget, - HalfFloatType, - RGBAFormat, -} from 'three'; -import { NodeMaterial } from '../../nodes/Nodes.js'; -import QuadMesh from '../../objects/QuadMesh.js'; -import RenderBundles from './RenderBundles.js'; - -const _scene = new Scene(); -const _drawingBufferSize = new Vector2(); -const _screen = new Vector4(); -const _frustum = new Frustum(); -const _projScreenMatrix = new Matrix4(); -const _vector3 = new Vector3(); -const _quad = new QuadMesh(new NodeMaterial()); - -class Renderer { - constructor(backend, parameters = {}) { - this.isRenderer = true; - - // - - const { logarithmicDepthBuffer = false, alpha = true } = parameters; - - // public - - this.domElement = backend.getDomElement(); - - this.backend = backend; - - this.autoClear = true; - this.autoClearColor = true; - this.autoClearDepth = true; - this.autoClearStencil = true; - - this.alpha = alpha; - - this.logarithmicDepthBuffer = logarithmicDepthBuffer; - - this.outputColorSpace = SRGBColorSpace; - - this.toneMapping = NoToneMapping; - this.toneMappingExposure = 1.0; - - this.sortObjects = true; - - this.depth = true; - this.stencil = false; - - this.clippingPlanes = []; - - this.info = new Info(); - - // nodes - - this.toneMappingNode = null; - - // internals - - this._pixelRatio = 1; - this._width = this.domElement.width; - this._height = this.domElement.height; - - this._viewport = new Vector4(0, 0, this._width, this._height); - this._scissor = new Vector4(0, 0, this._width, this._height); - this._scissorTest = false; - - this._attributes = null; - this._geometries = null; - this._nodes = null; - this._animation = null; - this._bindings = null; - this._objects = null; - this._pipelines = null; - this._bundles = null; - this._renderLists = null; - this._renderContexts = null; - this._textures = null; - this._background = null; - - this._currentRenderContext = null; - - this._opaqueSort = null; - this._transparentSort = null; - - this._frameBufferTarget = null; - - const alphaClear = this.alpha === true ? 0 : 1; - - this._clearColor = new Color4(0, 0, 0, alphaClear); - this._clearDepth = 1; - this._clearStencil = 0; - - this._renderTarget = null; - this._activeCubeFace = 0; - this._activeMipmapLevel = 0; - - this._renderObjectFunction = null; - this._currentRenderObjectFunction = null; - this._currentRenderBundle = null; - - this._handleObjectFunction = this._renderObjectDirect; - - this._initialized = false; - this._initPromise = null; - - this._compilationPromises = null; - - // backwards compatibility - - this.shadowMap = { - enabled: false, - type: null, - }; - - this.xr = { - enabled: false, - }; - - this.debug = { - checkShaderErrors: true, - onShaderError: null, - }; - } - - async init() { - if (this._initialized) { - throw new Error('Renderer: Backend has already been initialized.'); - } - - if (this._initPromise !== null) { - return this._initPromise; - } - - this._initPromise = new Promise(async (resolve, reject) => { - const backend = this.backend; - - try { - await backend.init(this); - } catch (error) { - reject(error); - return; - } - - this._nodes = new Nodes(this, backend); - this._animation = new Animation(this._nodes, this.info); - this._attributes = new Attributes(backend); - this._background = new Background(this, this._nodes); - this._geometries = new Geometries(this._attributes, this.info); - this._textures = new Textures(this, backend, this.info); - this._pipelines = new Pipelines(backend, this._nodes); - this._bindings = new Bindings( - backend, - this._nodes, - this._textures, - this._attributes, - this._pipelines, - this.info, - ); - this._objects = new RenderObjects( - this, - this._nodes, - this._geometries, - this._pipelines, - this._bindings, - this.info, - ); - this._renderLists = new RenderLists(); - this._bundles = new RenderBundles(); - this._renderContexts = new RenderContexts(); - - // - - this._initialized = true; - - resolve(); - }); - - return this._initPromise; - } - - get coordinateSystem() { - return this.backend.coordinateSystem; - } - - async compileAsync(scene, camera, targetScene = null) { - if (this._initialized === false) await this.init(); - - // preserve render tree - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - const previousRenderContext = this._currentRenderContext; - const previousRenderObjectFunction = this._currentRenderObjectFunction; - const previousCompilationPromises = this._compilationPromises; - - // - - const sceneRef = scene.isScene === true ? scene : _scene; - - if (targetScene === null) targetScene = scene; - - const renderTarget = this._renderTarget; - const renderContext = this._renderContexts.get(targetScene, camera, renderTarget); - const activeMipmapLevel = this._activeMipmapLevel; - - const compilationPromises = []; - - this._currentRenderContext = renderContext; - this._currentRenderObjectFunction = this.renderObject; - - this._handleObjectFunction = this._createObjectPipeline; - - this._compilationPromises = compilationPromises; - - nodeFrame.renderId++; - - // - - nodeFrame.update(); - - // - - renderContext.depth = this.depth; - renderContext.stencil = this.stencil; - - if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); - renderContext.clippingContext.updateGlobal(this, camera); - - // - - sceneRef.onBeforeRender(this, scene, camera, renderTarget); - - // - - const renderList = this._renderLists.get(scene, camera); - renderList.begin(); - - this._projectObject(scene, camera, 0, renderList); - - // include lights from target scene - if (targetScene !== scene) { - targetScene.traverseVisible(function (object) { - if (object.isLight && object.layers.test(camera.layers)) { - renderList.pushLight(object); - } - }); - } - - renderList.finish(); - - // - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); - - const renderTargetData = this._textures.get(renderTarget); - - renderContext.textures = renderTargetData.textures; - renderContext.depthTexture = renderTargetData.depthTexture; - } else { - renderContext.textures = null; - renderContext.depthTexture = null; - } - - // - - this._nodes.updateScene(sceneRef); - - // - - this._background.update(sceneRef, renderList, renderContext); - - // process render lists - - const opaqueObjects = renderList.opaque; - const transparentObjects = renderList.transparent; - const lightsNode = renderList.lightsNode; - - if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - if (transparentObjects.length > 0) this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); - - // restore render tree - - nodeFrame.renderId = previousRenderId; - - this._currentRenderContext = previousRenderContext; - this._currentRenderObjectFunction = previousRenderObjectFunction; - this._compilationPromises = previousCompilationPromises; - - this._handleObjectFunction = this._renderObjectDirect; - - // wait for all promises setup by backends awaiting compilation/linking/pipeline creation to complete - - await Promise.all(compilationPromises); - } - - async renderAsync(scene, camera) { - if (this._initialized === false) await this.init(); - - const renderContext = this._renderScene(scene, camera); - - await this.backend.resolveTimestampAsync(renderContext, 'render'); - } - - _renderBundle(bundle, sceneRef, lightsNode) { - const { object, camera, renderList } = bundle; - - const renderContext = this._currentRenderContext; - const renderContextData = this.backend.get(renderContext); - - // - - const renderBundle = this._bundles.get(object, camera); - - const renderBundleData = this.backend.get(renderBundle); - if (renderBundleData.renderContexts === undefined) renderBundleData.renderContexts = new Set(); - - // - - const renderBundleNeedsUpdate = - renderBundleData.renderContexts.has(renderContext) === false || object.needsUpdate === true; - - renderBundleData.renderContexts.add(renderContext); - - if (renderBundleNeedsUpdate) { - if (renderContextData.renderObjects === undefined || object.needsUpdate === true) { - const nodeFrame = this._nodes.nodeFrame; - - renderContextData.renderObjects = []; - renderContextData.renderBundles = []; - renderContextData.scene = sceneRef; - renderContextData.camera = camera; - renderContextData.renderId = nodeFrame.renderId; - - renderContextData.registerBundlesPhase = true; - } - - this._currentRenderBundle = renderBundle; - - const opaqueObjects = renderList.opaque; - - if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - - this._currentRenderBundle = null; - - // - - object.needsUpdate = false; - } else { - const renderContext = this._currentRenderContext; - const renderContextData = this.backend.get(renderContext); - - for (let i = 0, l = renderContextData.renderObjects.length; i < l; i++) { - const renderObject = renderContextData.renderObjects[i]; - - this._nodes.updateBefore(renderObject); - - // - - renderObject.object.modelViewMatrix.multiplyMatrices( - camera.matrixWorldInverse, - renderObject.object.matrixWorld, - ); - renderObject.object.normalMatrix.getNormalMatrix(renderObject.object.modelViewMatrix); - - this._nodes.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - - this.backend.draw(renderObject, this.info); - - this._nodes.updateAfter(renderObject); - } - } - } - - render(scene, camera) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.', - ); - - return this.renderAsync(scene, camera); - } - - this._renderScene(scene, camera); - } - - _getFrameBufferTarget() { - const { currentColorSpace } = this; - - const useToneMapping = - this._renderTarget === null && (this.toneMapping !== NoToneMapping || this.toneMappingNode !== null); - const useColorSpace = currentColorSpace !== LinearSRGBColorSpace && currentColorSpace !== NoColorSpace; - - if (useToneMapping === false && useColorSpace === false) return null; - - const { width, height } = this.getDrawingBufferSize(_drawingBufferSize); - const { depth, stencil } = this; - - let frameBufferTarget = this._frameBufferTarget; - - if (frameBufferTarget === null) { - frameBufferTarget = new RenderTarget(width, height, { - depthBuffer: depth, - stencilBuffer: stencil, - type: HalfFloatType, // FloatType - format: RGBAFormat, - colorSpace: LinearSRGBColorSpace, - generateMipmaps: false, - minFilter: LinearFilter, - magFilter: LinearFilter, - samples: this.backend.parameters.antialias ? 4 : 0, - }); - - frameBufferTarget.isPostProcessingRenderTarget = true; - - this._frameBufferTarget = frameBufferTarget; - } - - frameBufferTarget.depthBuffer = depth; - frameBufferTarget.stencilBuffer = stencil; - frameBufferTarget.setSize(width, height); - frameBufferTarget.viewport.copy(this._viewport); - frameBufferTarget.scissor.copy(this._scissor); - frameBufferTarget.viewport.multiplyScalar(this._pixelRatio); - frameBufferTarget.scissor.multiplyScalar(this._pixelRatio); - frameBufferTarget.scissorTest = this._scissorTest; - - return frameBufferTarget; - } - - _renderScene(scene, camera, useFrameBufferTarget = true) { - const frameBufferTarget = useFrameBufferTarget ? this._getFrameBufferTarget() : null; - - // preserve render tree - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - const previousRenderContext = this._currentRenderContext; - const previousRenderObjectFunction = this._currentRenderObjectFunction; - - // - - const sceneRef = scene.isScene === true ? scene : _scene; - - const outputRenderTarget = this._renderTarget; - - const activeCubeFace = this._activeCubeFace; - const activeMipmapLevel = this._activeMipmapLevel; - - // - - let renderTarget; - - if (frameBufferTarget !== null) { - renderTarget = frameBufferTarget; - - this.setRenderTarget(renderTarget); - } else { - renderTarget = outputRenderTarget; - } - - // - - const renderContext = this._renderContexts.get(scene, camera, renderTarget); - - this._currentRenderContext = renderContext; - this._currentRenderObjectFunction = this._renderObjectFunction || this.renderObject; - - // - - this.info.calls++; - this.info.render.calls++; - this.info.render.frameCalls++; - - nodeFrame.renderId = this.info.calls; - - // - - const coordinateSystem = this.coordinateSystem; - - if (camera.coordinateSystem !== coordinateSystem) { - camera.coordinateSystem = coordinateSystem; - - camera.updateProjectionMatrix(); - } - - // - - if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); - - if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); - - // - - let viewport = this._viewport; - let scissor = this._scissor; - let pixelRatio = this._pixelRatio; - - if (renderTarget !== null) { - viewport = renderTarget.viewport; - scissor = renderTarget.scissor; - pixelRatio = 1; - } - - this.getDrawingBufferSize(_drawingBufferSize); - - _screen.set(0, 0, _drawingBufferSize.width, _drawingBufferSize.height); - - const minDepth = viewport.minDepth === undefined ? 0 : viewport.minDepth; - const maxDepth = viewport.maxDepth === undefined ? 1 : viewport.maxDepth; - - renderContext.viewportValue.copy(viewport).multiplyScalar(pixelRatio).floor(); - renderContext.viewportValue.width >>= activeMipmapLevel; - renderContext.viewportValue.height >>= activeMipmapLevel; - renderContext.viewportValue.minDepth = minDepth; - renderContext.viewportValue.maxDepth = maxDepth; - renderContext.viewport = renderContext.viewportValue.equals(_screen) === false; - - renderContext.scissorValue.copy(scissor).multiplyScalar(pixelRatio).floor(); - renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals(_screen) === false; - renderContext.scissorValue.width >>= activeMipmapLevel; - renderContext.scissorValue.height >>= activeMipmapLevel; - - if (!renderContext.clippingContext) renderContext.clippingContext = new ClippingContext(); - renderContext.clippingContext.updateGlobal(this, camera); - - // - - sceneRef.onBeforeRender(this, scene, camera, renderTarget); - - // - - _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse); - _frustum.setFromProjectionMatrix(_projScreenMatrix, coordinateSystem); - - const renderList = this._renderLists.get(scene, camera); - renderList.begin(); - - this._projectObject(scene, camera, 0, renderList); - - renderList.finish(); - - if (this.sortObjects === true) { - renderList.sort(this._opaqueSort, this._transparentSort); - } - - // - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget, activeMipmapLevel); - - const renderTargetData = this._textures.get(renderTarget); - - renderContext.textures = renderTargetData.textures; - renderContext.depthTexture = renderTargetData.depthTexture; - renderContext.width = renderTargetData.width; - renderContext.height = renderTargetData.height; - renderContext.renderTarget = renderTarget; - renderContext.depth = renderTarget.depthBuffer; - renderContext.stencil = renderTarget.stencilBuffer; - } else { - renderContext.textures = null; - renderContext.depthTexture = null; - renderContext.width = this.domElement.width; - renderContext.height = this.domElement.height; - renderContext.depth = this.depth; - renderContext.stencil = this.stencil; - } - - renderContext.width >>= activeMipmapLevel; - renderContext.height >>= activeMipmapLevel; - renderContext.activeCubeFace = activeCubeFace; - renderContext.activeMipmapLevel = activeMipmapLevel; - renderContext.occlusionQueryCount = renderList.occlusionQueryCount; - - // - - this._nodes.updateScene(sceneRef); - - // - - this._background.update(sceneRef, renderList, renderContext); - - // - - this.backend.beginRender(renderContext); - - // process render lists - - const opaqueObjects = renderList.opaque; - const transparentObjects = renderList.transparent; - const bundles = renderList.bundles; - const lightsNode = renderList.lightsNode; - - if (bundles.length > 0) this._renderBundles(bundles, sceneRef, lightsNode); - if (opaqueObjects.length > 0) this._renderObjects(opaqueObjects, camera, sceneRef, lightsNode); - if (transparentObjects.length > 0) this._renderObjects(transparentObjects, camera, sceneRef, lightsNode); - - // finish render pass - - this.backend.finishRender(renderContext); - - // restore render tree - - nodeFrame.renderId = previousRenderId; - - this._currentRenderContext = previousRenderContext; - this._currentRenderObjectFunction = previousRenderObjectFunction; - - // - - if (frameBufferTarget !== null) { - this.setRenderTarget(outputRenderTarget, activeCubeFace, activeMipmapLevel); - - _quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); - - this._renderScene(_quad, _quad.camera, false); - } - - // - - sceneRef.onAfterRender(this, scene, camera, renderTarget); - - // - - return renderContext; - } - - getMaxAnisotropy() { - return this.backend.getMaxAnisotropy(); - } - - getActiveCubeFace() { - return this._activeCubeFace; - } - - getActiveMipmapLevel() { - return this._activeMipmapLevel; - } - - async setAnimationLoop(callback) { - if (this._initialized === false) await this.init(); - - this._animation.setAnimationLoop(callback); - } - - async getArrayBufferAsync(attribute) { - return await this.backend.getArrayBufferAsync(attribute); - } - - getContext() { - return this.backend.getContext(); - } - - getPixelRatio() { - return this._pixelRatio; - } - - getDrawingBufferSize(target) { - return target.set(this._width * this._pixelRatio, this._height * this._pixelRatio).floor(); - } - - getSize(target) { - return target.set(this._width, this._height); - } - - setPixelRatio(value = 1) { - this._pixelRatio = value; - - this.setSize(this._width, this._height, false); - } - - setDrawingBufferSize(width, height, pixelRatio) { - this._width = width; - this._height = height; - - this._pixelRatio = pixelRatio; - - this.domElement.width = Math.floor(width * pixelRatio); - this.domElement.height = Math.floor(height * pixelRatio); - - this.setViewport(0, 0, width, height); - - if (this._initialized) this.backend.updateSize(); - } - - setSize(width, height, updateStyle = true) { - this._width = width; - this._height = height; - - this.domElement.width = Math.floor(width * this._pixelRatio); - this.domElement.height = Math.floor(height * this._pixelRatio); - - if (updateStyle === true) { - this.domElement.style.width = width + 'px'; - this.domElement.style.height = height + 'px'; - } - - this.setViewport(0, 0, width, height); - - if (this._initialized) this.backend.updateSize(); - } - - setOpaqueSort(method) { - this._opaqueSort = method; - } - - setTransparentSort(method) { - this._transparentSort = method; - } - - getScissor(target) { - const scissor = this._scissor; - - target.x = scissor.x; - target.y = scissor.y; - target.width = scissor.width; - target.height = scissor.height; - - return target; - } - - setScissor(x, y, width, height) { - const scissor = this._scissor; - - if (x.isVector4) { - scissor.copy(x); - } else { - scissor.set(x, y, width, height); - } - } - - getScissorTest() { - return this._scissorTest; - } - - setScissorTest(boolean) { - this._scissorTest = boolean; - - this.backend.setScissorTest(boolean); - } - - getViewport(target) { - return target.copy(this._viewport); - } - - setViewport(x, y, width, height, minDepth = 0, maxDepth = 1) { - const viewport = this._viewport; - - if (x.isVector4) { - viewport.copy(x); - } else { - viewport.set(x, y, width, height); - } - - viewport.minDepth = minDepth; - viewport.maxDepth = maxDepth; - } - - getClearColor(target) { - return target.copy(this._clearColor); - } - - setClearColor(color, alpha = 1) { - this._clearColor.set(color); - this._clearColor.a = alpha; - } - - getClearAlpha() { - return this._clearColor.a; - } - - setClearAlpha(alpha) { - this._clearColor.a = alpha; - } - - getClearDepth() { - return this._clearDepth; - } - - setClearDepth(depth) { - this._clearDepth = depth; - } - - getClearStencil() { - return this._clearStencil; - } - - setClearStencil(stencil) { - this._clearStencil = stencil; - } - - isOccluded(object) { - const renderContext = this._currentRenderContext; - - return renderContext && this.backend.isOccluded(renderContext, object); - } - - clear(color = true, depth = true, stencil = true) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .clear() called before the backend is initialized. Try using .clearAsync() instead.', - ); - - return this.clearAsync(color, depth, stencil); - } - - const renderTarget = this._renderTarget || this._getFrameBufferTarget(); - - let renderTargetData = null; - - if (renderTarget !== null) { - this._textures.updateRenderTarget(renderTarget); - - renderTargetData = this._textures.get(renderTarget); - } - - this.backend.clear(color, depth, stencil, renderTargetData); - - if (renderTarget !== null && this._renderTarget === null) { - // If a color space transform or tone mapping is required, - // the clear operation clears the intermediate renderTarget texture, but does not update the screen canvas. - - _quad.material.fragmentNode = this._nodes.getOutputNode(renderTarget.texture); - this._renderScene(_quad, _quad.camera, false); - } - } - - clearColor() { - return this.clear(true, false, false); - } - - clearDepth() { - return this.clear(false, true, false); - } - - clearStencil() { - return this.clear(false, false, true); - } - - async clearAsync(color = true, depth = true, stencil = true) { - if (this._initialized === false) await this.init(); - - this.clear(color, depth, stencil); - } - - clearColorAsync() { - return this.clearAsync(true, false, false); - } - - clearDepthAsync() { - return this.clearAsync(false, true, false); - } - - clearStencilAsync() { - return this.clearAsync(false, false, true); - } - - get currentColorSpace() { - const renderTarget = this._renderTarget; - - if (renderTarget !== null) { - const texture = renderTarget.texture; - - return (Array.isArray(texture) ? texture[0] : texture).colorSpace; - } - - return this.outputColorSpace; - } - - dispose() { - this.info.dispose(); - - this._animation.dispose(); - this._objects.dispose(); - this._pipelines.dispose(); - this._nodes.dispose(); - this._bindings.dispose(); - this._renderLists.dispose(); - this._renderContexts.dispose(); - this._textures.dispose(); - - this.setRenderTarget(null); - this.setAnimationLoop(null); - } - - setRenderTarget(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) { - this._renderTarget = renderTarget; - this._activeCubeFace = activeCubeFace; - this._activeMipmapLevel = activeMipmapLevel; - } - - getRenderTarget() { - return this._renderTarget; - } - - setRenderObjectFunction(renderObjectFunction) { - this._renderObjectFunction = renderObjectFunction; - } - - getRenderObjectFunction() { - return this._renderObjectFunction; - } - - async computeAsync(computeNodes) { - if (this._initialized === false) await this.init(); - - const nodeFrame = this._nodes.nodeFrame; - - const previousRenderId = nodeFrame.renderId; - - // - - this.info.calls++; - this.info.compute.calls++; - this.info.compute.frameCalls++; - - nodeFrame.renderId = this.info.calls; - - // - - const backend = this.backend; - const pipelines = this._pipelines; - const bindings = this._bindings; - const nodes = this._nodes; - - const computeList = Array.isArray(computeNodes) ? computeNodes : [computeNodes]; - - if (computeList[0] === undefined || computeList[0].isComputeNode !== true) { - throw new Error('THREE.Renderer: .compute() expects a ComputeNode.'); - } - - backend.beginCompute(computeNodes); - - for (const computeNode of computeList) { - // onInit - - if (pipelines.has(computeNode) === false) { - const dispose = () => { - computeNode.removeEventListener('dispose', dispose); - - pipelines.delete(computeNode); - bindings.delete(computeNode); - nodes.delete(computeNode); - }; - - computeNode.addEventListener('dispose', dispose); - - // - - computeNode.onInit({ renderer: this }); - } - - nodes.updateForCompute(computeNode); - bindings.updateForCompute(computeNode); - - const computeBindings = bindings.getForCompute(computeNode); - const computePipeline = pipelines.getForCompute(computeNode, computeBindings); - - backend.compute(computeNodes, computeNode, computeBindings, computePipeline); - } - - backend.finishCompute(computeNodes); - - await this.backend.resolveTimestampAsync(computeNodes, 'compute'); - - // - - nodeFrame.renderId = previousRenderId; - } - - async hasFeatureAsync(name) { - if (this._initialized === false) await this.init(); - - return this.backend.hasFeature(name); - } - - hasFeature(name) { - if (this._initialized === false) { - console.warn( - 'THREE.Renderer: .hasFeature() called before the backend is initialized. Try using .hasFeatureAsync() instead.', - ); - - return false; - } - - return this.backend.hasFeature(name); - } - - copyFramebufferToTexture(framebufferTexture) { - const renderContext = this._currentRenderContext; - - this._textures.updateTexture(framebufferTexture); - - this.backend.copyFramebufferToTexture(framebufferTexture, renderContext); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { - this._textures.updateTexture(srcTexture); - this._textures.updateTexture(dstTexture); - - this.backend.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level); - } - - readRenderTargetPixelsAsync(renderTarget, x, y, width, height, index = 0) { - return this.backend.copyTextureToBuffer(renderTarget.textures[index], x, y, width, height); - } - - _projectObject(object, camera, groupOrder, renderList) { - if (object.visible === false) return; - - const visible = object.layers.test(camera.layers); - - if (visible) { - if (object.isGroup) { - groupOrder = object.renderOrder; - } else if (object.isLOD) { - if (object.autoUpdate === true) object.update(camera); - } else if (object.isLight) { - renderList.pushLight(object); - } else if (object.isSprite) { - if (!object.frustumCulled || _frustum.intersectsSprite(object)) { - if (this.sortObjects === true) { - _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix); - } - - const geometry = object.geometry; - const material = object.material; - - if (material.visible) { - renderList.push(object, geometry, material, groupOrder, _vector3.z, null); - } - } - } else if (object.isLineLoop) { - console.error( - 'THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.', - ); - } else if (object.isMesh || object.isLine || object.isPoints) { - if (!object.frustumCulled || _frustum.intersectsObject(object)) { - const geometry = object.geometry; - const material = object.material; - - if (this.sortObjects === true) { - if (geometry.boundingSphere === null) geometry.computeBoundingSphere(); - - _vector3 - .copy(geometry.boundingSphere.center) - .applyMatrix4(object.matrixWorld) - .applyMatrix4(_projScreenMatrix); - } - - if (Array.isArray(material)) { - const groups = geometry.groups; - - for (let i = 0, l = groups.length; i < l; i++) { - const group = groups[i]; - const groupMaterial = material[group.materialIndex]; - - if (groupMaterial && groupMaterial.visible) { - renderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); - } - } - } else if (material.visible) { - renderList.push(object, geometry, material, groupOrder, _vector3.z, null); - } - } - } - } - - if (object.static === true) { - const baseRenderList = renderList; - - // replace render list - renderList = this._renderLists.get(object, camera); - - renderList.begin(); - - baseRenderList.pushBundle({ - object, - camera, - renderList, - }); - - renderList.finish(); - } - - const children = object.children; - - for (let i = 0, l = children.length; i < l; i++) { - this._projectObject(children[i], camera, groupOrder, renderList); - } - } - - _renderBundles(bundles, sceneRef, lightsNode) { - for (const bundle of bundles) { - this._renderBundle(bundle, sceneRef, lightsNode); - } - } - - _renderObjects(renderList, camera, scene, lightsNode) { - // process renderable objects - - for (let i = 0, il = renderList.length; i < il; i++) { - const renderItem = renderList[i]; - - // @TODO: Add support for multiple materials per object. This will require to extract - // the material from the renderItem object and pass it with its group data to renderObject(). - - const { object, geometry, material, group } = renderItem; - - if (camera.isArrayCamera) { - const cameras = camera.cameras; - - for (let j = 0, jl = cameras.length; j < jl; j++) { - const camera2 = cameras[j]; - - if (object.layers.test(camera2.layers)) { - const vp = camera2.viewport; - const minDepth = vp.minDepth === undefined ? 0 : vp.minDepth; - const maxDepth = vp.maxDepth === undefined ? 1 : vp.maxDepth; - - const viewportValue = this._currentRenderContext.viewportValue; - viewportValue.copy(vp).multiplyScalar(this._pixelRatio).floor(); - viewportValue.minDepth = minDepth; - viewportValue.maxDepth = maxDepth; - - this.backend.updateViewport(this._currentRenderContext); - - this._currentRenderObjectFunction( - object, - scene, - camera2, - geometry, - material, - group, - lightsNode, - ); - } - } - } else { - this._currentRenderObjectFunction(object, scene, camera, geometry, material, group, lightsNode); - } - } - } - - renderObject(object, scene, camera, geometry, material, group, lightsNode) { - let overridePositionNode; - let overrideFragmentNode; - let overrideDepthNode; - - // - - object.onBeforeRender(this, scene, camera, geometry, material, group); - - // - - if (scene.overrideMaterial !== null) { - const overrideMaterial = scene.overrideMaterial; - - if (material.positionNode && material.positionNode.isNode) { - overridePositionNode = overrideMaterial.positionNode; - overrideMaterial.positionNode = material.positionNode; - } - - if (overrideMaterial.isShadowNodeMaterial) { - overrideMaterial.side = material.shadowSide === null ? material.side : material.shadowSide; - - if (material.depthNode && material.depthNode.isNode) { - overrideDepthNode = overrideMaterial.depthNode; - overrideMaterial.depthNode = material.depthNode; - } - - if (material.shadowNode && material.shadowNode.isNode) { - overrideFragmentNode = overrideMaterial.fragmentNode; - overrideMaterial.fragmentNode = material.shadowNode; - } - - if (this.localClippingEnabled) { - if (material.clipShadows) { - if (overrideMaterial.clippingPlanes !== material.clippingPlanes) { - overrideMaterial.clippingPlanes = material.clippingPlanes; - overrideMaterial.needsUpdate = true; - } - - if (overrideMaterial.clipIntersection !== material.clipIntersection) { - overrideMaterial.clipIntersection = material.clipIntersection; - } - } else if (Array.isArray(overrideMaterial.clippingPlanes)) { - overrideMaterial.clippingPlanes = null; - overrideMaterial.needsUpdate = true; - } - } - } - - material = overrideMaterial; - } - - // - - if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) { - material.side = BackSide; - this._handleObjectFunction(object, material, scene, camera, lightsNode, group, 'backSide'); // create backSide pass id - - material.side = FrontSide; - this._handleObjectFunction(object, material, scene, camera, lightsNode, group); // use default pass id - - material.side = DoubleSide; - } else { - this._handleObjectFunction(object, material, scene, camera, lightsNode, group); - } - - // - - if (overridePositionNode !== undefined) { - scene.overrideMaterial.positionNode = overridePositionNode; - } - - if (overrideDepthNode !== undefined) { - scene.overrideMaterial.depthNode = overrideDepthNode; - } - - if (overrideFragmentNode !== undefined) { - scene.overrideMaterial.fragmentNode = overrideFragmentNode; - } - - // - - object.onAfterRender(this, scene, camera, geometry, material, group); - } - - _renderObjectDirect(object, material, scene, camera, lightsNode, group, passId) { - const renderObject = this._objects.get( - object, - material, - scene, - camera, - lightsNode, - this._currentRenderContext, - passId, - ); - renderObject.drawRange = group || object.geometry.drawRange; - - // - - this._nodes.updateBefore(renderObject); - - // - - object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld); - object.normalMatrix.getNormalMatrix(object.modelViewMatrix); - - // - - this._nodes.updateForRender(renderObject); - this._geometries.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - this._pipelines.updateForRender(renderObject); - - // - - if (this._currentRenderBundle !== null && this._currentRenderBundle.needsUpdate === true) { - const renderObjectData = this.backend.get(renderObject); - - renderObjectData.bundleEncoder = undefined; - renderObjectData.lastPipelineGPU = undefined; - } - - this.backend.draw(renderObject, this.info); - - if (this._currentRenderBundle !== null) { - const renderContextData = this.backend.get(this._currentRenderContext); - - renderContextData.renderObjects.push(renderObject); - } - - this._nodes.updateAfter(renderObject); - } - - _createObjectPipeline(object, material, scene, camera, lightsNode, passId) { - const renderObject = this._objects.get( - object, - material, - scene, - camera, - lightsNode, - this._currentRenderContext, - passId, - ); - - // - - this._nodes.updateBefore(renderObject); - - // - - this._nodes.updateForRender(renderObject); - this._geometries.updateForRender(renderObject); - this._bindings.updateForRender(renderObject); - - this._pipelines.getForRender(renderObject, this._compilationPromises); - - this._nodes.updateAfter(renderObject); - } - - get compute() { - return this.computeAsync; - } - - get compile() { - return this.compileAsync; - } -} - -export default Renderer; diff --git a/examples-jsm/examples/renderers/common/SampledTexture.ts b/examples-jsm/examples/renderers/common/SampledTexture.ts deleted file mode 100644 index d995a59f8..000000000 --- a/examples-jsm/examples/renderers/common/SampledTexture.ts +++ /dev/null @@ -1,61 +0,0 @@ -import Binding from './Binding.js'; - -let id = 0; - -class SampledTexture extends Binding { - constructor(name, texture) { - super(name); - - this.id = id++; - - this.texture = texture; - this.version = texture ? texture.version : 0; - this.store = false; - - this.isSampledTexture = true; - } - - get needsBindingsUpdate() { - const { texture, version } = this; - - return texture.isVideoTexture ? true : version !== texture.version; // @TODO: version === 0 && texture.version > 0 ( add it just to External Textures like PNG,JPG ) - } - - update() { - const { texture, version } = this; - - if (version !== texture.version) { - this.version = texture.version; - - return true; - } - - return false; - } -} - -class SampledArrayTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampledArrayTexture = true; - } -} - -class Sampled3DTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampled3DTexture = true; - } -} - -class SampledCubeTexture extends SampledTexture { - constructor(name, texture) { - super(name, texture); - - this.isSampledCubeTexture = true; - } -} - -export { SampledTexture, SampledArrayTexture, Sampled3DTexture, SampledCubeTexture }; diff --git a/examples-jsm/examples/renderers/common/Sampler.ts b/examples-jsm/examples/renderers/common/Sampler.ts deleted file mode 100644 index 8cd20d04a..000000000 --- a/examples-jsm/examples/renderers/common/Sampler.ts +++ /dev/null @@ -1,14 +0,0 @@ -import Binding from './Binding.js'; - -class Sampler extends Binding { - constructor(name, texture) { - super(name); - - this.texture = texture; - this.version = texture ? texture.version : 0; - - this.isSampler = true; - } -} - -export default Sampler; diff --git a/examples-jsm/examples/renderers/common/StorageBuffer.ts b/examples-jsm/examples/renderers/common/StorageBuffer.ts deleted file mode 100644 index ef5d3e464..000000000 --- a/examples-jsm/examples/renderers/common/StorageBuffer.ts +++ /dev/null @@ -1,13 +0,0 @@ -import Buffer from './Buffer.js'; - -class StorageBuffer extends Buffer { - constructor(name, attribute) { - super(name, attribute ? attribute.array : null); - - this.attribute = attribute; - - this.isStorageBuffer = true; - } -} - -export default StorageBuffer; diff --git a/examples-jsm/examples/renderers/common/Textures.ts b/examples-jsm/examples/renderers/common/Textures.ts deleted file mode 100644 index 0eb0509ca..000000000 --- a/examples-jsm/examples/renderers/common/Textures.ts +++ /dev/null @@ -1,288 +0,0 @@ -import DataMap from './DataMap.js'; - -import { - Vector3, - DepthTexture, - DepthStencilFormat, - DepthFormat, - UnsignedIntType, - UnsignedInt248Type, - LinearFilter, - NearestFilter, - EquirectangularReflectionMapping, - EquirectangularRefractionMapping, - CubeReflectionMapping, - CubeRefractionMapping, - UnsignedByteType, -} from 'three'; - -const _size = new Vector3(); - -class Textures extends DataMap { - constructor(renderer, backend, info) { - super(); - - this.renderer = renderer; - this.backend = backend; - this.info = info; - } - - updateRenderTarget(renderTarget, activeMipmapLevel = 0) { - const renderTargetData = this.get(renderTarget); - - const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples; - const depthTextureMips = renderTargetData.depthTextureMips || (renderTargetData.depthTextureMips = {}); - - const texture = renderTarget.texture; - const textures = renderTarget.textures; - - const size = this.getSize(texture); - - const mipWidth = size.width >> activeMipmapLevel; - const mipHeight = size.height >> activeMipmapLevel; - - let depthTexture = renderTarget.depthTexture || depthTextureMips[activeMipmapLevel]; - let textureNeedsUpdate = false; - - if (depthTexture === undefined) { - depthTexture = new DepthTexture(); - depthTexture.format = renderTarget.stencilBuffer ? DepthStencilFormat : DepthFormat; - depthTexture.type = renderTarget.stencilBuffer ? UnsignedInt248Type : UnsignedIntType; // FloatType - depthTexture.image.width = mipWidth; - depthTexture.image.height = mipHeight; - - depthTextureMips[activeMipmapLevel] = depthTexture; - } - - if (renderTargetData.width !== size.width || size.height !== renderTargetData.height) { - textureNeedsUpdate = true; - depthTexture.needsUpdate = true; - - depthTexture.image.width = mipWidth; - depthTexture.image.height = mipHeight; - } - - renderTargetData.width = size.width; - renderTargetData.height = size.height; - renderTargetData.textures = textures; - renderTargetData.depthTexture = depthTexture; - renderTargetData.depth = renderTarget.depthBuffer; - renderTargetData.stencil = renderTarget.stencilBuffer; - renderTargetData.renderTarget = renderTarget; - - if (renderTargetData.sampleCount !== sampleCount) { - textureNeedsUpdate = true; - depthTexture.needsUpdate = true; - - renderTargetData.sampleCount = sampleCount; - } - - // - - const options = { sampleCount }; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (textureNeedsUpdate) texture.needsUpdate = true; - - this.updateTexture(texture, options); - } - - this.updateTexture(depthTexture, options); - - // dispose handler - - if (renderTargetData.initialized !== true) { - renderTargetData.initialized = true; - - // dispose - - const onDispose = () => { - renderTarget.removeEventListener('dispose', onDispose); - - if (textures !== undefined) { - for (let i = 0; i < textures.length; i++) { - this._destroyTexture(textures[i]); - } - } else { - this._destroyTexture(texture); - } - - this._destroyTexture(depthTexture); - }; - - renderTarget.addEventListener('dispose', onDispose); - } - } - - updateTexture(texture, options = {}) { - const textureData = this.get(texture); - if (textureData.initialized === true && textureData.version === texture.version) return; - - const isRenderTarget = texture.isRenderTargetTexture || texture.isDepthTexture || texture.isFramebufferTexture; - const backend = this.backend; - - if (isRenderTarget && textureData.initialized === true) { - // it's an update - - backend.destroySampler(texture); - backend.destroyTexture(texture); - } - - // - - if (texture.isFramebufferTexture) { - const renderer = this.renderer; - const renderTarget = renderer.getRenderTarget(); - - if (renderTarget) { - texture.type = renderTarget.texture.type; - } else { - texture.type = UnsignedByteType; - } - } - - // - - const { width, height, depth } = this.getSize(texture); - - options.width = width; - options.height = height; - options.depth = depth; - options.needsMipmaps = this.needsMipmaps(texture); - options.levels = options.needsMipmaps ? this.getMipLevels(texture, width, height) : 1; - - // - - if (isRenderTarget || texture.isStorageTexture === true) { - backend.createSampler(texture); - backend.createTexture(texture, options); - } else { - const needsCreate = textureData.initialized !== true; - - if (needsCreate) backend.createSampler(texture); - - if (texture.version > 0) { - const image = texture.image; - - if (image === undefined) { - console.warn('THREE.Renderer: Texture marked for update but image is undefined.'); - } else if (image.complete === false) { - console.warn('THREE.Renderer: Texture marked for update but image is incomplete.'); - } else { - if (texture.images) { - const images = []; - - for (const image of texture.images) { - images.push(image); - } - - options.images = images; - } else { - options.image = image; - } - - if (textureData.isDefaultTexture === undefined || textureData.isDefaultTexture === true) { - backend.createTexture(texture, options); - - textureData.isDefaultTexture = false; - } - - if (texture.source.dataReady === true) backend.updateTexture(texture, options); - - if (options.needsMipmaps && texture.mipmaps.length === 0) backend.generateMipmaps(texture); - } - } else { - // async update - - backend.createDefaultTexture(texture); - - textureData.isDefaultTexture = true; - } - } - - // dispose handler - - if (textureData.initialized !== true) { - textureData.initialized = true; - - // - - this.info.memory.textures++; - - // dispose - - const onDispose = () => { - texture.removeEventListener('dispose', onDispose); - - this._destroyTexture(texture); - - this.info.memory.textures--; - }; - - texture.addEventListener('dispose', onDispose); - } - - // - - textureData.version = texture.version; - } - - getSize(texture, target = _size) { - let image = texture.images ? texture.images[0] : texture.image; - - if (image) { - if (image.image !== undefined) image = image.image; - - target.width = image.width; - target.height = image.height; - target.depth = texture.isCubeTexture ? 6 : image.depth || 1; - } else { - target.width = target.height = target.depth = 1; - } - - return target; - } - - getMipLevels(texture, width, height) { - let mipLevelCount; - - if (texture.isCompressedTexture) { - mipLevelCount = texture.mipmaps.length; - } else { - mipLevelCount = Math.floor(Math.log2(Math.max(width, height))) + 1; - } - - return mipLevelCount; - } - - needsMipmaps(texture) { - if (this.isEnvironmentTexture(texture)) return true; - - return ( - texture.isCompressedTexture === true || - (texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) - ); - } - - isEnvironmentTexture(texture) { - const mapping = texture.mapping; - - return ( - mapping === EquirectangularReflectionMapping || - mapping === EquirectangularRefractionMapping || - mapping === CubeReflectionMapping || - mapping === CubeRefractionMapping - ); - } - - _destroyTexture(texture) { - this.backend.destroySampler(texture); - this.backend.destroyTexture(texture); - - this.delete(texture); - } -} - -export default Textures; diff --git a/examples-jsm/examples/renderers/common/Uniform.ts b/examples-jsm/examples/renderers/common/Uniform.ts deleted file mode 100644 index 3d58b44cb..000000000 --- a/examples-jsm/examples/renderers/common/Uniform.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three'; - -class Uniform { - constructor(name, value) { - this.name = name; - this.value = value; - - this.boundary = 0; // used to build the uniform buffer according to the STD140 layout - this.itemSize = 0; - - this.offset = 0; // this property is set by WebGPUUniformsGroup and marks the start position in the uniform buffer - } - - setValue(value) { - this.value = value; - } - - getValue() { - return this.value; - } -} - -class NumberUniform extends Uniform { - constructor(name, value = 0) { - super(name, value); - - this.isNumberUniform = true; - - this.boundary = 4; - this.itemSize = 1; - } -} - -class Vector2Uniform extends Uniform { - constructor(name, value = new Vector2()) { - super(name, value); - - this.isVector2Uniform = true; - - this.boundary = 8; - this.itemSize = 2; - } -} - -class Vector3Uniform extends Uniform { - constructor(name, value = new Vector3()) { - super(name, value); - - this.isVector3Uniform = true; - - this.boundary = 16; - this.itemSize = 3; - } -} - -class Vector4Uniform extends Uniform { - constructor(name, value = new Vector4()) { - super(name, value); - - this.isVector4Uniform = true; - - this.boundary = 16; - this.itemSize = 4; - } -} - -class ColorUniform extends Uniform { - constructor(name, value = new Color()) { - super(name, value); - - this.isColorUniform = true; - - this.boundary = 16; - this.itemSize = 3; - } -} - -class Matrix3Uniform extends Uniform { - constructor(name, value = new Matrix3()) { - super(name, value); - - this.isMatrix3Uniform = true; - - this.boundary = 48; - this.itemSize = 12; - } -} - -class Matrix4Uniform extends Uniform { - constructor(name, value = new Matrix4()) { - super(name, value); - - this.isMatrix4Uniform = true; - - this.boundary = 64; - this.itemSize = 16; - } -} - -export { NumberUniform, Vector2Uniform, Vector3Uniform, Vector4Uniform, ColorUniform, Matrix3Uniform, Matrix4Uniform }; diff --git a/examples-jsm/examples/renderers/common/UniformBuffer.ts b/examples-jsm/examples/renderers/common/UniformBuffer.ts deleted file mode 100644 index 28aac0d7e..000000000 --- a/examples-jsm/examples/renderers/common/UniformBuffer.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Buffer from './Buffer.js'; - -class UniformBuffer extends Buffer { - constructor(name, buffer = null) { - super(name, buffer); - - this.isUniformBuffer = true; - } -} - -export default UniformBuffer; diff --git a/examples-jsm/examples/renderers/common/UniformsGroup.ts b/examples-jsm/examples/renderers/common/UniformsGroup.ts deleted file mode 100644 index e2b62671a..000000000 --- a/examples-jsm/examples/renderers/common/UniformsGroup.ts +++ /dev/null @@ -1,277 +0,0 @@ -import UniformBuffer from './UniformBuffer.js'; -import { GPU_CHUNK_BYTES } from './Constants.js'; - -class UniformsGroup extends UniformBuffer { - constructor(name) { - super(name); - - this.isUniformsGroup = true; - - this._values = null; - - // the order of uniforms in this array must match the order of uniforms in the shader - - this.uniforms = []; - } - - addUniform(uniform) { - this.uniforms.push(uniform); - - return this; - } - - removeUniform(uniform) { - const index = this.uniforms.indexOf(uniform); - - if (index !== -1) { - this.uniforms.splice(index, 1); - } - - return this; - } - - get values() { - if (this._values === null) { - this._values = Array.from(this.buffer); - } - - return this._values; - } - - get buffer() { - let buffer = this._buffer; - - if (buffer === null) { - const byteLength = this.byteLength; - - buffer = new Float32Array(new ArrayBuffer(byteLength)); - - this._buffer = buffer; - } - - return buffer; - } - - get byteLength() { - let offset = 0; // global buffer offset in bytes - - for (let i = 0, l = this.uniforms.length; i < l; i++) { - const uniform = this.uniforms[i]; - - const { boundary, itemSize } = uniform; - - // offset within a single chunk in bytes - - const chunkOffset = offset % GPU_CHUNK_BYTES; - const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset; - - // conformance tests - - if (chunkOffset !== 0 && remainingSizeInChunk - boundary < 0) { - // check for chunk overflow - - offset += GPU_CHUNK_BYTES - chunkOffset; - } else if (chunkOffset % boundary !== 0) { - // check for correct alignment - - offset += chunkOffset % boundary; - } - - uniform.offset = offset / this.bytesPerElement; - - offset += itemSize * this.bytesPerElement; - } - - return Math.ceil(offset / GPU_CHUNK_BYTES) * GPU_CHUNK_BYTES; - } - - update() { - let updated = false; - - for (const uniform of this.uniforms) { - if (this.updateByType(uniform) === true) { - updated = true; - } - } - - return updated; - } - - updateByType(uniform) { - if (uniform.isNumberUniform) return this.updateNumber(uniform); - if (uniform.isVector2Uniform) return this.updateVector2(uniform); - if (uniform.isVector3Uniform) return this.updateVector3(uniform); - if (uniform.isVector4Uniform) return this.updateVector4(uniform); - if (uniform.isColorUniform) return this.updateColor(uniform); - if (uniform.isMatrix3Uniform) return this.updateMatrix3(uniform); - if (uniform.isMatrix4Uniform) return this.updateMatrix4(uniform); - - console.error('THREE.WebGPUUniformsGroup: Unsupported uniform type.', uniform); - } - - updateNumber(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset] !== v) { - const b = this.buffer; - - b[offset] = a[offset] = v; - updated = true; - } - - return updated; - } - - updateVector2(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - - updated = true; - } - - return updated; - } - - updateVector3(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - b[offset + 2] = a[offset + 2] = v.z; - - updated = true; - } - - return updated; - } - - updateVector4(uniform) { - let updated = false; - - const a = this.values; - const v = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== v.x || a[offset + 1] !== v.y || a[offset + 2] !== v.z || a[offset + 4] !== v.w) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = v.x; - b[offset + 1] = a[offset + 1] = v.y; - b[offset + 2] = a[offset + 2] = v.z; - b[offset + 3] = a[offset + 3] = v.w; - - updated = true; - } - - return updated; - } - - updateColor(uniform) { - let updated = false; - - const a = this.values; - const c = uniform.getValue(); - const offset = uniform.offset; - - if (a[offset + 0] !== c.r || a[offset + 1] !== c.g || a[offset + 2] !== c.b) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = c.r; - b[offset + 1] = a[offset + 1] = c.g; - b[offset + 2] = a[offset + 2] = c.b; - - updated = true; - } - - return updated; - } - - updateMatrix3(uniform) { - let updated = false; - - const a = this.values; - const e = uniform.getValue().elements; - const offset = uniform.offset; - - if ( - a[offset + 0] !== e[0] || - a[offset + 1] !== e[1] || - a[offset + 2] !== e[2] || - a[offset + 4] !== e[3] || - a[offset + 5] !== e[4] || - a[offset + 6] !== e[5] || - a[offset + 8] !== e[6] || - a[offset + 9] !== e[7] || - a[offset + 10] !== e[8] - ) { - const b = this.buffer; - - b[offset + 0] = a[offset + 0] = e[0]; - b[offset + 1] = a[offset + 1] = e[1]; - b[offset + 2] = a[offset + 2] = e[2]; - b[offset + 4] = a[offset + 4] = e[3]; - b[offset + 5] = a[offset + 5] = e[4]; - b[offset + 6] = a[offset + 6] = e[5]; - b[offset + 8] = a[offset + 8] = e[6]; - b[offset + 9] = a[offset + 9] = e[7]; - b[offset + 10] = a[offset + 10] = e[8]; - - updated = true; - } - - return updated; - } - - updateMatrix4(uniform) { - let updated = false; - - const a = this.values; - const e = uniform.getValue().elements; - const offset = uniform.offset; - - if (arraysEqual(a, e, offset) === false) { - const b = this.buffer; - b.set(e, offset); - setArray(a, e, offset); - updated = true; - } - - return updated; - } -} - -function setArray(a, b, offset) { - for (let i = 0, l = b.length; i < l; i++) { - a[offset + i] = b[i]; - } -} - -function arraysEqual(a, b, offset) { - for (let i = 0, l = b.length; i < l; i++) { - if (a[offset + i] !== b[i]) return false; - } - - return true; -} - -export default UniformsGroup; diff --git a/examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts b/examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts deleted file mode 100644 index b0aa2f8e8..000000000 --- a/examples-jsm/examples/renderers/common/extras/PMREMGenerator.ts +++ /dev/null @@ -1,659 +0,0 @@ -import NodeMaterial from '../../../nodes/materials/NodeMaterial.js'; -import { getDirection, blur } from '../../../nodes/pmrem/PMREMUtils.js'; -import { equirectUV } from '../../../nodes/utils/EquirectUVNode.js'; -import { uniform } from '../../../nodes/core/UniformNode.js'; -import { uniforms } from '../../../nodes/accessors/UniformsNode.js'; -import { texture } from '../../../nodes/accessors/TextureNode.js'; -import { cubeTexture } from '../../../nodes/accessors/CubeTextureNode.js'; -import { float, vec3 } from '../../../nodes/shadernode/ShaderNode.js'; -import { uv } from '../../../nodes/accessors/UVNode.js'; -import { attribute } from '../../../nodes/core/AttributeNode.js'; -import { - OrthographicCamera, - Color, - Vector3, - BufferGeometry, - BufferAttribute, - RenderTarget, - Mesh, - CubeReflectionMapping, - CubeRefractionMapping, - CubeUVReflectionMapping, - LinearFilter, - NoBlending, - RGBAFormat, - HalfFloatType, - BackSide, - LinearSRGBColorSpace, - PerspectiveCamera, - MeshBasicMaterial, - BoxGeometry, -} from 'three'; - -const LOD_MIN = 4; - -// The standard deviations (radians) associated with the extra mips. These are -// chosen to approximate a Trowbridge-Reitz distribution function times the -// geometric shadowing function. These sigma values squared must match the -// variance #defines in cube_uv_reflection_fragment.glsl.js. -const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; - -// The maximum length of the blur for loop. Smaller sigmas will use fewer -// samples and exit early, but not recompile the shader. -const MAX_SAMPLES = 20; - -const _flatCamera = /*@__PURE__*/ new OrthographicCamera(-1, 1, 1, -1, 0, 1); -const _cubeCamera = /*@__PURE__*/ new PerspectiveCamera(90, 1); -const _clearColor = /*@__PURE__*/ new Color(); -let _oldTarget = null; -let _oldActiveCubeFace = 0; -let _oldActiveMipmapLevel = 0; - -// Golden Ratio -const PHI = (1 + Math.sqrt(5)) / 2; -const INV_PHI = 1 / PHI; - -// Vertices of a dodecahedron (except the opposites, which represent the -// same axis), used as axis directions evenly spread on a sphere. -const _axisDirections = [ - /*@__PURE__*/ new Vector3(-PHI, INV_PHI, 0), - /*@__PURE__*/ new Vector3(PHI, INV_PHI, 0), - /*@__PURE__*/ new Vector3(-INV_PHI, 0, PHI), - /*@__PURE__*/ new Vector3(INV_PHI, 0, PHI), - /*@__PURE__*/ new Vector3(0, PHI, -INV_PHI), - /*@__PURE__*/ new Vector3(0, PHI, INV_PHI), - /*@__PURE__*/ new Vector3(-1, 1, -1), - /*@__PURE__*/ new Vector3(1, 1, -1), - /*@__PURE__*/ new Vector3(-1, 1, 1), - /*@__PURE__*/ new Vector3(1, 1, 1), -]; - -// - -// WebGPU Face indices -const _faceLib = [3, 1, 5, 0, 4, 2]; - -const direction = getDirection(uv(), attribute('faceIndex')).normalize(); -const outputDirection = vec3(direction.x, direction.y.negate(), direction.z); - -/** - * This class generates a Prefiltered, Mipmapped Radiance Environment Map - * (PMREM) from a cubeMap environment texture. This allows different levels of - * blur to be quickly accessed based on material roughness. It is packed into a - * special CubeUV format that allows us to perform custom interpolation so that - * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap - * chain, it only goes down to the LOD_MIN level (above), and then creates extra - * even more filtered 'mips' at the same LOD_MIN resolution, associated with - * higher roughness levels. In this way we maintain resolution to smoothly - * interpolate diffuse lighting while limiting sampling computation. - * - * Paper: Fast, Accurate Image-Based Lighting - * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view - */ - -class PMREMGenerator { - constructor(renderer) { - this._renderer = renderer; - this._pingPongRenderTarget = null; - - this._lodMax = 0; - this._cubeSize = 0; - this._lodPlanes = []; - this._sizeLods = []; - this._sigmas = []; - this._lodMeshes = []; - - this._blurMaterial = null; - this._cubemapMaterial = null; - this._equirectMaterial = null; - this._backgroundBox = null; - } - - /** - * Generates a PMREM from a supplied Scene, which can be faster than using an - * image if networking bandwidth is low. Optional sigma specifies a blur radius - * in radians to be applied to the scene before PMREM generation. Optional near - * and far planes ensure the scene is rendered in its entirety (the cubeCamera - * is placed at the origin). - */ - fromScene(scene, sigma = 0, near = 0.1, far = 100) { - _oldTarget = this._renderer.getRenderTarget(); - _oldActiveCubeFace = this._renderer.getActiveCubeFace(); - _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); - - this._setSize(256); - - const cubeUVRenderTarget = this._allocateTargets(); - cubeUVRenderTarget.depthBuffer = true; - - this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget); - - if (sigma > 0) { - this._blur(cubeUVRenderTarget, 0, 0, sigma); - } - - this._applyPMREM(cubeUVRenderTarget); - - this._cleanup(cubeUVRenderTarget); - - return cubeUVRenderTarget; - } - - /** - * Generates a PMREM from an equirectangular texture, which can be either LDR - * or HDR. The ideal input image size is 1k (1024 x 512), - * as this matches best with the 256 x 256 cubemap output. - */ - fromEquirectangular(equirectangular, renderTarget = null) { - return this._fromTexture(equirectangular, renderTarget); - } - - /** - * Generates a PMREM from an cubemap texture, which can be either LDR - * or HDR. The ideal input cube size is 256 x 256, - * as this matches best with the 256 x 256 cubemap output. - */ - fromCubemap(cubemap, renderTarget = null) { - return this._fromTexture(cubemap, renderTarget); - } - - /** - * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during - * your texture's network fetch for increased concurrency. - */ - compileCubemapShader() { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(); - this._compileMaterial(this._cubemapMaterial); - } - } - - /** - * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during - * your texture's network fetch for increased concurrency. - */ - compileEquirectangularShader() { - if (this._equirectMaterial === null) { - this._equirectMaterial = _getEquirectMaterial(); - this._compileMaterial(this._equirectMaterial); - } - } - - /** - * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, - * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on - * one of them will cause any others to also become unusable. - */ - dispose() { - this._dispose(); - - if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose(); - if (this._equirectMaterial !== null) this._equirectMaterial.dispose(); - if (this._backgroundBox !== null) { - this._backgroundBox.geometry.dispose(); - this._backgroundBox.material.dispose(); - } - } - - // private interface - - _setSize(cubeSize) { - this._lodMax = Math.floor(Math.log2(cubeSize)); - this._cubeSize = Math.pow(2, this._lodMax); - } - - _dispose() { - if (this._blurMaterial !== null) this._blurMaterial.dispose(); - - if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose(); - - for (let i = 0; i < this._lodPlanes.length; i++) { - this._lodPlanes[i].dispose(); - } - } - - _cleanup(outputTarget) { - this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel); - outputTarget.scissorTest = false; - _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height); - } - - _fromTexture(texture, renderTarget) { - if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) { - this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width); - } else { - // Equirectangular - - this._setSize(texture.image.width / 4); - } - - _oldTarget = this._renderer.getRenderTarget(); - _oldActiveCubeFace = this._renderer.getActiveCubeFace(); - _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel(); - - const cubeUVRenderTarget = renderTarget || this._allocateTargets(); - this._textureToCubeUV(texture, cubeUVRenderTarget); - this._applyPMREM(cubeUVRenderTarget); - this._cleanup(cubeUVRenderTarget); - - return cubeUVRenderTarget; - } - - _allocateTargets() { - const width = 3 * Math.max(this._cubeSize, 16 * 7); - const height = 4 * this._cubeSize; - - const params = { - magFilter: LinearFilter, - minFilter: LinearFilter, - generateMipmaps: false, - type: HalfFloatType, - format: RGBAFormat, - colorSpace: LinearSRGBColorSpace, - //depthBuffer: false - }; - - const cubeUVRenderTarget = _createRenderTarget(width, height, params); - - if ( - this._pingPongRenderTarget === null || - this._pingPongRenderTarget.width !== width || - this._pingPongRenderTarget.height !== height - ) { - if (this._pingPongRenderTarget !== null) { - this._dispose(); - } - - this._pingPongRenderTarget = _createRenderTarget(width, height, params); - - const { _lodMax } = this; - ({ - sizeLods: this._sizeLods, - lodPlanes: this._lodPlanes, - sigmas: this._sigmas, - lodMeshes: this._lodMeshes, - } = _createPlanes(_lodMax)); - - this._blurMaterial = _getBlurShader(_lodMax, width, height); - } - - return cubeUVRenderTarget; - } - - _compileMaterial(material) { - const tmpMesh = this._lodMeshes[0]; - tmpMesh.material = material; - - this._renderer.compile(tmpMesh, _flatCamera); - } - - _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) { - const cubeCamera = _cubeCamera; - cubeCamera.near = near; - cubeCamera.far = far; - - // px, py, pz, nx, ny, nz - const upSign = [-1, 1, -1, -1, -1, -1]; - const forwardSign = [1, 1, 1, -1, -1, -1]; - - const renderer = this._renderer; - - const originalAutoClear = renderer.autoClear; - - renderer.getClearColor(_clearColor); - - renderer.autoClear = false; - - let backgroundBox = this._backgroundBox; - - if (backgroundBox === null) { - const backgroundMaterial = new MeshBasicMaterial({ - name: 'PMREM.Background', - side: BackSide, - depthWrite: false, - depthTest: false, - }); - - backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial); - } - - let useSolidColor = false; - const background = scene.background; - - if (background) { - if (background.isColor) { - backgroundBox.material.color.copy(background); - scene.background = null; - useSolidColor = true; - } - } else { - backgroundBox.material.color.copy(_clearColor); - useSolidColor = true; - } - - renderer.setRenderTarget(cubeUVRenderTarget); - - renderer.clear(); - - if (useSolidColor) { - renderer.render(backgroundBox, cubeCamera); - } - - for (let i = 0; i < 6; i++) { - const col = i % 3; - - if (col === 0) { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(forwardSign[i], 0, 0); - } else if (col === 1) { - cubeCamera.up.set(0, 0, upSign[i]); - cubeCamera.lookAt(0, forwardSign[i], 0); - } else { - cubeCamera.up.set(0, upSign[i], 0); - cubeCamera.lookAt(0, 0, forwardSign[i]); - } - - const size = this._cubeSize; - - _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); - - renderer.render(scene, cubeCamera); - } - - renderer.autoClear = originalAutoClear; - scene.background = background; - } - - _textureToCubeUV(texture, cubeUVRenderTarget) { - const renderer = this._renderer; - - const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping; - - if (isCubeTexture) { - if (this._cubemapMaterial === null) { - this._cubemapMaterial = _getCubemapMaterial(texture); - } - } else { - if (this._equirectMaterial === null) { - this._equirectMaterial = _getEquirectMaterial(texture); - } - } - - const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial; - material.fragmentNode.value = texture; - - const mesh = this._lodMeshes[0]; - mesh.material = material; - - const size = this._cubeSize; - - _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); - - renderer.setRenderTarget(cubeUVRenderTarget); - renderer.render(mesh, _flatCamera); - } - - _applyPMREM(cubeUVRenderTarget) { - const renderer = this._renderer; - const autoClear = renderer.autoClear; - renderer.autoClear = false; - const n = this._lodPlanes.length; - - for (let i = 1; i < n; i++) { - const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]); - - const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length]; - - this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); - } - - renderer.autoClear = autoClear; - } - - /** - * This is a two-pass Gaussian blur for a cubemap. Normally this is done - * vertically and horizontally, but this breaks down on a cube. Here we apply - * the blur latitudinally (around the poles), and then longitudinally (towards - * the poles) to approximate the orthogonally-separable blur. It is least - * accurate at the poles, but still does a decent job. - */ - _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) { - const pingPongRenderTarget = this._pingPongRenderTarget; - - this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); - - this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis); - } - - _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) { - const renderer = this._renderer; - const blurMaterial = this._blurMaterial; - - if (direction !== 'latitudinal' && direction !== 'longitudinal') { - console.error('blur direction must be either latitudinal or longitudinal!'); - } - - // Number of standard deviations at which to cut off the discrete approximation. - const STANDARD_DEVIATIONS = 3; - - const blurMesh = this._lodMeshes[lodOut]; - blurMesh.material = blurMaterial; - - const blurUniforms = blurMaterial.uniforms; - - const pixels = this._sizeLods[lodIn] - 1; - const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : (2 * Math.PI) / (2 * MAX_SAMPLES - 1); - const sigmaPixels = sigmaRadians / radiansPerPixel; - const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES; - - if (samples > MAX_SAMPLES) { - console.warn( - `sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${ - samples - } samples when the maximum is set to ${MAX_SAMPLES}`, - ); - } - - const weights = []; - let sum = 0; - - for (let i = 0; i < MAX_SAMPLES; ++i) { - const x = i / sigmaPixels; - const weight = Math.exp((-x * x) / 2); - weights.push(weight); - - if (i === 0) { - sum += weight; - } else if (i < samples) { - sum += 2 * weight; - } - } - - for (let i = 0; i < weights.length; i++) { - weights[i] = weights[i] / sum; - } - - targetIn.texture.frame = (targetIn.texture.frame || 0) + 1; - - blurUniforms.envMap.value = targetIn.texture; - blurUniforms.samples.value = samples; - blurUniforms.weights.array = weights; - blurUniforms.latitudinal.value = direction === 'latitudinal' ? 1 : 0; - - if (poleAxis) { - blurUniforms.poleAxis.value = poleAxis; - } - - const { _lodMax } = this; - blurUniforms.dTheta.value = radiansPerPixel; - blurUniforms.mipInt.value = _lodMax - lodIn; - - const outputSize = this._sizeLods[lodOut]; - const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0); - const y = 4 * (this._cubeSize - outputSize); - - _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); - renderer.setRenderTarget(targetOut); - renderer.render(blurMesh, _flatCamera); - } -} - -function _createPlanes(lodMax) { - const lodPlanes = []; - const sizeLods = []; - const sigmas = []; - const lodMeshes = []; - - let lod = lodMax; - - const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length; - - for (let i = 0; i < totalLods; i++) { - const sizeLod = Math.pow(2, lod); - sizeLods.push(sizeLod); - let sigma = 1.0 / sizeLod; - - if (i > lodMax - LOD_MIN) { - sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1]; - } else if (i === 0) { - sigma = 0; - } - - sigmas.push(sigma); - - const texelSize = 1.0 / (sizeLod - 2); - const min = -texelSize; - const max = 1 + texelSize; - const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; - - const cubeFaces = 6; - const vertices = 6; - const positionSize = 3; - const uvSize = 2; - const faceIndexSize = 1; - - const position = new Float32Array(positionSize * vertices * cubeFaces); - const uv = new Float32Array(uvSize * vertices * cubeFaces); - const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces); - - for (let face = 0; face < cubeFaces; face++) { - const x = ((face % 3) * 2) / 3 - 1; - const y = face > 2 ? 0 : -1; - const coordinates = [ - x, - y, - 0, - x + 2 / 3, - y, - 0, - x + 2 / 3, - y + 1, - 0, - x, - y, - 0, - x + 2 / 3, - y + 1, - 0, - x, - y + 1, - 0, - ]; - - const faceIdx = _faceLib[face]; - position.set(coordinates, positionSize * vertices * faceIdx); - uv.set(uv1, uvSize * vertices * faceIdx); - const fill = [faceIdx, faceIdx, faceIdx, faceIdx, faceIdx, faceIdx]; - faceIndex.set(fill, faceIndexSize * vertices * faceIdx); - } - - const planes = new BufferGeometry(); - planes.setAttribute('position', new BufferAttribute(position, positionSize)); - planes.setAttribute('uv', new BufferAttribute(uv, uvSize)); - planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize)); - lodPlanes.push(planes); - lodMeshes.push(new Mesh(planes, null)); - - if (lod > LOD_MIN) { - lod--; - } - } - - return { lodPlanes, sizeLods, sigmas, lodMeshes }; -} - -function _createRenderTarget(width, height, params) { - const cubeUVRenderTarget = new RenderTarget(width, height, params); - cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; - cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; - cubeUVRenderTarget.texture.isPMREMTexture = true; - cubeUVRenderTarget.scissorTest = true; - return cubeUVRenderTarget; -} - -function _setViewport(target, x, y, width, height) { - const viewY = target.height - height - y; - - target.viewport.set(x, viewY, width, height); - target.scissor.set(x, viewY, width, height); -} - -function _getMaterial() { - const material = new NodeMaterial(); - material.depthTest = false; - material.depthWrite = false; - material.blending = NoBlending; - - return material; -} - -function _getBlurShader(lodMax, width, height) { - const weights = uniforms(new Array(MAX_SAMPLES).fill(0)); - const poleAxis = uniform(new Vector3(0, 1, 0)); - const dTheta = uniform(0); - const n = float(MAX_SAMPLES); - const latitudinal = uniform(0); // false, bool - const samples = uniform(1); // int - const envMap = texture(null); - const mipInt = uniform(0); // int - const CUBEUV_TEXEL_WIDTH = float(1 / width); - const CUBEUV_TEXEL_HEIGHT = float(1 / height); - const CUBEUV_MAX_MIP = float(lodMax); - - const materialUniforms = { - n, - latitudinal, - weights, - poleAxis, - outputDirection, - dTheta, - samples, - envMap, - mipInt, - CUBEUV_TEXEL_WIDTH, - CUBEUV_TEXEL_HEIGHT, - CUBEUV_MAX_MIP, - }; - - const material = _getMaterial(); - material.uniforms = materialUniforms; // TODO: Move to outside of the material - material.fragmentNode = blur({ ...materialUniforms, latitudinal: latitudinal.equal(1) }); - - return material; -} - -function _getCubemapMaterial(envTexture) { - const material = _getMaterial(); - material.fragmentNode = cubeTexture(envTexture, outputDirection); - - return material; -} - -function _getEquirectMaterial(envTexture) { - const material = _getMaterial(); - material.fragmentNode = texture(envTexture, equirectUV(outputDirection), 0); - - return material; -} - -export default PMREMGenerator; diff --git a/examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts b/examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts deleted file mode 100644 index e94d965f9..000000000 --- a/examples-jsm/examples/renderers/common/nodes/NodeBuilderState.ts +++ /dev/null @@ -1,55 +0,0 @@ -import BindGroup from '../BindGroup.js'; - -class NodeBuilderState { - constructor( - vertexShader, - fragmentShader, - computeShader, - nodeAttributes, - bindings, - updateNodes, - updateBeforeNodes, - updateAfterNodes, - instanceBindGroups = true, - transforms = [], - ) { - this.vertexShader = vertexShader; - this.fragmentShader = fragmentShader; - this.computeShader = computeShader; - this.transforms = transforms; - - this.nodeAttributes = nodeAttributes; - this.bindings = bindings; - - this.updateNodes = updateNodes; - this.updateBeforeNodes = updateBeforeNodes; - this.updateAfterNodes = updateAfterNodes; - - this.instanceBindGroups = instanceBindGroups; - - this.usedTimes = 0; - } - - createBindings() { - const bindings = []; - - for (const instanceGroup of this.bindings) { - const shared = this.instanceBindGroups && instanceGroup.bindings[0].groupNode.shared; - - if (shared !== true) { - const bindingsGroup = new BindGroup(instanceGroup.name); - bindings.push(bindingsGroup); - - for (const instanceBinding of instanceGroup.bindings) { - bindingsGroup.bindings.push(instanceBinding.clone()); - } - } else { - bindings.push(instanceGroup); - } - } - - return bindings; - } -} - -export default NodeBuilderState; diff --git a/examples-jsm/examples/renderers/common/nodes/NodeUniform.ts b/examples-jsm/examples/renderers/common/nodes/NodeUniform.ts deleted file mode 100644 index 659f5a82f..000000000 --- a/examples-jsm/examples/renderers/common/nodes/NodeUniform.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { - NumberUniform, - Vector2Uniform, - Vector3Uniform, - Vector4Uniform, - ColorUniform, - Matrix3Uniform, - Matrix4Uniform, -} from '../Uniform.js'; - -class NumberNodeUniform extends NumberUniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector2NodeUniform extends Vector2Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector3NodeUniform extends Vector3Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Vector4NodeUniform extends Vector4Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class ColorNodeUniform extends ColorUniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Matrix3NodeUniform extends Matrix3Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -class Matrix4NodeUniform extends Matrix4Uniform { - constructor(nodeUniform) { - super(nodeUniform.name, nodeUniform.value); - - this.nodeUniform = nodeUniform; - } - - getValue() { - return this.nodeUniform.value; - } -} - -export { - NumberNodeUniform, - Vector2NodeUniform, - Vector3NodeUniform, - Vector4NodeUniform, - ColorNodeUniform, - Matrix3NodeUniform, - Matrix4NodeUniform, -}; diff --git a/examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts b/examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts deleted file mode 100644 index e7b389cd6..000000000 --- a/examples-jsm/examples/renderers/common/nodes/NodeUniformsGroup.ts +++ /dev/null @@ -1,30 +0,0 @@ -import UniformsGroup from '../UniformsGroup.js'; - -let id = 0; - -class NodeUniformsGroup extends UniformsGroup { - constructor(name, groupNode) { - super(name); - - this.id = id++; - this.groupNode = groupNode; - - this.isNodeUniformsGroup = true; - } - - getNodes() { - const nodes = []; - - for (const uniform of this.uniforms) { - const node = uniform.nodeUniform.node; - - if (!node) throw new Error('NodeUniformsGroup: Uniform has no node.'); - - nodes.push(node); - } - - return nodes; - } -} - -export default NodeUniformsGroup; diff --git a/examples-jsm/examples/renderers/common/nodes/Nodes.ts b/examples-jsm/examples/renderers/common/nodes/Nodes.ts deleted file mode 100644 index db035f6d9..000000000 --- a/examples-jsm/examples/renderers/common/nodes/Nodes.ts +++ /dev/null @@ -1,394 +0,0 @@ -import DataMap from '../DataMap.js'; -import ChainMap from '../ChainMap.js'; -import NodeBuilderState from './NodeBuilderState.js'; -import { - EquirectangularReflectionMapping, - EquirectangularRefractionMapping, - NoToneMapping, - SRGBColorSpace, -} from 'three'; -import { - NodeFrame, - vec4, - objectGroup, - renderGroup, - frameGroup, - cubeTexture, - texture, - rangeFog, - densityFog, - reference, - viewportBottomLeft, - normalWorld, - pmremTexture, - viewportTopLeft, -} from '../../../nodes/Nodes.js'; - -class Nodes extends DataMap { - constructor(renderer, backend) { - super(); - - this.renderer = renderer; - this.backend = backend; - this.nodeFrame = new NodeFrame(); - this.nodeBuilderCache = new Map(); - this.callHashCache = new ChainMap(); - this.groupsData = new ChainMap(); - } - - updateGroup(nodeUniformsGroup) { - const groupNode = nodeUniformsGroup.groupNode; - const name = groupNode.name; - - // objectGroup is every updated - - if (name === objectGroup.name) return true; - - // renderGroup is updated once per render/compute call - - if (name === renderGroup.name) { - const uniformsGroupData = this.get(nodeUniformsGroup); - const renderId = this.nodeFrame.renderId; - - if (uniformsGroupData.renderId !== renderId) { - uniformsGroupData.renderId = renderId; - - return true; - } - - return false; - } - - // frameGroup is updated once per frame - - if (name === frameGroup.name) { - const uniformsGroupData = this.get(nodeUniformsGroup); - const frameId = this.nodeFrame.frameId; - - if (uniformsGroupData.frameId !== frameId) { - uniformsGroupData.frameId = frameId; - - return true; - } - - return false; - } - - // other groups are updated just when groupNode.needsUpdate is true - - const groupChain = [groupNode, nodeUniformsGroup]; - - let groupData = this.groupsData.get(groupChain); - if (groupData === undefined) this.groupsData.set(groupChain, (groupData = {})); - - if (groupData.version !== groupNode.version) { - groupData.version = groupNode.version; - - return true; - } - - return false; - } - - getForRenderCacheKey(renderObject) { - return renderObject.initialCacheKey; - } - - getForRender(renderObject) { - const renderObjectData = this.get(renderObject); - - let nodeBuilderState = renderObjectData.nodeBuilderState; - - if (nodeBuilderState === undefined) { - const { nodeBuilderCache } = this; - - const cacheKey = this.getForRenderCacheKey(renderObject); - - nodeBuilderState = nodeBuilderCache.get(cacheKey); - - if (nodeBuilderState === undefined) { - const nodeBuilder = this.backend.createNodeBuilder(renderObject.object, this.renderer); - nodeBuilder.scene = renderObject.scene; - nodeBuilder.material = renderObject.material; - nodeBuilder.camera = renderObject.camera; - nodeBuilder.context.material = renderObject.material; - nodeBuilder.lightsNode = renderObject.lightsNode; - nodeBuilder.environmentNode = this.getEnvironmentNode(renderObject.scene); - nodeBuilder.fogNode = this.getFogNode(renderObject.scene); - nodeBuilder.clippingContext = renderObject.clippingContext; - nodeBuilder.build(); - - nodeBuilderState = this._createNodeBuilderState(nodeBuilder); - - nodeBuilderCache.set(cacheKey, nodeBuilderState); - } - - nodeBuilderState.usedTimes++; - - renderObjectData.nodeBuilderState = nodeBuilderState; - } - - return nodeBuilderState; - } - - delete(object) { - if (object.isRenderObject) { - const nodeBuilderState = this.get(object).nodeBuilderState; - nodeBuilderState.usedTimes--; - - if (nodeBuilderState.usedTimes === 0) { - this.nodeBuilderCache.delete(this.getForRenderCacheKey(object)); - } - } - - return super.delete(object); - } - - getForCompute(computeNode) { - const computeData = this.get(computeNode); - - let nodeBuilderState = computeData.nodeBuilderState; - - if (nodeBuilderState === undefined) { - const nodeBuilder = this.backend.createNodeBuilder(computeNode, this.renderer); - nodeBuilder.build(); - - nodeBuilderState = this._createNodeBuilderState(nodeBuilder); - - computeData.nodeBuilderState = nodeBuilderState; - } - - return nodeBuilderState; - } - - _createNodeBuilderState(nodeBuilder) { - return new NodeBuilderState( - nodeBuilder.vertexShader, - nodeBuilder.fragmentShader, - nodeBuilder.computeShader, - nodeBuilder.getAttributesArray(), - nodeBuilder.getBindings(), - nodeBuilder.updateNodes, - nodeBuilder.updateBeforeNodes, - nodeBuilder.updateAfterNodes, - nodeBuilder.instanceBindGroups, - nodeBuilder.transforms, - ); - } - - getEnvironmentNode(scene) { - return scene.environmentNode || this.get(scene).environmentNode || null; - } - - getBackgroundNode(scene) { - return scene.backgroundNode || this.get(scene).backgroundNode || null; - } - - getFogNode(scene) { - return scene.fogNode || this.get(scene).fogNode || null; - } - - getCacheKey(scene, lightsNode) { - const chain = [scene, lightsNode]; - const callId = this.renderer.info.calls; - - let cacheKeyData = this.callHashCache.get(chain); - - if (cacheKeyData === undefined || cacheKeyData.callId !== callId) { - const environmentNode = this.getEnvironmentNode(scene); - const fogNode = this.getFogNode(scene); - - const cacheKey = []; - - if (lightsNode) cacheKey.push(lightsNode.getCacheKey()); - if (environmentNode) cacheKey.push(environmentNode.getCacheKey()); - if (fogNode) cacheKey.push(fogNode.getCacheKey()); - - cacheKeyData = { - callId, - cacheKey: cacheKey.join(','), - }; - - this.callHashCache.set(chain, cacheKeyData); - } - - return cacheKeyData.cacheKey; - } - - updateScene(scene) { - this.updateEnvironment(scene); - this.updateFog(scene); - this.updateBackground(scene); - } - - get isToneMappingState() { - return this.renderer.getRenderTarget() ? false : true; - } - - updateBackground(scene) { - const sceneData = this.get(scene); - const background = scene.background; - - if (background) { - if (sceneData.background !== background) { - let backgroundNode = null; - - if ( - background.isCubeTexture === true || - background.mapping === EquirectangularReflectionMapping || - background.mapping === EquirectangularRefractionMapping - ) { - backgroundNode = pmremTexture(background, normalWorld); - } else if (background.isTexture === true) { - backgroundNode = texture(background, viewportBottomLeft).setUpdateMatrix(true); - } else if (background.isColor !== true) { - console.error('WebGPUNodes: Unsupported background configuration.', background); - } - - sceneData.backgroundNode = backgroundNode; - sceneData.background = background; - } - } else if (sceneData.backgroundNode) { - delete sceneData.backgroundNode; - delete sceneData.background; - } - } - - updateFog(scene) { - const sceneData = this.get(scene); - const fog = scene.fog; - - if (fog) { - if (sceneData.fog !== fog) { - let fogNode = null; - - if (fog.isFogExp2) { - fogNode = densityFog(reference('color', 'color', fog), reference('density', 'float', fog)); - } else if (fog.isFog) { - fogNode = rangeFog( - reference('color', 'color', fog), - reference('near', 'float', fog), - reference('far', 'float', fog), - ); - } else { - console.error('WebGPUNodes: Unsupported fog configuration.', fog); - } - - sceneData.fogNode = fogNode; - sceneData.fog = fog; - } - } else { - delete sceneData.fogNode; - delete sceneData.fog; - } - } - - updateEnvironment(scene) { - const sceneData = this.get(scene); - const environment = scene.environment; - - if (environment) { - if (sceneData.environment !== environment) { - let environmentNode = null; - - if (environment.isCubeTexture === true) { - environmentNode = cubeTexture(environment); - } else if (environment.isTexture === true) { - environmentNode = texture(environment); - } else { - console.error('Nodes: Unsupported environment configuration.', environment); - } - - sceneData.environmentNode = environmentNode; - sceneData.environment = environment; - } - } else if (sceneData.environmentNode) { - delete sceneData.environmentNode; - delete sceneData.environment; - } - } - - getNodeFrame(renderer = this.renderer, scene = null, object = null, camera = null, material = null) { - const nodeFrame = this.nodeFrame; - nodeFrame.renderer = renderer; - nodeFrame.scene = scene; - nodeFrame.object = object; - nodeFrame.camera = camera; - nodeFrame.material = material; - - return nodeFrame; - } - - getNodeFrameForRender(renderObject) { - return this.getNodeFrame( - renderObject.renderer, - renderObject.scene, - renderObject.object, - renderObject.camera, - renderObject.material, - ); - } - - getOutputNode(outputTexture) { - let output = texture(outputTexture, viewportTopLeft); - - if (this.isToneMappingState) { - if (this.renderer.toneMappingNode) { - output = vec4(this.renderer.toneMappingNode.context({ color: output.rgb }), output.a); - } else if (this.renderer.toneMapping !== NoToneMapping) { - output = output.toneMapping(this.renderer.toneMapping); - } - } - - if (this.renderer.currentColorSpace === SRGBColorSpace) { - output = output.linearToColorSpace(this.renderer.currentColorSpace); - } - - return output; - } - - updateBefore(renderObject) { - const nodeFrame = this.getNodeFrameForRender(renderObject); - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateBeforeNodes) { - nodeFrame.updateBeforeNode(node); - } - } - - updateAfter(renderObject) { - const nodeFrame = this.getNodeFrameForRender(renderObject); - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateAfterNodes) { - nodeFrame.updateAfterNode(node); - } - } - - updateForCompute(computeNode) { - const nodeFrame = this.getNodeFrame(); - const nodeBuilder = this.getForCompute(computeNode); - - for (const node of nodeBuilder.updateNodes) { - nodeFrame.updateNode(node); - } - } - - updateForRender(renderObject) { - const nodeFrame = this.getNodeFrameForRender(renderObject); - const nodeBuilder = renderObject.getNodeBuilderState(); - - for (const node of nodeBuilder.updateNodes) { - nodeFrame.updateNode(node); - } - } - - dispose() { - super.dispose(); - - this.nodeFrame = new NodeFrame(); - this.nodeBuilderCache = new Map(); - } -} - -export default Nodes; diff --git a/examples-jsm/examples/renderers/webgl/WebGLBackend.ts b/examples-jsm/examples/renderers/webgl/WebGLBackend.ts deleted file mode 100644 index f32af4344..000000000 --- a/examples-jsm/examples/renderers/webgl/WebGLBackend.ts +++ /dev/null @@ -1,1268 +0,0 @@ -import { WebGLCoordinateSystem } from 'three'; - -import GLSLNodeBuilder from './nodes/GLSLNodeBuilder.js'; -import Backend from '../common/Backend.js'; - -import WebGLAttributeUtils from './utils/WebGLAttributeUtils.js'; -import WebGLState from './utils/WebGLState.js'; -import WebGLUtils from './utils/WebGLUtils.js'; -import WebGLTextureUtils from './utils/WebGLTextureUtils.js'; -import WebGLExtensions from './utils/WebGLExtensions.js'; -import WebGLCapabilities from './utils/WebGLCapabilities.js'; -import { GLFeatureName } from './utils/WebGLConstants.js'; -import { WebGLBufferRenderer } from './WebGLBufferRenderer.js'; - -// - -class WebGLBackend extends Backend { - constructor(parameters = {}) { - super(parameters); - - this.isWebGLBackend = true; - } - - init(renderer) { - super.init(renderer); - - // - - const parameters = this.parameters; - - const glContext = - parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgl2'); - - this.gl = glContext; - - this.extensions = new WebGLExtensions(this); - this.capabilities = new WebGLCapabilities(this); - this.attributeUtils = new WebGLAttributeUtils(this); - this.textureUtils = new WebGLTextureUtils(this); - this.bufferRenderer = new WebGLBufferRenderer(this); - - this.state = new WebGLState(this); - this.utils = new WebGLUtils(this); - - this.vaoCache = {}; - this.transformFeedbackCache = {}; - this.discard = false; - this.trackTimestamp = parameters.trackTimestamp === true; - - this.extensions.get('EXT_color_buffer_float'); - this.disjoint = this.extensions.get('EXT_disjoint_timer_query_webgl2'); - this.parallel = this.extensions.get('KHR_parallel_shader_compile'); - this._currentContext = null; - } - - get coordinateSystem() { - return WebGLCoordinateSystem; - } - - async getArrayBufferAsync(attribute) { - return await this.attributeUtils.getArrayBufferAsync(attribute); - } - - initTimestampQuery(renderContext) { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (this.queryRunning) { - if (!renderContextData.queryQueue) renderContextData.queryQueue = []; - renderContextData.queryQueue.push(renderContext); - return; - } - - if (renderContextData.activeQuery) { - this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); - renderContextData.activeQuery = null; - } - - renderContextData.activeQuery = this.gl.createQuery(); - - if (renderContextData.activeQuery !== null) { - this.gl.beginQuery(this.disjoint.TIME_ELAPSED_EXT, renderContextData.activeQuery); - this.queryRunning = true; - } - } - - // timestamp utils - - prepareTimestampBuffer(renderContext) { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (renderContextData.activeQuery) { - this.gl.endQuery(this.disjoint.TIME_ELAPSED_EXT); - - if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; - renderContextData.gpuQueries.push({ query: renderContextData.activeQuery }); - renderContextData.activeQuery = null; - this.queryRunning = false; - - if (renderContextData.queryQueue && renderContextData.queryQueue.length > 0) { - const nextRenderContext = renderContextData.queryQueue.shift(); - this.initTimestampQuery(nextRenderContext); - } - } - } - - async resolveTimestampAsync(renderContext, type = 'render') { - if (!this.disjoint || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (!renderContextData.gpuQueries) renderContextData.gpuQueries = []; - - for (let i = 0; i < renderContextData.gpuQueries.length; i++) { - const queryInfo = renderContextData.gpuQueries[i]; - const available = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT_AVAILABLE); - const disjoint = this.gl.getParameter(this.disjoint.GPU_DISJOINT_EXT); - - if (available && !disjoint) { - const elapsed = this.gl.getQueryParameter(queryInfo.query, this.gl.QUERY_RESULT); - const duration = Number(elapsed) / 1000000; // Convert nanoseconds to milliseconds - this.gl.deleteQuery(queryInfo.query); - renderContextData.gpuQueries.splice(i, 1); // Remove the processed query - i--; - this.renderer.info.updateTimestamp(type, duration); - } - } - } - - getContext() { - return this.gl; - } - - beginRender(renderContext) { - const { gl } = this; - const renderContextData = this.get(renderContext); - - // - - // - - this.initTimestampQuery(renderContext); - - renderContextData.previousContext = this._currentContext; - this._currentContext = renderContext; - - this._setFramebuffer(renderContext); - - this.clear( - renderContext.clearColor, - renderContext.clearDepth, - renderContext.clearStencil, - renderContext, - false, - ); - - // - if (renderContext.viewport) { - this.updateViewport(renderContext); - } else { - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - } - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - gl.scissor(x, y, width, height); - } - - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (occlusionQueryCount > 0) { - // Get a reference to the array of objects with queries. The renderContextData property - // can be changed by another render pass before the async reading of all previous queries complete - renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries; - renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; - - renderContextData.lastOcclusionObject = null; - renderContextData.occlusionQueries = new Array(occlusionQueryCount); - renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); - renderContextData.occlusionQueryIndex = 0; - } - } - - finishRender(renderContext) { - const { gl, state } = this; - const renderContextData = this.get(renderContext); - const previousContext = renderContextData.previousContext; - - const textures = renderContext.textures; - - if (textures !== null) { - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (texture.generateMipmaps) { - this.generateMipmaps(texture); - } - } - } - - this._currentContext = previousContext; - - if (renderContext.textures !== null && renderContext.renderTarget) { - const renderTargetContextData = this.get(renderContext.renderTarget); - - const { samples } = renderContext.renderTarget; - const fb = renderTargetContextData.framebuffer; - - const mask = gl.COLOR_BUFFER_BIT; - - if (samples > 0) { - const msaaFrameBuffer = renderTargetContextData.msaaFrameBuffer; - - const textures = renderContext.textures; - - state.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFrameBuffer); - state.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fb); - - for (let i = 0; i < textures.length; i++) { - // TODO Add support for MRT - - gl.blitFramebuffer( - 0, - 0, - renderContext.width, - renderContext.height, - 0, - 0, - renderContext.width, - renderContext.height, - mask, - gl.NEAREST, - ); - - gl.invalidateFramebuffer(gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray); - } - } - } - - if (previousContext !== null) { - this._setFramebuffer(previousContext); - - if (previousContext.viewport) { - this.updateViewport(previousContext); - } else { - const gl = this.gl; - - gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); - } - } - - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (occlusionQueryCount > 0) { - const renderContextData = this.get(renderContext); - - if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { - const { gl } = this; - - gl.endQuery(gl.ANY_SAMPLES_PASSED); - } - - this.resolveOccludedAsync(renderContext); - } - - this.prepareTimestampBuffer(renderContext); - } - - resolveOccludedAsync(renderContext) { - const renderContextData = this.get(renderContext); - - // handle occlusion query results - - const { currentOcclusionQueries, currentOcclusionQueryObjects } = renderContextData; - - if (currentOcclusionQueries && currentOcclusionQueryObjects) { - const occluded = new WeakSet(); - const { gl } = this; - - renderContextData.currentOcclusionQueryObjects = null; - renderContextData.currentOcclusionQueries = null; - - const check = () => { - let completed = 0; - - // check all queries and requeue as appropriate - for (let i = 0; i < currentOcclusionQueries.length; i++) { - const query = currentOcclusionQueries[i]; - - if (query === null) continue; - - if (gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE)) { - if (gl.getQueryParameter(query, gl.QUERY_RESULT) > 0) - occluded.add(currentOcclusionQueryObjects[i]); - - currentOcclusionQueries[i] = null; - gl.deleteQuery(query); - - completed++; - } - } - - if (completed < currentOcclusionQueries.length) { - requestAnimationFrame(check); - } else { - renderContextData.occluded = occluded; - } - }; - - check(); - } - } - - isOccluded(renderContext, object) { - const renderContextData = this.get(renderContext); - - return renderContextData.occluded && renderContextData.occluded.has(object); - } - - updateViewport(renderContext) { - const gl = this.gl; - const { x, y, width, height } = renderContext.viewportValue; - - gl.viewport(x, y, width, height); - } - - setScissorTest(boolean) { - const gl = this.gl; - - if (boolean) { - gl.enable(gl.SCISSOR_TEST); - } else { - gl.disable(gl.SCISSOR_TEST); - } - } - - clear(color, depth, stencil, descriptor = null, setFrameBuffer = true) { - const { gl } = this; - - if (descriptor === null) { - descriptor = { - textures: null, - clearColorValue: this.getClearColor(), - }; - } - - // - - let clear = 0; - - if (color) clear |= gl.COLOR_BUFFER_BIT; - if (depth) clear |= gl.DEPTH_BUFFER_BIT; - if (stencil) clear |= gl.STENCIL_BUFFER_BIT; - - if (clear !== 0) { - const clearColor = descriptor.clearColorValue || this.getClearColor(); - - if (depth) this.state.setDepthMask(true); - - if (descriptor.textures === null) { - gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); - gl.clear(clear); - } else { - if (setFrameBuffer) this._setFramebuffer(descriptor); - - if (color) { - for (let i = 0; i < descriptor.textures.length; i++) { - gl.clearBufferfv(gl.COLOR, i, [clearColor.r, clearColor.g, clearColor.b, clearColor.a]); - } - } - - if (depth && stencil) { - gl.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0); - } else if (depth) { - gl.clearBufferfv(gl.DEPTH, 0, [1.0]); - } else if (stencil) { - gl.clearBufferiv(gl.STENCIL, 0, [0]); - } - } - } - } - - beginCompute(computeGroup) { - const gl = this.gl; - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - this.initTimestampQuery(computeGroup); - } - - compute(computeGroup, computeNode, bindings, pipeline) { - const gl = this.gl; - - if (!this.discard) { - // required here to handle async behaviour of render.compute() - gl.enable(gl.RASTERIZER_DISCARD); - this.discard = true; - } - - const { programGPU, transformBuffers, attributes } = this.get(pipeline); - - const vaoKey = this._getVaoKey(null, attributes); - - const vaoGPU = this.vaoCache[vaoKey]; - - if (vaoGPU === undefined) { - this._createVao(null, attributes); - } else { - gl.bindVertexArray(vaoGPU); - } - - gl.useProgram(programGPU); - - this._bindUniforms(bindings); - - const transformFeedbackGPU = this._getTransformFeedback(transformBuffers); - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); - gl.beginTransformFeedback(gl.POINTS); - - if (attributes[0].isStorageInstancedBufferAttribute) { - gl.drawArraysInstanced(gl.POINTS, 0, 1, computeNode.count); - } else { - gl.drawArrays(gl.POINTS, 0, computeNode.count); - } - - gl.endTransformFeedback(); - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); - - // switch active buffers - - for (let i = 0; i < transformBuffers.length; i++) { - const dualAttributeData = transformBuffers[i]; - - if (dualAttributeData.pbo) { - this.textureUtils.copyBufferToTexture(dualAttributeData.transformBuffer, dualAttributeData.pbo); - } - - dualAttributeData.switchBuffers(); - } - } - - finishCompute(computeGroup) { - const gl = this.gl; - - this.discard = false; - - gl.disable(gl.RASTERIZER_DISCARD); - - this.prepareTimestampBuffer(computeGroup); - } - - draw(renderObject /*, info*/) { - const { object, pipeline, material, context } = renderObject; - const { programGPU } = this.get(pipeline); - - const { gl, state } = this; - - const contextData = this.get(context); - - // - - this._bindUniforms(renderObject.getBindings()); - - const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0; - - state.setMaterial(material, frontFaceCW); - - gl.useProgram(programGPU); - - // - - let vaoGPU = renderObject.staticVao; - - if (vaoGPU === undefined) { - const vaoKey = this._getVaoKey(renderObject.getIndex(), renderObject.getAttributes()); - - vaoGPU = this.vaoCache[vaoKey]; - - if (vaoGPU === undefined) { - let staticVao; - - ({ vaoGPU, staticVao } = this._createVao(renderObject.getIndex(), renderObject.getAttributes())); - - if (staticVao) renderObject.staticVao = vaoGPU; - } - } - - gl.bindVertexArray(vaoGPU); - - // - - const index = renderObject.getIndex(); - - const geometry = renderObject.geometry; - const drawRange = renderObject.drawRange; - const firstVertex = drawRange.start; - - // - - const lastObject = contextData.lastOcclusionObject; - - if (lastObject !== object && lastObject !== undefined) { - if (lastObject !== null && lastObject.occlusionTest === true) { - gl.endQuery(gl.ANY_SAMPLES_PASSED); - - contextData.occlusionQueryIndex++; - } - - if (object.occlusionTest === true) { - const query = gl.createQuery(); - - gl.beginQuery(gl.ANY_SAMPLES_PASSED, query); - - contextData.occlusionQueries[contextData.occlusionQueryIndex] = query; - contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; - } - - contextData.lastOcclusionObject = object; - } - - // - - const renderer = this.bufferRenderer; - - if (object.isPoints) renderer.mode = gl.POINTS; - else if (object.isLineSegments) renderer.mode = gl.LINES; - else if (object.isLine) renderer.mode = gl.LINE_STRIP; - else if (object.isLineLoop) renderer.mode = gl.LINE_LOOP; - else { - if (material.wireframe === true) { - state.setLineWidth(material.wireframeLinewidth * this.renderer.getPixelRatio()); - renderer.mode = gl.LINES; - } else { - renderer.mode = gl.TRIANGLES; - } - } - - // - - let count; - - renderer.object = object; - - if (index !== null) { - const indexData = this.get(index); - const indexCount = drawRange.count !== Infinity ? drawRange.count : index.count; - - renderer.index = index.count; - renderer.type = indexData.type; - - count = indexCount; - } else { - renderer.index = 0; - - const vertexCount = drawRange.count !== Infinity ? drawRange.count : geometry.attributes.position.count; - - count = vertexCount; - } - - const instanceCount = this.getInstanceCount(renderObject); - - if (object.isBatchedMesh) { - if (object._multiDrawInstances !== null) { - renderer.renderMultiDrawInstances( - object._multiDrawStarts, - object._multiDrawCounts, - object._multiDrawCount, - object._multiDrawInstances, - ); - } else { - renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount); - } - } else if (instanceCount > 1) { - renderer.renderInstances(firstVertex, count, instanceCount); - } else { - renderer.render(firstVertex, count); - } - // - - gl.bindVertexArray(null); - } - - needsRenderUpdate(/*renderObject*/) { - return false; - } - - getRenderCacheKey(renderObject) { - return renderObject.id; - } - - // textures - - createDefaultTexture(texture) { - this.textureUtils.createDefaultTexture(texture); - } - - createTexture(texture, options) { - this.textureUtils.createTexture(texture, options); - } - - updateTexture(texture, options) { - this.textureUtils.updateTexture(texture, options); - } - - generateMipmaps(texture) { - this.textureUtils.generateMipmaps(texture); - } - - destroyTexture(texture) { - this.textureUtils.destroyTexture(texture); - } - - copyTextureToBuffer(texture, x, y, width, height) { - return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height); - } - - createSampler(/*texture*/) { - //console.warn( 'Abstract class.' ); - } - - destroySampler() {} - - // node builder - - createNodeBuilder(object, renderer) { - return new GLSLNodeBuilder(object, renderer); - } - - // program - - createProgram(program) { - const gl = this.gl; - const { stage, code } = program; - - const shader = stage === 'fragment' ? gl.createShader(gl.FRAGMENT_SHADER) : gl.createShader(gl.VERTEX_SHADER); - - gl.shaderSource(shader, code); - gl.compileShader(shader); - - this.set(program, { - shaderGPU: shader, - }); - } - - destroyProgram(/*program*/) { - console.warn('Abstract class.'); - } - - createRenderPipeline(renderObject, promises) { - const gl = this.gl; - const pipeline = renderObject.pipeline; - - // Program - - const { fragmentProgram, vertexProgram } = pipeline; - - const programGPU = gl.createProgram(); - - const fragmentShader = this.get(fragmentProgram).shaderGPU; - const vertexShader = this.get(vertexProgram).shaderGPU; - - gl.attachShader(programGPU, fragmentShader); - gl.attachShader(programGPU, vertexShader); - gl.linkProgram(programGPU); - - this.set(pipeline, { - programGPU, - fragmentShader, - vertexShader, - }); - - if (promises !== null && this.parallel) { - const p = new Promise((resolve /*, reject*/) => { - const parallel = this.parallel; - const checkStatus = () => { - if (gl.getProgramParameter(programGPU, parallel.COMPLETION_STATUS_KHR)) { - this._completeCompile(renderObject, pipeline); - resolve(); - } else { - requestAnimationFrame(checkStatus); - } - }; - - checkStatus(); - }); - - promises.push(p); - - return; - } - - this._completeCompile(renderObject, pipeline); - } - - _handleSource(string, errorLine) { - const lines = string.split('\n'); - const lines2 = []; - - const from = Math.max(errorLine - 6, 0); - const to = Math.min(errorLine + 6, lines.length); - - for (let i = from; i < to; i++) { - const line = i + 1; - lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`); - } - - return lines2.join('\n'); - } - - _getShaderErrors(gl, shader, type) { - const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS); - const errors = gl.getShaderInfoLog(shader).trim(); - - if (status && errors === '') return ''; - - const errorMatches = /ERROR: 0:(\d+)/.exec(errors); - if (errorMatches) { - const errorLine = parseInt(errorMatches[1]); - return ( - type.toUpperCase() + - '\n\n' + - errors + - '\n\n' + - this._handleSource(gl.getShaderSource(shader), errorLine) - ); - } else { - return errors; - } - } - - _logProgramError(programGPU, glFragmentShader, glVertexShader) { - if (this.renderer.debug.checkShaderErrors) { - const gl = this.gl; - - const programLog = gl.getProgramInfoLog(programGPU).trim(); - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - if (typeof this.renderer.debug.onShaderError === 'function') { - this.renderer.debug.onShaderError(gl, programGPU, glVertexShader, glFragmentShader); - } else { - // default error reporting - - const vertexErrors = this._getShaderErrors(gl, glVertexShader, 'vertex'); - const fragmentErrors = this._getShaderErrors(gl, glFragmentShader, 'fragment'); - - console.error( - 'THREE.WebGLProgram: Shader Error ' + - gl.getError() + - ' - ' + - 'VALIDATE_STATUS ' + - gl.getProgramParameter(programGPU, gl.VALIDATE_STATUS) + - '\n\n' + - 'Program Info Log: ' + - programLog + - '\n' + - vertexErrors + - '\n' + - fragmentErrors, - ); - } - } else if (programLog !== '') { - console.warn('THREE.WebGLProgram: Program Info Log:', programLog); - } - } - } - - _completeCompile(renderObject, pipeline) { - const gl = this.gl; - const pipelineData = this.get(pipeline); - const { programGPU, fragmentShader, vertexShader } = pipelineData; - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - this._logProgramError(programGPU, fragmentShader, vertexShader); - } - - gl.useProgram(programGPU); - - // Bindings - - const bindings = renderObject.getBindings(); - - this._setupBindings(bindings, programGPU); - - // - - this.set(pipeline, { - programGPU, - }); - } - - createComputePipeline(computePipeline, bindings) { - const gl = this.gl; - - // Program - - const fragmentProgram = { - stage: 'fragment', - code: '#version 300 es\nprecision highp float;\nvoid main() {}', - }; - - this.createProgram(fragmentProgram); - - const { computeProgram } = computePipeline; - - const programGPU = gl.createProgram(); - - const fragmentShader = this.get(fragmentProgram).shaderGPU; - const vertexShader = this.get(computeProgram).shaderGPU; - - const transforms = computeProgram.transforms; - - const transformVaryingNames = []; - const transformAttributeNodes = []; - - for (let i = 0; i < transforms.length; i++) { - const transform = transforms[i]; - - transformVaryingNames.push(transform.varyingName); - transformAttributeNodes.push(transform.attributeNode); - } - - gl.attachShader(programGPU, fragmentShader); - gl.attachShader(programGPU, vertexShader); - - gl.transformFeedbackVaryings(programGPU, transformVaryingNames, gl.SEPARATE_ATTRIBS); - - gl.linkProgram(programGPU); - - if (gl.getProgramParameter(programGPU, gl.LINK_STATUS) === false) { - this._logProgramError(programGPU, fragmentShader, vertexShader); - } - - gl.useProgram(programGPU); - - // Bindings - - this.createBindings(null, bindings); - - this._setupBindings(bindings, programGPU); - - const attributeNodes = computeProgram.attributes; - const attributes = []; - const transformBuffers = []; - - for (let i = 0; i < attributeNodes.length; i++) { - const attribute = attributeNodes[i].node.attribute; - - attributes.push(attribute); - - if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - for (let i = 0; i < transformAttributeNodes.length; i++) { - const attribute = transformAttributeNodes[i].attribute; - - if (!this.has(attribute)) this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - - const attributeData = this.get(attribute); - - transformBuffers.push(attributeData); - } - - // - - this.set(computePipeline, { - programGPU, - transformBuffers, - attributes, - }); - } - - createBindings(bindGroup, bindings) { - this.updateBindings(bindGroup, bindings); - } - - updateBindings(bindGroup, bindings) { - const { gl } = this; - - let groupIndex = 0; - let textureIndex = 0; - - for (const bindGroup of bindings) { - for (const binding of bindGroup.bindings) { - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const bufferGPU = gl.createBuffer(); - const data = binding.buffer; - - gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); - gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); - gl.bindBufferBase(gl.UNIFORM_BUFFER, groupIndex, bufferGPU); - - this.set(binding, { - index: groupIndex++, - bufferGPU, - }); - } else if (binding.isSampledTexture) { - const { textureGPU, glTextureType } = this.get(binding.texture); - - this.set(binding, { - index: textureIndex++, - textureGPU, - glTextureType, - }); - } - } - } - } - - updateBinding(binding) { - const gl = this.gl; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const bindingData = this.get(binding); - const bufferGPU = bindingData.bufferGPU; - const data = binding.buffer; - - gl.bindBuffer(gl.UNIFORM_BUFFER, bufferGPU); - gl.bufferData(gl.UNIFORM_BUFFER, data, gl.DYNAMIC_DRAW); - } - } - - // attributes - - createIndexAttribute(attribute) { - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ELEMENT_ARRAY_BUFFER); - } - - createAttribute(attribute) { - if (this.has(attribute)) return; - - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - createStorageAttribute(attribute) { - if (this.has(attribute)) return; - - const gl = this.gl; - - this.attributeUtils.createAttribute(attribute, gl.ARRAY_BUFFER); - } - - updateAttribute(attribute) { - this.attributeUtils.updateAttribute(attribute); - } - - destroyAttribute(attribute) { - this.attributeUtils.destroyAttribute(attribute); - } - - updateSize() { - //console.warn( 'Abstract class.' ); - } - - hasFeature(name) { - const keysMatching = Object.keys(GLFeatureName).filter(key => GLFeatureName[key] === name); - - const extensions = this.extensions; - - for (let i = 0; i < keysMatching.length; i++) { - if (extensions.has(keysMatching[i])) return true; - } - - return false; - } - - getMaxAnisotropy() { - return this.capabilities.getMaxAnisotropy(); - } - - copyTextureToTexture(position, srcTexture, dstTexture, level) { - this.textureUtils.copyTextureToTexture(position, srcTexture, dstTexture, level); - } - - copyFramebufferToTexture(texture, renderContext) { - this.textureUtils.copyFramebufferToTexture(texture, renderContext); - } - - _setFramebuffer(renderContext) { - const { gl, state } = this; - - let currentFrameBuffer = null; - - if (renderContext.textures !== null) { - const renderTarget = renderContext.renderTarget; - const renderTargetContextData = this.get(renderTarget); - const { samples, depthBuffer, stencilBuffer } = renderTarget; - const cubeFace = this.renderer._activeCubeFace; - const isCube = renderTarget.isWebGLCubeRenderTarget === true; - - let msaaFb = renderTargetContextData.msaaFrameBuffer; - let depthRenderbuffer = renderTargetContextData.depthRenderbuffer; - - let fb; - - if (isCube) { - if (renderTargetContextData.cubeFramebuffers === undefined) { - renderTargetContextData.cubeFramebuffers = []; - } - - fb = renderTargetContextData.cubeFramebuffers[cubeFace]; - } else { - fb = renderTargetContextData.framebuffer; - } - - if (fb === undefined) { - fb = gl.createFramebuffer(); - - state.bindFramebuffer(gl.FRAMEBUFFER, fb); - - const textures = renderContext.textures; - - if (isCube) { - renderTargetContextData.cubeFramebuffers[cubeFace] = fb; - const { textureGPU } = this.get(textures[0]); - - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_CUBE_MAP_POSITIVE_X + cubeFace, - textureGPU, - 0, - ); - } else { - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - const textureData = this.get(texture); - textureData.renderTarget = renderContext.renderTarget; - - const attachment = gl.COLOR_ATTACHMENT0 + i; - - gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0); - } - - renderTargetContextData.framebuffer = fb; - - state.drawBuffers(renderContext, fb); - } - - if (renderContext.depthTexture !== null) { - const textureData = this.get(renderContext.depthTexture); - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - - gl.framebufferTexture2D(gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0); - } - } - - if (samples > 0) { - if (msaaFb === undefined) { - const invalidationArray = []; - - msaaFb = gl.createFramebuffer(); - - state.bindFramebuffer(gl.FRAMEBUFFER, msaaFb); - - const msaaRenderbuffers = []; - - const textures = renderContext.textures; - - for (let i = 0; i < textures.length; i++) { - msaaRenderbuffers[i] = gl.createRenderbuffer(); - - gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRenderbuffers[i]); - - invalidationArray.push(gl.COLOR_ATTACHMENT0 + i); - - if (depthBuffer) { - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - invalidationArray.push(depthStyle); - } - - const texture = renderContext.textures[i]; - const textureData = this.get(texture); - - gl.renderbufferStorageMultisample( - gl.RENDERBUFFER, - samples, - textureData.glInternalFormat, - renderContext.width, - renderContext.height, - ); - gl.framebufferRenderbuffer( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0 + i, - gl.RENDERBUFFER, - msaaRenderbuffers[i], - ); - } - - renderTargetContextData.msaaFrameBuffer = msaaFb; - renderTargetContextData.msaaRenderbuffers = msaaRenderbuffers; - - if (depthRenderbuffer === undefined) { - depthRenderbuffer = gl.createRenderbuffer(); - this.textureUtils.setupRenderBufferStorage(depthRenderbuffer, renderContext); - - renderTargetContextData.depthRenderbuffer = depthRenderbuffer; - - const depthStyle = stencilBuffer ? gl.DEPTH_STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT; - invalidationArray.push(depthStyle); - } - - renderTargetContextData.invalidationArray = invalidationArray; - } - - currentFrameBuffer = renderTargetContextData.msaaFrameBuffer; - } else { - currentFrameBuffer = fb; - } - } - - state.bindFramebuffer(gl.FRAMEBUFFER, currentFrameBuffer); - } - - _getVaoKey(index, attributes) { - let key = []; - - if (index !== null) { - const indexData = this.get(index); - - key += ':' + indexData.id; - } - - for (let i = 0; i < attributes.length; i++) { - const attributeData = this.get(attributes[i]); - - key += ':' + attributeData.id; - } - - return key; - } - - _createVao(index, attributes) { - const { gl } = this; - - const vaoGPU = gl.createVertexArray(); - let key = ''; - - let staticVao = true; - - gl.bindVertexArray(vaoGPU); - - if (index !== null) { - const indexData = this.get(index); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexData.bufferGPU); - - key += ':' + indexData.id; - } - - for (let i = 0; i < attributes.length; i++) { - const attribute = attributes[i]; - const attributeData = this.get(attribute); - - key += ':' + attributeData.id; - - gl.bindBuffer(gl.ARRAY_BUFFER, attributeData.bufferGPU); - gl.enableVertexAttribArray(i); - - if (attribute.isStorageBufferAttribute || attribute.isStorageInstancedBufferAttribute) staticVao = false; - - let stride, offset; - - if (attribute.isInterleavedBufferAttribute === true) { - stride = attribute.data.stride * attributeData.bytesPerElement; - offset = attribute.offset * attributeData.bytesPerElement; - } else { - stride = 0; - offset = 0; - } - - if (attributeData.isInteger) { - gl.vertexAttribIPointer(i, attribute.itemSize, attributeData.type, stride, offset); - } else { - gl.vertexAttribPointer(i, attribute.itemSize, attributeData.type, attribute.normalized, stride, offset); - } - - if (attribute.isInstancedBufferAttribute && !attribute.isInterleavedBufferAttribute) { - gl.vertexAttribDivisor(i, attribute.meshPerAttribute); - } else if (attribute.isInterleavedBufferAttribute && attribute.data.isInstancedInterleavedBuffer) { - gl.vertexAttribDivisor(i, attribute.data.meshPerAttribute); - } - } - - gl.bindBuffer(gl.ARRAY_BUFFER, null); - - this.vaoCache[key] = vaoGPU; - - return { vaoGPU, staticVao }; - } - - _getTransformFeedback(transformBuffers) { - let key = ''; - - for (let i = 0; i < transformBuffers.length; i++) { - key += ':' + transformBuffers[i].id; - } - - let transformFeedbackGPU = this.transformFeedbackCache[key]; - - if (transformFeedbackGPU !== undefined) { - return transformFeedbackGPU; - } - - const gl = this.gl; - - transformFeedbackGPU = gl.createTransformFeedback(); - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackGPU); - - for (let i = 0; i < transformBuffers.length; i++) { - const attributeData = transformBuffers[i]; - - gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, i, attributeData.transformBuffer); - } - - gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null); - - this.transformFeedbackCache[key] = transformFeedbackGPU; - - return transformFeedbackGPU; - } - - _setupBindings(bindings, programGPU) { - const gl = this.gl; - - for (const bindGroup of bindings) { - for (const binding of bindGroup.bindings) { - const bindingData = this.get(binding); - const index = bindingData.index; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - const location = gl.getUniformBlockIndex(programGPU, binding.name); - gl.uniformBlockBinding(programGPU, location, index); - } else if (binding.isSampledTexture) { - const location = gl.getUniformLocation(programGPU, binding.name); - gl.uniform1i(location, index); - } - } - } - } - - _bindUniforms(bindings) { - const { gl, state } = this; - - for (const bindGroup of bindings) { - for (const binding of bindGroup.bindings) { - const bindingData = this.get(binding); - const index = bindingData.index; - - if (binding.isUniformsGroup || binding.isUniformBuffer) { - gl.bindBufferBase(gl.UNIFORM_BUFFER, index, bindingData.bufferGPU); - } else if (binding.isSampledTexture) { - state.bindTexture(bindingData.glTextureType, bindingData.textureGPU, gl.TEXTURE0 + index); - } - } - } - } -} - -export default WebGLBackend; diff --git a/examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts b/examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts deleted file mode 100644 index 816b83eaf..000000000 --- a/examples-jsm/examples/renderers/webgl/nodes/GLSLNodeBuilder.ts +++ /dev/null @@ -1,747 +0,0 @@ -import { MathNode, GLSLNodeParser, NodeBuilder, TextureNode, vectorComponents } from '../../../nodes/Nodes.js'; - -import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; -import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; - -import { - NodeSampledTexture, - NodeSampledCubeTexture, - NodeSampledTexture3D, -} from '../../common/nodes/NodeSampledTexture.js'; - -import { - ByteType, - ShortType, - RGBAIntegerFormat, - RGBIntegerFormat, - RedIntegerFormat, - RGIntegerFormat, - UnsignedByteType, - UnsignedIntType, - UnsignedShortType, - RedFormat, - RGFormat, - IntType, - DataTexture, - RGBFormat, - RGBAFormat, - FloatType, -} from 'three'; - -const glslMethods = { - [MathNode.ATAN2]: 'atan', - textureDimensions: 'textureSize', - equals: 'equal', -}; - -const precisionLib = { - low: 'lowp', - medium: 'mediump', - high: 'highp', -}; - -const supports = { - swizzleAssign: true, - storageBuffer: false, -}; - -const defaultPrecisions = ` -precision highp float; -precision highp int; -precision highp sampler2D; -precision highp sampler3D; -precision highp samplerCube; -precision highp sampler2DArray; - -precision highp usampler2D; -precision highp usampler3D; -precision highp usamplerCube; -precision highp usampler2DArray; - -precision highp isampler2D; -precision highp isampler3D; -precision highp isamplerCube; -precision highp isampler2DArray; - -precision lowp sampler2DShadow; -`; - -class GLSLNodeBuilder extends NodeBuilder { - constructor(object, renderer) { - super(object, renderer, new GLSLNodeParser()); - - this.uniformGroups = {}; - this.transforms = []; - - this.instanceBindGroups = false; - } - - getMethod(method) { - return glslMethods[method] || method; - } - - getOutputStructName() { - return ''; - } - - buildFunctionCode(shaderNode) { - const layout = shaderNode.layout; - const flowData = this.flowShaderNode(shaderNode); - - const parameters = []; - - for (const input of layout.inputs) { - parameters.push(this.getType(input.type) + ' ' + input.name); - } - - // - - const code = `${this.getType(layout.type)} ${layout.name}( ${parameters.join(', ')} ) { - - ${flowData.vars} - -${flowData.code} - return ${flowData.result}; - -}`; - - // - - return code; - } - - setupPBO(storageBufferNode) { - const attribute = storageBufferNode.value; - - if (attribute.pbo === undefined) { - const originalArray = attribute.array; - const numElements = attribute.count * attribute.itemSize; - - const { itemSize } = attribute; - - const isInteger = attribute.array.constructor.name.toLowerCase().includes('int'); - - let format = isInteger ? RedIntegerFormat : RedFormat; - - if (itemSize === 2) { - format = isInteger ? RGIntegerFormat : RGFormat; - } else if (itemSize === 3) { - format = isInteger ? RGBIntegerFormat : RGBFormat; - } else if (itemSize === 4) { - format = isInteger ? RGBAIntegerFormat : RGBAFormat; - } - - const typeMap = { - Float32Array: FloatType, - Uint8Array: UnsignedByteType, - Uint16Array: UnsignedShortType, - Uint32Array: UnsignedIntType, - Int8Array: ByteType, - Int16Array: ShortType, - Int32Array: IntType, - Uint8ClampedArray: UnsignedByteType, - }; - - const width = Math.pow(2, Math.ceil(Math.log2(Math.sqrt(numElements / itemSize)))); - let height = Math.ceil(numElements / itemSize / width); - if (width * height * itemSize < numElements) height++; // Ensure enough space - - const newSize = width * height * itemSize; - - const newArray = new originalArray.constructor(newSize); - - newArray.set(originalArray, 0); - - attribute.array = newArray; - - const pboTexture = new DataTexture( - attribute.array, - width, - height, - format, - typeMap[attribute.array.constructor.name] || FloatType, - ); - pboTexture.needsUpdate = true; - pboTexture.isPBOTexture = true; - - const pbo = new TextureNode(pboTexture); - pbo.setPrecision('high'); - - attribute.pboNode = pbo; - attribute.pbo = pbo.value; - - this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); - } - } - - getPropertyName(node, shaderStage = this.shaderStage) { - if (node.isNodeUniform && node.node.isTextureNode !== true && node.node.isBufferNode !== true) { - return shaderStage.charAt(0) + '_' + node.name; - } - - return super.getPropertyName(node, shaderStage); - } - - generatePBO(storageArrayElementNode) { - const { node, indexNode } = storageArrayElementNode; - const attribute = node.value; - - if (this.renderer.backend.has(attribute)) { - const attributeData = this.renderer.backend.get(attribute); - attributeData.pbo = attribute.pbo; - } - - const nodeUniform = this.getUniformFromNode(attribute.pboNode, 'texture', this.shaderStage, this.context.label); - const textureName = this.getPropertyName(nodeUniform); - - indexNode.increaseUsage(this); // force cache generate to be used as index in x,y - const indexSnippet = indexNode.build(this, 'uint'); - - const elementNodeData = this.getDataFromNode(storageArrayElementNode); - - let propertyName = elementNodeData.propertyName; - - if (propertyName === undefined) { - // property element - - const nodeVar = this.getVarFromNode(storageArrayElementNode); - - propertyName = this.getPropertyName(nodeVar); - - // property size - - const bufferNodeData = this.getDataFromNode(node); - - let propertySizeName = bufferNodeData.propertySizeName; - - if (propertySizeName === undefined) { - propertySizeName = propertyName + 'Size'; - - this.getVarFromNode(node, propertySizeName, 'uint'); - - this.addLineFlowCode(`${propertySizeName} = uint( textureSize( ${textureName}, 0 ).x )`); - - bufferNodeData.propertySizeName = propertySizeName; - } - - // - - const { itemSize } = attribute; - - const channel = '.' + vectorComponents.join('').slice(0, itemSize); - const uvSnippet = `ivec2(${indexSnippet} % ${propertySizeName}, ${indexSnippet} / ${propertySizeName})`; - - const snippet = this.generateTextureLoad(null, textureName, uvSnippet, null, '0'); - - // - - const typePrefix = attribute.array.constructor.name.toLowerCase().charAt(0); - - let prefix = 'vec4'; - if (typePrefix === 'u') { - prefix = 'uvec4'; - } else if (typePrefix === 'i') { - prefix = 'ivec4'; - } - - this.addLineFlowCode(`${propertyName} = ${prefix}(${snippet})${channel}`); - - elementNodeData.propertyName = propertyName; - } - - return propertyName; - } - - generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0') { - if (depthSnippet) { - return `texelFetch( ${textureProperty}, ivec3( ${uvIndexSnippet}, ${depthSnippet} ), ${levelSnippet} )`; - } else { - return `texelFetch( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; - } - } - - generateTexture(texture, textureProperty, uvSnippet, depthSnippet) { - if (texture.isDepthTexture) { - return `texture( ${textureProperty}, ${uvSnippet} ).x`; - } else { - if (depthSnippet) uvSnippet = `vec3( ${uvSnippet}, ${depthSnippet} )`; - - return `texture( ${textureProperty}, ${uvSnippet} )`; - } - } - - generateTextureLevel(texture, textureProperty, uvSnippet, levelSnippet) { - return `textureLod( ${textureProperty}, ${uvSnippet}, ${levelSnippet} )`; - } - - generateTextureGrad(texture, textureProperty, uvSnippet, gradSnippet) { - return `textureGrad( ${textureProperty}, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; - } - - generateTextureCompare( - texture, - textureProperty, - uvSnippet, - compareSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `texture( ${textureProperty}, vec3( ${uvSnippet}, ${compareSnippet} ) )`; - } else { - console.error( - `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, - ); - } - } - - getVars(shaderStage) { - const snippets = []; - - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippets.push(`${this.getVar(variable.type, variable.name)};`); - } - } - - return snippets.join('\n\t'); - } - - getUniforms(shaderStage) { - const uniforms = this.uniforms[shaderStage]; - - const bindingSnippets = []; - const uniformGroups = {}; - - for (const uniform of uniforms) { - let snippet = null; - let group = false; - - if (uniform.type === 'texture') { - const texture = uniform.node.value; - - let typePrefix = ''; - - if (texture.isPBOTexture === true) { - const prefix = texture.source.data.data.constructor.name.toLowerCase().charAt(0); - - if (prefix === 'u' || prefix === 'i') { - typePrefix = prefix; - } - } - - if (texture.compareFunction) { - snippet = `sampler2DShadow ${uniform.name};`; - } else if (texture.isDataArrayTexture === true) { - snippet = `${typePrefix}sampler2DArray ${uniform.name};`; - } else { - snippet = `${typePrefix}sampler2D ${uniform.name};`; - } - } else if (uniform.type === 'cubeTexture') { - snippet = `samplerCube ${uniform.name};`; - } else if (uniform.type === 'texture3D') { - snippet = `sampler3D ${uniform.name};`; - } else if (uniform.type === 'buffer') { - const bufferNode = uniform.node; - const bufferType = this.getType(bufferNode.bufferType); - const bufferCount = bufferNode.bufferCount; - - const bufferCountSnippet = bufferCount > 0 ? bufferCount : ''; - snippet = `${bufferNode.name} {\n\t${bufferType} ${uniform.name}[${bufferCountSnippet}];\n};\n`; - } else { - const vectorType = this.getVectorType(uniform.type); - - snippet = `${vectorType} ${this.getPropertyName(uniform, shaderStage)};`; - - group = true; - } - - const precision = uniform.node.precision; - - if (precision !== null) { - snippet = precisionLib[precision] + ' ' + snippet; - } - - if (group) { - snippet = '\t' + snippet; - - const groupName = uniform.groupNode.name; - const groupSnippets = uniformGroups[groupName] || (uniformGroups[groupName] = []); - - groupSnippets.push(snippet); - } else { - snippet = 'uniform ' + snippet; - - bindingSnippets.push(snippet); - } - } - - let output = ''; - - for (const name in uniformGroups) { - const groupSnippets = uniformGroups[name]; - - output += this._getGLSLUniformStruct(shaderStage + '_' + name, groupSnippets.join('\n')) + '\n'; - } - - output += bindingSnippets.join('\n'); - - return output; - } - - getTypeFromAttribute(attribute) { - let nodeType = super.getTypeFromAttribute(attribute); - - if (/^[iu]/.test(nodeType) && attribute.gpuType !== IntType) { - let dataAttribute = attribute; - - if (attribute.isInterleavedBufferAttribute) dataAttribute = attribute.data; - - const array = dataAttribute.array; - - if ( - (array instanceof Uint32Array || - array instanceof Int32Array || - array instanceof Uint16Array || - array instanceof Int16Array) === false - ) { - nodeType = nodeType.slice(1); - } - } - - return nodeType; - } - - getAttributes(shaderStage) { - let snippet = ''; - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - const attributes = this.getAttributesArray(); - - let location = 0; - - for (const attribute of attributes) { - snippet += `layout( location = ${location++} ) in ${attribute.type} ${attribute.name};\n`; - } - } - - return snippet; - } - - getStructMembers(struct) { - const snippets = []; - const members = struct.getMemberTypes(); - - for (let i = 0; i < members.length; i++) { - const member = members[i]; - snippets.push(`layout( location = ${i} ) out ${member} m${i};`); - } - - return snippets.join('\n'); - } - - getStructs(shaderStage) { - const snippets = []; - const structs = this.structs[shaderStage]; - - if (structs.length === 0) { - return 'layout( location = 0 ) out vec4 fragColor;\n'; - } - - for (let index = 0, length = structs.length; index < length; index++) { - const struct = structs[index]; - - let snippet = '\n'; - snippet += this.getStructMembers(struct); - snippet += '\n'; - - snippets.push(snippet); - } - - return snippets.join('\n\n'); - } - - getVaryings(shaderStage) { - let snippet = ''; - - const varyings = this.varyings; - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - for (const varying of varyings) { - if (shaderStage === 'compute') varying.needsInterpolation = true; - const type = varying.type; - const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; - - snippet += `${flat}${varying.needsInterpolation ? 'out' : '/*out*/'} ${type} ${varying.name};\n`; - } - } else if (shaderStage === 'fragment') { - for (const varying of varyings) { - if (varying.needsInterpolation) { - const type = varying.type; - const flat = type.includes('int') || type.includes('uv') || type.includes('iv') ? 'flat ' : ''; - - snippet += `${flat}in ${type} ${varying.name};\n`; - } - } - } - - return snippet; - } - - getVertexIndex() { - return 'uint( gl_VertexID )'; - } - - getInstanceIndex() { - return 'uint( gl_InstanceID )'; - } - - getFrontFacing() { - return 'gl_FrontFacing'; - } - - getFragCoord() { - return 'gl_FragCoord'; - } - - getFragDepth() { - return 'gl_FragDepth'; - } - - isAvailable(name) { - let result = supports[name]; - - if (result === undefined) { - if (name === 'float32Filterable') { - const extentions = this.renderer.backend.extensions; - - if (extentions.has('OES_texture_float_linear')) { - extentions.get('OES_texture_float_linear'); - result = true; - } else { - result = false; - } - } - - supports[name] = result; - } - - return result; - } - - isFlipY() { - return true; - } - - registerTransform(varyingName, attributeNode) { - this.transforms.push({ varyingName, attributeNode }); - } - - getTransforms(/* shaderStage */) { - const transforms = this.transforms; - - let snippet = ''; - - for (let i = 0; i < transforms.length; i++) { - const transform = transforms[i]; - - const attributeName = this.getPropertyName(transform.attributeNode); - - snippet += `${transform.varyingName} = ${attributeName};\n\t`; - } - - return snippet; - } - - _getGLSLUniformStruct(name, vars) { - return ` -layout( std140 ) uniform ${name} { -${vars} -};`; - } - - _getGLSLVertexCode(shaderData) { - return `#version 300 es - -${this.getSignature()} - -// precision -${defaultPrecisions} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} - -// attributes -${shaderData.attributes} - -// codes -${shaderData.codes} - -void main() { - - // vars - ${shaderData.vars} - - // transforms - ${shaderData.transforms} - - // flow - ${shaderData.flow} - - gl_PointSize = 1.0; - -} -`; - } - - _getGLSLFragmentCode(shaderData) { - return `#version 300 es - -${this.getSignature()} - -// precision -${defaultPrecisions} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} - -// codes -${shaderData.codes} - -${shaderData.structs} - -void main() { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - buildCode() { - const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; - - for (const shaderStage in shadersData) { - let flow = '// code\n\n'; - flow += this.flowCode[shaderStage]; - - const flowNodes = this.flowNodes[shaderStage]; - const mainNode = flowNodes[flowNodes.length - 1]; - - for (const node of flowNodes) { - const flowSlotData = this.getFlowData(node /*, shaderStage*/); - const slotName = node.name; - - if (slotName) { - if (flow.length > 0) flow += '\n'; - - flow += `\t// flow -> ${slotName}\n\t`; - } - - flow += `${flowSlotData.code}\n\t`; - - if (node === mainNode && shaderStage !== 'compute') { - flow += '// result\n\t'; - - if (shaderStage === 'vertex') { - flow += 'gl_Position = '; - flow += `${flowSlotData.result};`; - } else if (shaderStage === 'fragment') { - if (!node.outputNode.isOutputStructNode) { - flow += 'fragColor = '; - flow += `${flowSlotData.result};`; - } - } - } - } - - const stageData = shadersData[shaderStage]; - - stageData.uniforms = this.getUniforms(shaderStage); - stageData.attributes = this.getAttributes(shaderStage); - stageData.varyings = this.getVaryings(shaderStage); - stageData.vars = this.getVars(shaderStage); - stageData.structs = this.getStructs(shaderStage); - stageData.codes = this.getCodes(shaderStage); - stageData.transforms = this.getTransforms(shaderStage); - stageData.flow = flow; - } - - if (this.material !== null) { - this.vertexShader = this._getGLSLVertexCode(shadersData.vertex); - this.fragmentShader = this._getGLSLFragmentCode(shadersData.fragment); - } else { - this.computeShader = this._getGLSLVertexCode(shadersData.compute); - } - } - - getUniformFromNode(node, type, shaderStage, name = null) { - const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - let uniformGPU = nodeData.uniformGPU; - - if (uniformGPU === undefined) { - const group = node.groupNode; - const groupName = group.name; - - const bindings = this.getBindGroupArray(groupName, shaderStage); - - if (type === 'texture') { - uniformGPU = new NodeSampledTexture(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'cubeTexture') { - uniformGPU = new NodeSampledCubeTexture(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'texture3D') { - uniformGPU = new NodeSampledTexture3D(uniformNode.name, uniformNode.node, group); - bindings.push(uniformGPU); - } else if (type === 'buffer') { - node.name = `NodeBuffer_${node.id}`; - uniformNode.name = `buffer${node.id}`; - - const buffer = new NodeUniformBuffer(node, group); - buffer.name = node.name; - - bindings.push(buffer); - - uniformGPU = buffer; - } else { - const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); - - let uniformsGroup = uniformsStage[groupName]; - - if (uniformsGroup === undefined) { - uniformsGroup = new NodeUniformsGroup(shaderStage + '_' + groupName, group); - //uniformsGroup.setVisibility( gpuShaderStageLib[ shaderStage ] ); - - uniformsStage[groupName] = uniformsGroup; - - bindings.push(uniformsGroup); - } - - uniformGPU = this.getNodeUniform(uniformNode, type); - - uniformsGroup.addUniform(uniformGPU); - } - - nodeData.uniformGPU = uniformGPU; - } - - return uniformNode; - } -} - -export default GLSLNodeBuilder; diff --git a/examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts b/examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts deleted file mode 100644 index a5c38c170..000000000 --- a/examples-jsm/examples/renderers/webgpu/WebGPUBackend.ts +++ /dev/null @@ -1,1205 +0,0 @@ -/*// debugger tools -import 'https://greggman.github.io/webgpu-avoid-redundant-state-setting/webgpu-check-redundant-state-setting.js'; -//*/ - -import { WebGPUCoordinateSystem } from 'three'; - -import { - GPUFeatureName, - GPUTextureFormat, - GPULoadOp, - GPUStoreOp, - GPUIndexFormat, - GPUTextureViewDimension, -} from './utils/WebGPUConstants.js'; - -import WGSLNodeBuilder from './nodes/WGSLNodeBuilder.js'; -import Backend from '../common/Backend.js'; - -import WebGPUUtils from './utils/WebGPUUtils.js'; -import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js'; -import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; -import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; -import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; - -// - -class WebGPUBackend extends Backend { - constructor(parameters = {}) { - super(parameters); - - this.isWebGPUBackend = true; - - // some parameters require default values other than "undefined" - this.parameters.alpha = parameters.alpha === undefined ? true : parameters.alpha; - - this.parameters.antialias = parameters.antialias === true; - - if (this.parameters.antialias === true) { - this.parameters.sampleCount = parameters.sampleCount === undefined ? 4 : parameters.sampleCount; - } else { - this.parameters.sampleCount = 1; - } - - this.parameters.requiredLimits = parameters.requiredLimits === undefined ? {} : parameters.requiredLimits; - - this.trackTimestamp = parameters.trackTimestamp === true; - - this.device = null; - this.context = null; - this.colorBuffer = null; - this.defaultRenderPassdescriptor = null; - - this.utils = new WebGPUUtils(this); - this.attributeUtils = new WebGPUAttributeUtils(this); - this.bindingUtils = new WebGPUBindingUtils(this); - this.pipelineUtils = new WebGPUPipelineUtils(this); - this.textureUtils = new WebGPUTextureUtils(this); - this.occludedResolveCache = new Map(); - } - - async init(renderer) { - await super.init(renderer); - - // - - const parameters = this.parameters; - - // create the device if it is not passed with parameters - - let device; - - if (parameters.device === undefined) { - const adapterOptions = { - powerPreference: parameters.powerPreference, - }; - - const adapter = await navigator.gpu.requestAdapter(adapterOptions); - - if (adapter === null) { - throw new Error('WebGPUBackend: Unable to create WebGPU adapter.'); - } - - // feature support - - const features = Object.values(GPUFeatureName); - - const supportedFeatures = []; - - for (const name of features) { - if (adapter.features.has(name)) { - supportedFeatures.push(name); - } - } - - const deviceDescriptor = { - requiredFeatures: supportedFeatures, - requiredLimits: parameters.requiredLimits, - }; - - device = await adapter.requestDevice(deviceDescriptor); - } else { - device = parameters.device; - } - - const context = - parameters.context !== undefined ? parameters.context : renderer.domElement.getContext('webgpu'); - - this.device = device; - this.context = context; - - const alphaMode = parameters.alpha ? 'premultiplied' : 'opaque'; - - this.context.configure({ - device: this.device, - format: GPUTextureFormat.BGRA8Unorm, - usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, - alphaMode: alphaMode, - }); - - this.updateSize(); - } - - get coordinateSystem() { - return WebGPUCoordinateSystem; - } - - async getArrayBufferAsync(attribute) { - return await this.attributeUtils.getArrayBufferAsync(attribute); - } - - getContext() { - return this.context; - } - - _getDefaultRenderPassDescriptor() { - let descriptor = this.defaultRenderPassdescriptor; - - const antialias = this.parameters.antialias; - - if (descriptor === null) { - const renderer = this.renderer; - - descriptor = { - colorAttachments: [ - { - view: null, - }, - ], - depthStencilAttachment: { - view: this.textureUtils.getDepthBuffer(renderer.depth, renderer.stencil).createView(), - }, - }; - - const colorAttachment = descriptor.colorAttachments[0]; - - if (antialias === true) { - colorAttachment.view = this.colorBuffer.createView(); - } else { - colorAttachment.resolveTarget = undefined; - } - - this.defaultRenderPassdescriptor = descriptor; - } - - const colorAttachment = descriptor.colorAttachments[0]; - - if (antialias === true) { - colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); - } else { - colorAttachment.view = this.context.getCurrentTexture().createView(); - } - - return descriptor; - } - - _getRenderPassDescriptor(renderContext) { - const renderTarget = renderContext.renderTarget; - const renderTargetData = this.get(renderTarget); - - let descriptors = renderTargetData.descriptors; - - if (descriptors === undefined) { - descriptors = []; - - renderTargetData.descriptors = descriptors; - } - - if ( - renderTargetData.width !== renderTarget.width || - renderTargetData.height !== renderTarget.height || - renderTargetData.activeMipmapLevel !== renderTarget.activeMipmapLevel || - renderTargetData.samples !== renderTarget.samples - ) { - descriptors.length = 0; - } - - let descriptor = descriptors[renderContext.activeCubeFace]; - - if (descriptor === undefined) { - const textures = renderContext.textures; - const colorAttachments = []; - - for (let i = 0; i < textures.length; i++) { - const textureData = this.get(textures[i]); - - const textureView = textureData.texture.createView({ - baseMipLevel: renderContext.activeMipmapLevel, - mipLevelCount: 1, - baseArrayLayer: renderContext.activeCubeFace, - dimension: GPUTextureViewDimension.TwoD, - }); - - let view, resolveTarget; - - if (textureData.msaaTexture !== undefined) { - view = textureData.msaaTexture.createView(); - resolveTarget = textureView; - } else { - view = textureView; - resolveTarget = undefined; - } - - colorAttachments.push({ - view, - resolveTarget, - loadOp: GPULoadOp.Load, - storeOp: GPUStoreOp.Store, - }); - } - - const depthTextureData = this.get(renderContext.depthTexture); - - const depthStencilAttachment = { - view: depthTextureData.texture.createView(), - }; - - descriptor = { - colorAttachments, - depthStencilAttachment, - }; - - descriptors[renderContext.activeCubeFace] = descriptor; - - renderTargetData.width = renderTarget.width; - renderTargetData.height = renderTarget.height; - renderTargetData.samples = renderTarget.samples; - renderTargetData.activeMipmapLevel = renderTarget.activeMipmapLevel; - } - - return descriptor; - } - - beginRender(renderContext) { - const renderContextData = this.get(renderContext); - - const device = this.device; - const occlusionQueryCount = renderContext.occlusionQueryCount; - - let occlusionQuerySet; - - if (occlusionQueryCount > 0) { - if (renderContextData.currentOcclusionQuerySet) renderContextData.currentOcclusionQuerySet.destroy(); - if (renderContextData.currentOcclusionQueryBuffer) renderContextData.currentOcclusionQueryBuffer.destroy(); - - // Get a reference to the array of objects with queries. The renderContextData property - // can be changed by another render pass before the buffer.mapAsyc() completes. - renderContextData.currentOcclusionQuerySet = renderContextData.occlusionQuerySet; - renderContextData.currentOcclusionQueryBuffer = renderContextData.occlusionQueryBuffer; - renderContextData.currentOcclusionQueryObjects = renderContextData.occlusionQueryObjects; - - // - - occlusionQuerySet = device.createQuerySet({ type: 'occlusion', count: occlusionQueryCount }); - - renderContextData.occlusionQuerySet = occlusionQuerySet; - renderContextData.occlusionQueryIndex = 0; - renderContextData.occlusionQueryObjects = new Array(occlusionQueryCount); - - renderContextData.lastOcclusionObject = null; - } - - let descriptor; - - if (renderContext.textures === null) { - descriptor = this._getDefaultRenderPassDescriptor(); - } else { - descriptor = this._getRenderPassDescriptor(renderContext); - } - - this.initTimestampQuery(renderContext, descriptor); - - descriptor.occlusionQuerySet = occlusionQuerySet; - - const depthStencilAttachment = descriptor.depthStencilAttachment; - - if (renderContext.textures !== null) { - const colorAttachments = descriptor.colorAttachments; - - for (let i = 0; i < colorAttachments.length; i++) { - const colorAttachment = colorAttachments[i]; - - if (renderContext.clearColor) { - colorAttachment.clearValue = renderContext.clearColorValue; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } else { - colorAttachment.loadOp = GPULoadOp.Load; - colorAttachment.storeOp = GPUStoreOp.Store; - } - } - } else { - const colorAttachment = descriptor.colorAttachments[0]; - - if (renderContext.clearColor) { - colorAttachment.clearValue = renderContext.clearColorValue; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } else { - colorAttachment.loadOp = GPULoadOp.Load; - colorAttachment.storeOp = GPUStoreOp.Store; - } - } - - // - - if (renderContext.depth) { - if (renderContext.clearDepth) { - depthStencilAttachment.depthClearValue = renderContext.clearDepthValue; - depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } - } - - if (renderContext.stencil) { - if (renderContext.clearStencil) { - depthStencilAttachment.stencilClearValue = renderContext.clearStencilValue; - depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } - } - - // - - const encoder = device.createCommandEncoder({ label: 'renderContext_' + renderContext.id }); - const currentPass = encoder.beginRenderPass(descriptor); - - // - - renderContextData.descriptor = descriptor; - renderContextData.encoder = encoder; - renderContextData.currentPass = currentPass; - renderContextData.currentSets = { attributes: {} }; - - // - - if (renderContext.viewport) { - this.updateViewport(renderContext); - } - - if (renderContext.scissor) { - const { x, y, width, height } = renderContext.scissorValue; - - currentPass.setScissorRect(x, renderContext.height - height - y, width, height); - } - } - - finishRender(renderContext) { - const renderContextData = this.get(renderContext); - const occlusionQueryCount = renderContext.occlusionQueryCount; - - if (renderContextData.renderBundles !== undefined && renderContextData.renderBundles.length > 0) { - renderContextData.registerBundlesPhase = false; - renderContextData.currentPass.executeBundles(renderContextData.renderBundles); - } - - if (occlusionQueryCount > renderContextData.occlusionQueryIndex) { - renderContextData.currentPass.endOcclusionQuery(); - } - - renderContextData.currentPass.end(); - - if (occlusionQueryCount > 0) { - const bufferSize = occlusionQueryCount * 8; // 8 byte entries for query results - - // - - let queryResolveBuffer = this.occludedResolveCache.get(bufferSize); - - if (queryResolveBuffer === undefined) { - queryResolveBuffer = this.device.createBuffer({ - size: bufferSize, - usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, - }); - - this.occludedResolveCache.set(bufferSize, queryResolveBuffer); - } - - // - - const readBuffer = this.device.createBuffer({ - size: bufferSize, - usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, - }); - - // two buffers required here - WebGPU doesn't allow usage of QUERY_RESOLVE & MAP_READ to be combined - renderContextData.encoder.resolveQuerySet( - renderContextData.occlusionQuerySet, - 0, - occlusionQueryCount, - queryResolveBuffer, - 0, - ); - renderContextData.encoder.copyBufferToBuffer(queryResolveBuffer, 0, readBuffer, 0, bufferSize); - - renderContextData.occlusionQueryBuffer = readBuffer; - - // - - this.resolveOccludedAsync(renderContext); - } - - this.prepareTimestampBuffer(renderContext, renderContextData.encoder); - - this.device.queue.submit([renderContextData.encoder.finish()]); - - // - - if (renderContext.textures !== null) { - const textures = renderContext.textures; - - for (let i = 0; i < textures.length; i++) { - const texture = textures[i]; - - if (texture.generateMipmaps === true) { - this.textureUtils.generateMipmaps(texture); - } - } - } - } - - isOccluded(renderContext, object) { - const renderContextData = this.get(renderContext); - - return renderContextData.occluded && renderContextData.occluded.has(object); - } - - async resolveOccludedAsync(renderContext) { - const renderContextData = this.get(renderContext); - - // handle occlusion query results - - const { currentOcclusionQueryBuffer, currentOcclusionQueryObjects } = renderContextData; - - if (currentOcclusionQueryBuffer && currentOcclusionQueryObjects) { - const occluded = new WeakSet(); - - renderContextData.currentOcclusionQueryObjects = null; - renderContextData.currentOcclusionQueryBuffer = null; - - await currentOcclusionQueryBuffer.mapAsync(GPUMapMode.READ); - - const buffer = currentOcclusionQueryBuffer.getMappedRange(); - const results = new BigUint64Array(buffer); - - for (let i = 0; i < currentOcclusionQueryObjects.length; i++) { - if (results[i] !== 0n) { - occluded.add(currentOcclusionQueryObjects[i]); - } - } - - currentOcclusionQueryBuffer.destroy(); - - renderContextData.occluded = occluded; - } - } - - updateViewport(renderContext) { - const { currentPass } = this.get(renderContext); - const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue; - - currentPass.setViewport(x, renderContext.height - height - y, width, height, minDepth, maxDepth); - } - - clear(color, depth, stencil, renderTargetData = null) { - const device = this.device; - const renderer = this.renderer; - - let colorAttachments = []; - - let depthStencilAttachment; - let clearValue; - - let supportsDepth; - let supportsStencil; - - if (color) { - const clearColor = this.getClearColor(); - - clearValue = { r: clearColor.r, g: clearColor.g, b: clearColor.b, a: clearColor.a }; - } - - if (renderTargetData === null) { - supportsDepth = renderer.depth; - supportsStencil = renderer.stencil; - - const descriptor = this._getDefaultRenderPassDescriptor(); - - if (color) { - colorAttachments = descriptor.colorAttachments; - - const colorAttachment = colorAttachments[0]; - - colorAttachment.clearValue = clearValue; - colorAttachment.loadOp = GPULoadOp.Clear; - colorAttachment.storeOp = GPUStoreOp.Store; - } - - if (supportsDepth || supportsStencil) { - depthStencilAttachment = descriptor.depthStencilAttachment; - } - } else { - supportsDepth = renderTargetData.depth; - supportsStencil = renderTargetData.stencil; - - if (color) { - for (const texture of renderTargetData.textures) { - const textureData = this.get(texture); - const textureView = textureData.texture.createView(); - - let view, resolveTarget; - - if (textureData.msaaTexture !== undefined) { - view = textureData.msaaTexture.createView(); - resolveTarget = textureView; - } else { - view = textureView; - resolveTarget = undefined; - } - - colorAttachments.push({ - view, - resolveTarget, - clearValue, - loadOp: GPULoadOp.Clear, - storeOp: GPUStoreOp.Store, - }); - } - } - - if (supportsDepth || supportsStencil) { - const depthTextureData = this.get(renderTargetData.depthTexture); - - depthStencilAttachment = { - view: depthTextureData.texture.createView(), - }; - } - } - - // - - if (supportsDepth) { - if (depth) { - depthStencilAttachment.depthLoadOp = GPULoadOp.Clear; - depthStencilAttachment.depthClearValue = renderer.getClearDepth(); - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - depthStencilAttachment.depthStoreOp = GPUStoreOp.Store; - } - } - - // - - if (supportsStencil) { - if (stencil) { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Clear; - depthStencilAttachment.stencilClearValue = renderer.getClearStencil(); - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } else { - depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - depthStencilAttachment.stencilStoreOp = GPUStoreOp.Store; - } - } - - // - - const encoder = device.createCommandEncoder({}); - const currentPass = encoder.beginRenderPass({ - colorAttachments, - depthStencilAttachment, - }); - - currentPass.end(); - - device.queue.submit([encoder.finish()]); - } - - // compute - - beginCompute(computeGroup) { - const groupGPU = this.get(computeGroup); - - const descriptor = {}; - - this.initTimestampQuery(computeGroup, descriptor); - - groupGPU.cmdEncoderGPU = this.device.createCommandEncoder(); - - groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass(descriptor); - } - - compute(computeGroup, computeNode, bindings, pipeline) { - const { passEncoderGPU } = this.get(computeGroup); - - // pipeline - - const pipelineGPU = this.get(pipeline).pipeline; - passEncoderGPU.setPipeline(pipelineGPU); - - // bind groups - - for (let i = 0, l = bindings.length; i < l; i++) { - const bindGroup = bindings[i]; - const bindingsData = this.get(bindGroup); - - passEncoderGPU.setBindGroup(i, bindingsData.group); - } - - passEncoderGPU.dispatchWorkgroups(computeNode.dispatchCount); - } - - finishCompute(computeGroup) { - const groupData = this.get(computeGroup); - - groupData.passEncoderGPU.end(); - - this.prepareTimestampBuffer(computeGroup, groupData.cmdEncoderGPU); - - this.device.queue.submit([groupData.cmdEncoderGPU.finish()]); - } - - // render object - - draw(renderObject, info) { - const { object, geometry, context, pipeline } = renderObject; - - const bindings = renderObject.getBindings(); - const contextData = this.get(context); - const pipelineGPU = this.get(pipeline).pipeline; - const currentSets = contextData.currentSets; - - const renderObjectData = this.get(renderObject); - - const { bundleEncoder, renderBundle, lastPipelineGPU } = renderObjectData; - - const renderContextData = this.get(context); - - if ( - renderContextData.registerBundlesPhase === true && - bundleEncoder !== undefined && - lastPipelineGPU === pipelineGPU - ) { - renderContextData.renderBundles.push(renderBundle); - return; - } - - const passEncoderGPU = this.renderer._currentRenderBundle - ? this.createBundleEncoder(context, renderObject) - : contextData.currentPass; - - // pipeline - - if (currentSets.pipeline !== pipelineGPU) { - passEncoderGPU.setPipeline(pipelineGPU); - - currentSets.pipeline = pipelineGPU; - } - - // bind groups - - for (let i = 0, l = bindings.length; i < l; i++) { - const bindGroup = bindings[i]; - const bindingsData = this.get(bindGroup); - - passEncoderGPU.setBindGroup(i, bindingsData.group); - } - - // attributes - - const index = renderObject.getIndex(); - - const hasIndex = index !== null; - - // index - - if (hasIndex === true) { - if (currentSets.index !== index) { - const buffer = this.get(index).buffer; - const indexFormat = index.array instanceof Uint16Array ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; - - passEncoderGPU.setIndexBuffer(buffer, indexFormat); - - currentSets.index = index; - } - } - - // vertex buffers - - const vertexBuffers = renderObject.getVertexBuffers(); - - for (let i = 0, l = vertexBuffers.length; i < l; i++) { - const vertexBuffer = vertexBuffers[i]; - - if (currentSets.attributes[i] !== vertexBuffer) { - const buffer = this.get(vertexBuffer).buffer; - passEncoderGPU.setVertexBuffer(i, buffer); - - currentSets.attributes[i] = vertexBuffer; - } - } - - // occlusion queries - handle multiple consecutive draw calls for an object - - if (contextData.occlusionQuerySet !== undefined) { - const lastObject = contextData.lastOcclusionObject; - - if (lastObject !== object) { - if (lastObject !== null && lastObject.occlusionTest === true) { - passEncoderGPU.endOcclusionQuery(); - contextData.occlusionQueryIndex++; - } - - if (object.occlusionTest === true) { - passEncoderGPU.beginOcclusionQuery(contextData.occlusionQueryIndex); - contextData.occlusionQueryObjects[contextData.occlusionQueryIndex] = object; - } - - contextData.lastOcclusionObject = object; - } - } - - // draw - - const drawRange = renderObject.drawRange; - const firstVertex = drawRange.start; - - const instanceCount = this.getInstanceCount(renderObject); - if (instanceCount === 0) return; - - if (hasIndex === true) { - const indexCount = drawRange.count !== Infinity ? drawRange.count : index.count; - - passEncoderGPU.drawIndexed(indexCount, instanceCount, firstVertex, 0, 0); - - info.update(object, indexCount, instanceCount); - } else { - const positionAttribute = geometry.attributes.position; - const vertexCount = drawRange.count !== Infinity ? drawRange.count : positionAttribute.count; - - passEncoderGPU.draw(vertexCount, instanceCount, firstVertex, 0); - - info.update(object, vertexCount, instanceCount); - } - - if (this.renderer._currentRenderBundle) { - const renderBundle = passEncoderGPU.finish(); - renderObjectData.lastPipelineGPU = pipelineGPU; - renderObjectData.renderBundle = renderBundle; - renderObjectData.bundleEncoder = passEncoderGPU; - } - } - - // cache key - - needsRenderUpdate(renderObject) { - const data = this.get(renderObject); - - const { object, material } = renderObject; - - const utils = this.utils; - - const sampleCount = utils.getSampleCount(renderObject.context); - const colorSpace = utils.getCurrentColorSpace(renderObject.context); - const colorFormat = utils.getCurrentColorFormat(renderObject.context); - const depthStencilFormat = utils.getCurrentDepthStencilFormat(renderObject.context); - const primitiveTopology = utils.getPrimitiveTopology(object, material); - - let needsUpdate = false; - - if ( - data.material !== material || - data.materialVersion !== material.version || - data.transparent !== material.transparent || - data.blending !== material.blending || - data.premultipliedAlpha !== material.premultipliedAlpha || - data.blendSrc !== material.blendSrc || - data.blendDst !== material.blendDst || - data.blendEquation !== material.blendEquation || - data.blendSrcAlpha !== material.blendSrcAlpha || - data.blendDstAlpha !== material.blendDstAlpha || - data.blendEquationAlpha !== material.blendEquationAlpha || - data.colorWrite !== material.colorWrite || - data.depthWrite !== material.depthWrite || - data.depthTest !== material.depthTest || - data.depthFunc !== material.depthFunc || - data.stencilWrite !== material.stencilWrite || - data.stencilFunc !== material.stencilFunc || - data.stencilFail !== material.stencilFail || - data.stencilZFail !== material.stencilZFail || - data.stencilZPass !== material.stencilZPass || - data.stencilFuncMask !== material.stencilFuncMask || - data.stencilWriteMask !== material.stencilWriteMask || - data.side !== material.side || - data.alphaToCoverage !== material.alphaToCoverage || - data.sampleCount !== sampleCount || - data.colorSpace !== colorSpace || - data.colorFormat !== colorFormat || - data.depthStencilFormat !== depthStencilFormat || - data.primitiveTopology !== primitiveTopology || - data.clippingContextVersion !== renderObject.clippingContextVersion - ) { - data.material = material; - data.materialVersion = material.version; - data.transparent = material.transparent; - data.blending = material.blending; - data.premultipliedAlpha = material.premultipliedAlpha; - data.blendSrc = material.blendSrc; - data.blendDst = material.blendDst; - data.blendEquation = material.blendEquation; - data.blendSrcAlpha = material.blendSrcAlpha; - data.blendDstAlpha = material.blendDstAlpha; - data.blendEquationAlpha = material.blendEquationAlpha; - data.colorWrite = material.colorWrite; - data.depthWrite = material.depthWrite; - data.depthTest = material.depthTest; - data.depthFunc = material.depthFunc; - data.stencilWrite = material.stencilWrite; - data.stencilFunc = material.stencilFunc; - data.stencilFail = material.stencilFail; - data.stencilZFail = material.stencilZFail; - data.stencilZPass = material.stencilZPass; - data.stencilFuncMask = material.stencilFuncMask; - data.stencilWriteMask = material.stencilWriteMask; - data.side = material.side; - data.alphaToCoverage = material.alphaToCoverage; - data.sampleCount = sampleCount; - data.colorSpace = colorSpace; - data.colorFormat = colorFormat; - data.depthStencilFormat = depthStencilFormat; - data.primitiveTopology = primitiveTopology; - data.clippingContextVersion = renderObject.clippingContextVersion; - - needsUpdate = true; - } - - return needsUpdate; - } - - getRenderCacheKey(renderObject) { - const { object, material } = renderObject; - - const utils = this.utils; - const renderContext = renderObject.context; - - return [ - material.transparent, - material.blending, - material.premultipliedAlpha, - material.blendSrc, - material.blendDst, - material.blendEquation, - material.blendSrcAlpha, - material.blendDstAlpha, - material.blendEquationAlpha, - material.colorWrite, - material.depthWrite, - material.depthTest, - material.depthFunc, - material.stencilWrite, - material.stencilFunc, - material.stencilFail, - material.stencilZFail, - material.stencilZPass, - material.stencilFuncMask, - material.stencilWriteMask, - material.side, - utils.getSampleCount(renderContext), - utils.getCurrentColorSpace(renderContext), - utils.getCurrentColorFormat(renderContext), - utils.getCurrentDepthStencilFormat(renderContext), - utils.getPrimitiveTopology(object, material), - renderObject.clippingContextVersion, - ].join(); - } - - // textures - - createSampler(texture) { - this.textureUtils.createSampler(texture); - } - - destroySampler(texture) { - this.textureUtils.destroySampler(texture); - } - - createDefaultTexture(texture) { - this.textureUtils.createDefaultTexture(texture); - } - - createTexture(texture, options) { - this.textureUtils.createTexture(texture, options); - } - - updateTexture(texture, options) { - this.textureUtils.updateTexture(texture, options); - } - - generateMipmaps(texture) { - this.textureUtils.generateMipmaps(texture); - } - - destroyTexture(texture) { - this.textureUtils.destroyTexture(texture); - } - - copyTextureToBuffer(texture, x, y, width, height) { - return this.textureUtils.copyTextureToBuffer(texture, x, y, width, height); - } - - initTimestampQuery(renderContext, descriptor) { - if (!this.hasFeature(GPUFeatureName.TimestampQuery) || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (!renderContextData.timeStampQuerySet) { - // Create a GPUQuerySet which holds 2 timestamp query results: one for the - // beginning and one for the end of compute pass execution. - const timeStampQuerySet = this.device.createQuerySet({ type: 'timestamp', count: 2 }); - - const timestampWrites = { - querySet: timeStampQuerySet, - beginningOfPassWriteIndex: 0, // Write timestamp in index 0 when pass begins. - endOfPassWriteIndex: 1, // Write timestamp in index 1 when pass ends. - }; - - Object.assign(descriptor, { - timestampWrites, - }); - - renderContextData.timeStampQuerySet = timeStampQuerySet; - } - } - - // timestamp utils - - prepareTimestampBuffer(renderContext, encoder) { - if (!this.hasFeature(GPUFeatureName.TimestampQuery) || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - const size = 2 * BigInt64Array.BYTES_PER_ELEMENT; - - if (renderContextData.currentTimestampQueryBuffers === undefined) { - renderContextData.currentTimestampQueryBuffers = { - resolveBuffer: this.device.createBuffer({ - label: 'timestamp resolve buffer', - size: size, - usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC, - }), - resultBuffer: this.device.createBuffer({ - label: 'timestamp result buffer', - size: size, - usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, - }), - isMappingPending: false, - }; - } - - const { resolveBuffer, resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; - - if (isMappingPending === true) return; - - encoder.resolveQuerySet(renderContextData.timeStampQuerySet, 0, 2, resolveBuffer, 0); - encoder.copyBufferToBuffer(resolveBuffer, 0, resultBuffer, 0, size); - } - - async resolveTimestampAsync(renderContext, type = 'render') { - if (!this.hasFeature(GPUFeatureName.TimestampQuery) || !this.trackTimestamp) return; - - const renderContextData = this.get(renderContext); - - if (renderContextData.currentTimestampQueryBuffers === undefined) return; - - const { resultBuffer, isMappingPending } = renderContextData.currentTimestampQueryBuffers; - - if (isMappingPending === true) return; - - renderContextData.currentTimestampQueryBuffers.isMappingPending = true; - - resultBuffer.mapAsync(GPUMapMode.READ).then(() => { - const times = new BigUint64Array(resultBuffer.getMappedRange()); - const duration = Number(times[1] - times[0]) / 1000000; - - this.renderer.info.updateTimestamp(type, duration); - - resultBuffer.unmap(); - - renderContextData.currentTimestampQueryBuffers.isMappingPending = false; - }); - } - - // node builder - - createNodeBuilder(object, renderer) { - return new WGSLNodeBuilder(object, renderer); - } - - // program - - createProgram(program) { - const programGPU = this.get(program); - - programGPU.module = { - module: this.device.createShaderModule({ code: program.code, label: program.stage }), - entryPoint: 'main', - }; - } - - destroyProgram(program) { - this.delete(program); - } - - // pipelines - - createRenderPipeline(renderObject, promises) { - this.pipelineUtils.createRenderPipeline(renderObject, promises); - } - - createComputePipeline(computePipeline, bindings) { - this.pipelineUtils.createComputePipeline(computePipeline, bindings); - } - - createBundleEncoder(renderContext, renderObject) { - return this.pipelineUtils.createBundleEncoder(renderContext, renderObject); - } - - // bindings - - createBindings(bindGroup) { - this.bindingUtils.createBindings(bindGroup); - } - - updateBindings(bindGroup) { - this.bindingUtils.createBindings(bindGroup); - } - - updateBinding(binding) { - this.bindingUtils.updateBinding(binding); - } - - // attributes - - createIndexAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.INDEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - createStorageAttribute(attribute) { - this.attributeUtils.createAttribute( - attribute, - GPUBufferUsage.STORAGE | GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST, - ); - } - - updateAttribute(attribute) { - this.attributeUtils.updateAttribute(attribute); - } - - destroyAttribute(attribute) { - this.attributeUtils.destroyAttribute(attribute); - } - - // canvas - - updateSize() { - this.colorBuffer = this.textureUtils.getColorBuffer(); - this.defaultRenderPassdescriptor = null; - } - - // utils public - - getMaxAnisotropy() { - return 16; - } - - hasFeature(name) { - return this.device.features.has(name); - } - - copyTextureToTexture(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) { - let dstX = 0; - let dstY = 0; - - if (dstPosition !== null) { - dstX = dstPosition.x; - dstY = dstPosition.y; - } - - const encoder = this.device.createCommandEncoder({ - label: 'copyTextureToTexture_' + srcTexture.id + '_' + dstTexture.id, - }); - - const sourceGPU = this.get(srcTexture).texture; - const destinationGPU = this.get(dstTexture).texture; - - encoder.copyTextureToTexture( - { - texture: sourceGPU, - mipLevel: level, - origin: { x: 0, y: 0, z: 0 }, - }, - { - texture: destinationGPU, - mipLevel: level, - origin: { x: dstX, y: dstY, z: 0 }, - }, - [srcTexture.image.width, srcTexture.image.height], - ); - - this.device.queue.submit([encoder.finish()]); - } - - copyFramebufferToTexture(texture, renderContext) { - const renderContextData = this.get(renderContext); - - const { encoder, descriptor } = renderContextData; - - let sourceGPU = null; - - if (renderContext.renderTarget) { - if (texture.isDepthTexture) { - sourceGPU = this.get(renderContext.depthTexture).texture; - } else { - sourceGPU = this.get(renderContext.textures[0]).texture; - } - } else { - if (texture.isDepthTexture) { - sourceGPU = this.textureUtils.getDepthBuffer(renderContext.depth, renderContext.stencil); - } else { - sourceGPU = this.context.getCurrentTexture(); - } - } - - const destinationGPU = this.get(texture).texture; - - if (sourceGPU.format !== destinationGPU.format) { - console.error( - 'WebGPUBackend: copyFramebufferToTexture: Source and destination formats do not match.', - sourceGPU.format, - destinationGPU.format, - ); - - return; - } - - renderContextData.currentPass.end(); - - encoder.copyTextureToTexture( - { - texture: sourceGPU, - origin: { x: 0, y: 0, z: 0 }, - }, - { - texture: destinationGPU, - }, - [texture.image.width, texture.image.height], - ); - - if (texture.generateMipmaps) this.textureUtils.generateMipmaps(texture); - - descriptor.colorAttachments[0].loadOp = GPULoadOp.Load; - if (renderContext.depth) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load; - if (renderContext.stencil) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load; - - renderContextData.currentPass = encoder.beginRenderPass(descriptor); - renderContextData.currentSets = { attributes: {} }; - } -} - -export default WebGPUBackend; diff --git a/examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts b/examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts deleted file mode 100644 index 1e548639e..000000000 --- a/examples-jsm/examples/renderers/webgpu/WebGPURenderer.ts +++ /dev/null @@ -1,43 +0,0 @@ -import WebGPU from '../../capabilities/WebGPU.js'; - -import Renderer from '../common/Renderer.js'; -import WebGLBackend from '../webgl/WebGLBackend.js'; -import WebGPUBackend from './WebGPUBackend.js'; -/* -const debugHandler = { - - get: function ( target, name ) { - - // Add |update - if ( /^(create|destroy)/.test( name ) ) console.log( 'WebGPUBackend.' + name ); - - return target[ name ]; - - } - -}; -*/ -class WebGPURenderer extends Renderer { - constructor(parameters = {}) { - let BackendClass; - - if (parameters.forceWebGL) { - BackendClass = WebGLBackend; - } else if (WebGPU.isAvailable()) { - BackendClass = WebGPUBackend; - } else { - BackendClass = WebGLBackend; - - console.warn('THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend.'); - } - - const backend = new BackendClass(parameters); - - //super( new Proxy( backend, debugHandler ) ); - super(backend, parameters); - - this.isWebGPURenderer = true; - } -} - -export default WebGPURenderer; diff --git a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts deleted file mode 100644 index 205865b39..000000000 --- a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeBuilder.ts +++ /dev/null @@ -1,1017 +0,0 @@ -import { NoColorSpace, FloatType } from 'three'; - -import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; - -import NodeSampler from '../../common/nodes/NodeSampler.js'; -import { - NodeSampledTexture, - NodeSampledCubeTexture, - NodeSampledTexture3D, -} from '../../common/nodes/NodeSampledTexture.js'; - -import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; -import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js'; - -import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js'; - -import { getFormat } from '../utils/WebGPUTextureUtils.js'; - -import WGSLNodeParser from './WGSLNodeParser.js'; -import { GPUBufferBindingType, GPUStorageTextureAccess } from '../utils/WebGPUConstants.js'; - -// GPUShaderStage is not defined in browsers not supporting WebGPU -const GPUShaderStage = self.GPUShaderStage; - -const gpuShaderStageLib = { - vertex: GPUShaderStage ? GPUShaderStage.VERTEX : 1, - fragment: GPUShaderStage ? GPUShaderStage.FRAGMENT : 2, - compute: GPUShaderStage ? GPUShaderStage.COMPUTE : 4, -}; - -const supports = { - instance: true, - swizzleAssign: false, - storageBuffer: true, -}; - -const wgslFnOpLib = { - '^^': 'threejs_xor', -}; - -const wgslTypeLib = { - float: 'f32', - int: 'i32', - uint: 'u32', - bool: 'bool', - color: 'vec3', - - vec2: 'vec2', - ivec2: 'vec2', - uvec2: 'vec2', - bvec2: 'vec2', - - vec3: 'vec3', - ivec3: 'vec3', - uvec3: 'vec3', - bvec3: 'vec3', - - vec4: 'vec4', - ivec4: 'vec4', - uvec4: 'vec4', - bvec4: 'vec4', - - mat2: 'mat2x2', - imat2: 'mat2x2', - umat2: 'mat2x2', - bmat2: 'mat2x2', - - mat3: 'mat3x3', - imat3: 'mat3x3', - umat3: 'mat3x3', - bmat3: 'mat3x3', - - mat4: 'mat4x4', - imat4: 'mat4x4', - umat4: 'mat4x4', - bmat4: 'mat4x4', -}; - -const wgslMethods = { - dFdx: 'dpdx', - dFdy: '- dpdy', - mod_float: 'threejs_mod_float', - mod_vec2: 'threejs_mod_vec2', - mod_vec3: 'threejs_mod_vec3', - mod_vec4: 'threejs_mod_vec4', - equals_bool: 'threejs_equals_bool', - equals_bvec2: 'threejs_equals_bvec2', - equals_bvec3: 'threejs_equals_bvec3', - equals_bvec4: 'threejs_equals_bvec4', - lessThanEqual: 'threejs_lessThanEqual', - greaterThan: 'threejs_greaterThan', - inversesqrt: 'inverseSqrt', - bitcast: 'bitcast', -}; - -const wgslPolyfill = { - threejs_xor: new CodeNode(` -fn threejs_xor( a : bool, b : bool ) -> bool { - - return ( a || b ) && !( a && b ); - -} -`), - lessThanEqual: new CodeNode(` -fn threejs_lessThanEqual( a : vec3, b : vec3 ) -> vec3 { - - return vec3( a.x <= b.x, a.y <= b.y, a.z <= b.z ); - -} -`), - greaterThan: new CodeNode(` -fn threejs_greaterThan( a : vec3, b : vec3 ) -> vec3 { - - return vec3( a.x > b.x, a.y > b.y, a.z > b.z ); - -} -`), - mod_float: new CodeNode('fn threejs_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }'), - mod_vec2: new CodeNode('fn threejs_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }'), - mod_vec3: new CodeNode('fn threejs_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }'), - mod_vec4: new CodeNode('fn threejs_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }'), - equals_bool: new CodeNode('fn threejs_equals_bool( a : bool, b : bool ) -> bool { return a == b; }'), - equals_bvec2: new CodeNode( - 'fn threejs_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }', - ), - equals_bvec3: new CodeNode( - 'fn threejs_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }', - ), - equals_bvec4: new CodeNode( - 'fn threejs_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }', - ), - repeatWrapping: new CodeNode(` -fn threejs_repeatWrapping( uv : vec2, dimension : vec2 ) -> vec2 { - - let uvScaled = vec2( uv * vec2( dimension ) ); - - return ( ( uvScaled % dimension ) + dimension ) % dimension; - -} -`), - biquadraticTexture: new CodeNode(` -fn threejs_biquadraticTexture( map : texture_2d, coord : vec2f, level : i32 ) -> vec4f { - - let res = vec2f( textureDimensions( map, level ) ); - - let uvScaled = coord * res; - let uvWrapping = ( ( uvScaled % res ) + res ) % res; - - // https://www.shadertoy.com/view/WtyXRy - - let uv = uvWrapping - 0.5; - let iuv = floor( uv ); - let f = fract( uv ); - - let rg1 = textureLoad( map, vec2i( iuv + vec2( 0.5, 0.5 ) ), level ); - let rg2 = textureLoad( map, vec2i( iuv + vec2( 1.5, 0.5 ) ), level ); - let rg3 = textureLoad( map, vec2i( iuv + vec2( 0.5, 1.5 ) ), level ); - let rg4 = textureLoad( map, vec2i( iuv + vec2( 1.5, 1.5 ) ), level ); - - return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); - -} -`), -}; - -class WGSLNodeBuilder extends NodeBuilder { - constructor(object, renderer) { - super(object, renderer, new WGSLNodeParser()); - - this.uniformGroups = {}; - - this.builtins = {}; - } - - needsColorSpaceToLinear(texture) { - return texture.isVideoTexture === true && texture.colorSpace !== NoColorSpace; - } - - _generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { - if (shaderStage === 'fragment') { - if (depthSnippet) { - return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${depthSnippet} )`; - } else { - return `textureSample( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet} )`; - } - } else if (this.isFilteredTexture(texture)) { - return this.generateFilteredTexture(texture, textureProperty, uvSnippet); - } else { - return this.generateTextureLod(texture, textureProperty, uvSnippet, '0'); - } - } - - _generateVideoSample(textureProperty, uvSnippet, shaderStage = this.shaderStage) { - if (shaderStage === 'fragment') { - return `textureSampleBaseClampToEdge( ${textureProperty}, ${textureProperty}_sampler, vec2( ${uvSnippet}.x, 1.0 - ${uvSnippet}.y ) )`; - } else { - console.error(`WebGPURenderer: THREE.VideoTexture does not support ${shaderStage} shader.`); - } - } - - _generateTextureSampleLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment' && this.isUnfilterable(texture) === false) { - return `textureSampleLevel( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${levelSnippet} )`; - } else if (this.isFilteredTexture(texture)) { - return this.generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet); - } else { - return this.generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet); - } - } - - generateFilteredTexture(texture, textureProperty, uvSnippet, levelSnippet = '0') { - this._include('biquadraticTexture'); - - return `threejs_biquadraticTexture( ${textureProperty}, ${uvSnippet}, i32( ${levelSnippet} ) )`; - } - - generateTextureLod(texture, textureProperty, uvSnippet, levelSnippet = '0') { - this._include('repeatWrapping'); - - const dimension = `textureDimensions( ${textureProperty}, 0 )`; - - return `textureLoad( ${textureProperty}, threejs_repeatWrapping( ${uvSnippet}, ${dimension} ), i32( ${levelSnippet} ) )`; - } - - generateTextureLoad(texture, textureProperty, uvIndexSnippet, depthSnippet, levelSnippet = '0u') { - if (depthSnippet) { - return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${depthSnippet}, ${levelSnippet} )`; - } else { - return `textureLoad( ${textureProperty}, ${uvIndexSnippet}, ${levelSnippet} )`; - } - } - - generateTextureStore(texture, textureProperty, uvIndexSnippet, valueSnippet) { - return `textureStore( ${textureProperty}, ${uvIndexSnippet}, ${valueSnippet} )`; - } - - isUnfilterable(texture) { - return ( - this.getComponentTypeFromTexture(texture) !== 'float' || - (texture.isDataTexture === true && texture.type === FloatType) - ); - } - - generateTexture(texture, textureProperty, uvSnippet, depthSnippet, shaderStage = this.shaderStage) { - let snippet = null; - - if (texture.isVideoTexture === true) { - snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); - } else if (this.isUnfilterable(texture)) { - snippet = this.generateTextureLod(texture, textureProperty, uvSnippet, '0', depthSnippet, shaderStage); - } else { - snippet = this._generateTextureSample(texture, textureProperty, uvSnippet, depthSnippet, shaderStage); - } - - return snippet; - } - - generateTextureGrad( - texture, - textureProperty, - uvSnippet, - gradSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - // TODO handle i32 or u32 --> uvSnippet, array_index: A, ddx, ddy - return `textureSampleGrad( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${gradSnippet[0]}, ${gradSnippet[1]} )`; - } else { - console.error(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${shaderStage} shader.`); - } - } - - generateTextureCompare( - texture, - textureProperty, - uvSnippet, - compareSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - if (shaderStage === 'fragment') { - return `textureSampleCompare( ${textureProperty}, ${textureProperty}_sampler, ${uvSnippet}, ${compareSnippet} )`; - } else { - console.error( - `WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${shaderStage} shader.`, - ); - } - } - - generateTextureLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage = this.shaderStage, - ) { - let snippet = null; - - if (texture.isVideoTexture === true) { - snippet = this._generateVideoSample(textureProperty, uvSnippet, shaderStage); - } else { - snippet = this._generateTextureSampleLevel( - texture, - textureProperty, - uvSnippet, - levelSnippet, - depthSnippet, - shaderStage, - ); - } - - return snippet; - } - - getPropertyName(node, shaderStage = this.shaderStage) { - if (node.isNodeVarying === true && node.needsInterpolation === true) { - if (shaderStage === 'vertex') { - return `varyings.${node.name}`; - } - } else if (node.isNodeUniform === true) { - const name = node.name; - const type = node.type; - - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { - return name; - } else if (type === 'buffer' || type === 'storageBuffer') { - return `NodeBuffer_${node.id}.${name}`; - } else { - return node.groupNode.name + '.' + name; - } - } - - return super.getPropertyName(node); - } - - getOutputStructName() { - return 'output'; - } - - _getUniformGroupCount(shaderStage) { - return Object.keys(this.uniforms[shaderStage]).length; - } - - getFunctionOperator(op) { - const fnOp = wgslFnOpLib[op]; - - if (fnOp !== undefined) { - this._include(fnOp); - - return fnOp; - } - - return null; - } - - getStorageAccess(node) { - if (node.isStorageTextureNode) { - switch (node.access) { - case GPUStorageTextureAccess.ReadOnly: - return 'read'; - - case GPUStorageTextureAccess.WriteOnly: - return 'write'; - - default: - return 'read_write'; - } - } else { - switch (node.access) { - case GPUBufferBindingType.Storage: - return 'read_write'; - - case GPUBufferBindingType.ReadOnlyStorage: - return 'read'; - - default: - return 'write'; - } - } - } - - getUniformFromNode(node, type, shaderStage, name = null) { - const uniformNode = super.getUniformFromNode(node, type, shaderStage, name); - const nodeData = this.getDataFromNode(node, shaderStage, this.globalCache); - - if (nodeData.uniformGPU === undefined) { - let uniformGPU; - - const group = node.groupNode; - const groupName = group.name; - - const bindings = this.getBindGroupArray(groupName, shaderStage); - - if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') { - let texture = null; - - if (type === 'texture' || type === 'storageTexture') { - texture = new NodeSampledTexture( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } else if (type === 'cubeTexture') { - texture = new NodeSampledCubeTexture( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } else if (type === 'texture3D') { - texture = new NodeSampledTexture3D( - uniformNode.name, - uniformNode.node, - group, - node.access ? node.access : null, - ); - } - - texture.store = node.isStorageTextureNode === true; - texture.setVisibility(gpuShaderStageLib[shaderStage]); - - if ( - shaderStage === 'fragment' && - this.isUnfilterable(node.value) === false && - texture.store === false - ) { - const sampler = new NodeSampler(`${uniformNode.name}_sampler`, uniformNode.node, group); - sampler.setVisibility(gpuShaderStageLib[shaderStage]); - - bindings.push(sampler, texture); - - uniformGPU = [sampler, texture]; - } else { - bindings.push(texture); - - uniformGPU = [texture]; - } - } else if (type === 'buffer' || type === 'storageBuffer') { - const bufferClass = type === 'storageBuffer' ? NodeStorageBuffer : NodeUniformBuffer; - const buffer = new bufferClass(node, group); - buffer.setVisibility(gpuShaderStageLib[shaderStage]); - - bindings.push(buffer); - - uniformGPU = buffer; - } else { - const uniformsStage = this.uniformGroups[shaderStage] || (this.uniformGroups[shaderStage] = {}); - - let uniformsGroup = uniformsStage[groupName]; - - if (uniformsGroup === undefined) { - uniformsGroup = new NodeUniformsGroup(groupName, group); - uniformsGroup.setVisibility(gpuShaderStageLib[shaderStage]); - - uniformsStage[groupName] = uniformsGroup; - - bindings.push(uniformsGroup); - } - - uniformGPU = this.getNodeUniform(uniformNode, type); - - uniformsGroup.addUniform(uniformGPU); - } - - nodeData.uniformGPU = uniformGPU; - } - - return uniformNode; - } - - getBuiltin(name, property, type, shaderStage = this.shaderStage) { - const map = this.builtins[shaderStage] || (this.builtins[shaderStage] = new Map()); - - if (map.has(name) === false) { - map.set(name, { - name, - property, - type, - }); - } - - return property; - } - - getVertexIndex() { - if (this.shaderStage === 'vertex') { - return this.getBuiltin('vertex_index', 'vertexIndex', 'u32', 'attribute'); - } - - return 'vertexIndex'; - } - - buildFunctionCode(shaderNode) { - const layout = shaderNode.layout; - const flowData = this.flowShaderNode(shaderNode); - - const parameters = []; - - for (const input of layout.inputs) { - parameters.push(input.name + ' : ' + this.getType(input.type)); - } - - // - - const code = `fn ${layout.name}( ${parameters.join(', ')} ) -> ${this.getType(layout.type)} { -${flowData.vars} -${flowData.code} - return ${flowData.result}; - -}`; - - // - - return code; - } - - getInstanceIndex() { - if (this.shaderStage === 'vertex') { - return this.getBuiltin('instance_index', 'instanceIndex', 'u32', 'attribute'); - } - - return 'instanceIndex'; - } - - getFrontFacing() { - return this.getBuiltin('front_facing', 'isFront', 'bool'); - } - - getFragCoord() { - return this.getBuiltin('position', 'fragCoord', 'vec4') + '.xyz'; - } - - getFragDepth() { - return 'output.' + this.getBuiltin('frag_depth', 'depth', 'f32', 'output'); - } - - isFlipY() { - return false; - } - - getBuiltins(shaderStage) { - const snippets = []; - const builtins = this.builtins[shaderStage]; - - if (builtins !== undefined) { - for (const { name, property, type } of builtins.values()) { - snippets.push(`@builtin( ${name} ) ${property} : ${type}`); - } - } - - return snippets.join(',\n\t'); - } - - getAttributes(shaderStage) { - const snippets = []; - - if (shaderStage === 'compute') { - this.getBuiltin('global_invocation_id', 'id', 'vec3', 'attribute'); - } - - if (shaderStage === 'vertex' || shaderStage === 'compute') { - const builtins = this.getBuiltins('attribute'); - - if (builtins) snippets.push(builtins); - - const attributes = this.getAttributesArray(); - - for (let index = 0, length = attributes.length; index < length; index++) { - const attribute = attributes[index]; - const name = attribute.name; - const type = this.getType(attribute.type); - - snippets.push(`@location( ${index} ) ${name} : ${type}`); - } - } - - return snippets.join(',\n\t'); - } - - getStructMembers(struct) { - const snippets = []; - const members = struct.getMemberTypes(); - - for (let i = 0; i < members.length; i++) { - const member = members[i]; - snippets.push(`\t@location( ${i} ) m${i} : ${member}`); - } - - const builtins = this.getBuiltins('output'); - - if (builtins) snippets.push(builtins); - - return snippets.join(',\n'); - } - - getStructs(shaderStage) { - const snippets = []; - const structs = this.structs[shaderStage]; - - for (let index = 0, length = structs.length; index < length; index++) { - const struct = structs[index]; - const name = struct.name; - - let snippet = `\struct ${name} {\n`; - snippet += this.getStructMembers(struct); - snippet += '\n}'; - - snippets.push(snippet); - - snippets.push(`\nvar output : ${name};\n\n`); - } - - return snippets.join('\n\n'); - } - - getVar(type, name) { - return `var ${name} : ${this.getType(type)}`; - } - - getVars(shaderStage) { - const snippets = []; - const vars = this.vars[shaderStage]; - - if (vars !== undefined) { - for (const variable of vars) { - snippets.push(`\t${this.getVar(variable.type, variable.name)};`); - } - } - - return `\n${snippets.join('\n')}\n`; - } - - getVaryings(shaderStage) { - const snippets = []; - - if (shaderStage === 'vertex') { - this.getBuiltin('position', 'Vertex', 'vec4', 'vertex'); - } - - if (shaderStage === 'vertex' || shaderStage === 'fragment') { - const varyings = this.varyings; - const vars = this.vars[shaderStage]; - - for (let index = 0; index < varyings.length; index++) { - const varying = varyings[index]; - - if (varying.needsInterpolation) { - let attributesSnippet = `@location( ${index} )`; - - if (/^(int|uint|ivec|uvec)/.test(varying.type)) { - attributesSnippet += ' @interpolate( flat )'; - } - - snippets.push(`${attributesSnippet} ${varying.name} : ${this.getType(varying.type)}`); - } else if (shaderStage === 'vertex' && vars.includes(varying) === false) { - vars.push(varying); - } - } - } - - const builtins = this.getBuiltins(shaderStage); - - if (builtins) snippets.push(builtins); - - const code = snippets.join(',\n\t'); - - return shaderStage === 'vertex' ? this._getWGSLStruct('VaryingsStruct', '\t' + code) : code; - } - - getUniforms(shaderStage) { - const uniforms = this.uniforms[shaderStage]; - - const bindingSnippets = []; - const bufferSnippets = []; - const structSnippets = []; - const uniformGroups = {}; - - for (const uniform of uniforms) { - const groundName = uniform.groupNode.name; - const uniformIndexes = this.bindingsIndexes[groundName]; - - if ( - uniform.type === 'texture' || - uniform.type === 'cubeTexture' || - uniform.type === 'storageTexture' || - uniform.type === 'texture3D' - ) { - const texture = uniform.node.value; - - if ( - shaderStage === 'fragment' && - this.isUnfilterable(texture) === false && - uniform.node.isStorageTextureNode !== true - ) { - if (texture.isDepthTexture === true && texture.compareFunction !== null) { - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler_comparison;`, - ); - } else { - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name}_sampler : sampler;`, - ); - } - } - - let textureType; - - if (texture.isCubeTexture === true) { - textureType = 'texture_cube'; - } else if (texture.isDataArrayTexture === true) { - textureType = 'texture_2d_array'; - } else if (texture.isDepthTexture === true) { - textureType = 'texture_depth_2d'; - } else if (texture.isVideoTexture === true) { - textureType = 'texture_external'; - } else if (texture.isData3DTexture === true) { - textureType = 'texture_3d'; - } else if (uniform.node.isStorageTextureNode === true) { - const format = getFormat(texture); - const access = this.getStorageAccess(uniform.node); - - textureType = `texture_storage_2d<${format}, ${access}>`; - } else { - const componentPrefix = this.getComponentTypeFromTexture(texture).charAt(0); - - textureType = `texture_2d<${componentPrefix}32>`; - } - - bindingSnippets.push( - `@binding( ${uniformIndexes.binding++} ) @group( ${uniformIndexes.group} ) var ${uniform.name} : ${textureType};`, - ); - } else if (uniform.type === 'buffer' || uniform.type === 'storageBuffer') { - const bufferNode = uniform.node; - const bufferType = this.getType(bufferNode.bufferType); - const bufferCount = bufferNode.bufferCount; - - const bufferCountSnippet = bufferCount > 0 ? ', ' + bufferCount : ''; - const bufferSnippet = `\t${uniform.name} : array< ${bufferType}${bufferCountSnippet} >\n`; - const bufferAccessMode = bufferNode.isStorageBufferNode - ? `storage, ${this.getStorageAccess(bufferNode)}` - : 'uniform'; - - bufferSnippets.push( - this._getWGSLStructBinding( - 'NodeBuffer_' + bufferNode.id, - bufferSnippet, - bufferAccessMode, - uniformIndexes.binding++, - uniformIndexes.group, - ), - ); - } else { - const vectorType = this.getType(this.getVectorType(uniform.type)); - const groupName = uniform.groupNode.name; - - const group = - uniformGroups[groupName] || - (uniformGroups[groupName] = { - index: uniformIndexes.binding++, - id: uniformIndexes.group, - snippets: [], - }); - - group.snippets.push(`\t${uniform.name} : ${vectorType}`); - } - } - - for (const name in uniformGroups) { - const group = uniformGroups[name]; - - structSnippets.push( - this._getWGSLStructBinding(name, group.snippets.join(',\n'), 'uniform', group.index, group.id), - ); - } - - let code = bindingSnippets.join('\n'); - code += bufferSnippets.join('\n'); - code += structSnippets.join('\n'); - - return code; - } - - buildCode() { - const shadersData = this.material !== null ? { fragment: {}, vertex: {} } : { compute: {} }; - - for (const shaderStage in shadersData) { - const stageData = shadersData[shaderStage]; - stageData.uniforms = this.getUniforms(shaderStage); - stageData.attributes = this.getAttributes(shaderStage); - stageData.varyings = this.getVaryings(shaderStage); - stageData.structs = this.getStructs(shaderStage); - stageData.vars = this.getVars(shaderStage); - stageData.codes = this.getCodes(shaderStage); - - // - - let flow = '// code\n\n'; - flow += this.flowCode[shaderStage]; - - const flowNodes = this.flowNodes[shaderStage]; - const mainNode = flowNodes[flowNodes.length - 1]; - - const outputNode = mainNode.outputNode; - const isOutputStruct = outputNode !== undefined && outputNode.isOutputStructNode === true; - - for (const node of flowNodes) { - const flowSlotData = this.getFlowData(node /*, shaderStage*/); - const slotName = node.name; - - if (slotName) { - if (flow.length > 0) flow += '\n'; - - flow += `\t// flow -> ${slotName}\n\t`; - } - - flow += `${flowSlotData.code}\n\t`; - - if (node === mainNode && shaderStage !== 'compute') { - flow += '// result\n\n\t'; - - if (shaderStage === 'vertex') { - flow += `varyings.Vertex = ${flowSlotData.result};`; - } else if (shaderStage === 'fragment') { - if (isOutputStruct) { - stageData.returnType = outputNode.nodeType; - - flow += `return ${flowSlotData.result};`; - } else { - let structSnippet = '\t@location(0) color: vec4'; - - const builtins = this.getBuiltins('output'); - - if (builtins) structSnippet += ',\n\t' + builtins; - - stageData.returnType = 'OutputStruct'; - stageData.structs += this._getWGSLStruct('OutputStruct', structSnippet); - stageData.structs += '\nvar output : OutputStruct;\n\n'; - - flow += `output.color = ${flowSlotData.result};\n\n\treturn output;`; - } - } - } - } - - stageData.flow = flow; - } - - if (this.material !== null) { - this.vertexShader = this._getWGSLVertexCode(shadersData.vertex); - this.fragmentShader = this._getWGSLFragmentCode(shadersData.fragment); - } else { - this.computeShader = this._getWGSLComputeCode( - shadersData.compute, - (this.object.workgroupSize || [64]).join(', '), - ); - } - } - - getMethod(method, output = null) { - let wgslMethod; - - if (output !== null) { - wgslMethod = this._getWGSLMethod(method + '_' + output); - } - - if (wgslMethod === undefined) { - wgslMethod = this._getWGSLMethod(method); - } - - return wgslMethod || method; - } - - getType(type) { - return wgslTypeLib[type] || type; - } - - isAvailable(name) { - let result = supports[name]; - - if (result === undefined) { - if (name === 'float32Filterable') { - result = this.renderer.hasFeature('float32-filterable'); - } - - supports[name] = result; - } - - return result; - } - - _getWGSLMethod(method) { - if (wgslPolyfill[method] !== undefined) { - this._include(method); - } - - return wgslMethods[method]; - } - - _include(name) { - const codeNode = wgslPolyfill[name]; - codeNode.build(this); - - if (this.currentFunctionNode !== null) { - this.currentFunctionNode.includes.push(codeNode); - } - - return codeNode; - } - - _getWGSLVertexCode(shaderData) { - return `${this.getSignature()} - -// uniforms -${shaderData.uniforms} - -// varyings -${shaderData.varyings} -var varyings : VaryingsStruct; - -// codes -${shaderData.codes} - -@vertex -fn main( ${shaderData.attributes} ) -> VaryingsStruct { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - - return varyings; - -} -`; - } - - _getWGSLFragmentCode(shaderData) { - return `${this.getSignature()} - -// uniforms -${shaderData.uniforms} - -// structs -${shaderData.structs} - -// codes -${shaderData.codes} - -@fragment -fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - _getWGSLComputeCode(shaderData, workgroupSize) { - return `${this.getSignature()} -// system -var instanceIndex : u32; - -// uniforms -${shaderData.uniforms} - -// codes -${shaderData.codes} - -@compute @workgroup_size( ${workgroupSize} ) -fn main( ${shaderData.attributes} ) { - - // system - instanceIndex = id.x; - - // vars - ${shaderData.vars} - - // flow - ${shaderData.flow} - -} -`; - } - - _getWGSLStruct(name, vars) { - return ` -struct ${name} { -${vars} -};`; - } - - _getWGSLStructBinding(name, vars, access, binding = 0, group = 0) { - const structName = name + 'Struct'; - const structSnippet = this._getWGSLStruct(structName, vars); - - return `${structSnippet} -@binding( ${binding} ) @group( ${group} ) -var<${access}> ${name} : ${structName};`; - } -} - -export default WGSLNodeBuilder; diff --git a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts deleted file mode 100644 index dfe1a2f37..000000000 --- a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeFunction.ts +++ /dev/null @@ -1,127 +0,0 @@ -import NodeFunction from '../../../nodes/core/NodeFunction.js'; -import NodeFunctionInput from '../../../nodes/core/NodeFunctionInput.js'; - -const declarationRegexp = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\-\>]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i; -const propertiesRegexp = /([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi; - -const wgslTypeLib = { - f32: 'float', - i32: 'int', - u32: 'uint', - bool: 'bool', - - 'vec2': 'vec2', - 'vec2': 'ivec2', - 'vec2': 'uvec2', - 'vec2': 'bvec2', - - vec2f: 'vec2', - vec2i: 'ivec2', - vec2u: 'uvec2', - vec2b: 'bvec2', - - 'vec3': 'vec3', - 'vec3': 'ivec3', - 'vec3': 'uvec3', - 'vec3': 'bvec3', - - vec3f: 'vec3', - vec3i: 'ivec3', - vec3u: 'uvec3', - vec3b: 'bvec3', - - 'vec4': 'vec4', - 'vec4': 'ivec4', - 'vec4': 'uvec4', - 'vec4': 'bvec4', - - vec4f: 'vec4', - vec4i: 'ivec4', - vec4u: 'uvec4', - vec4b: 'bvec4', - - 'mat2x2': 'mat2', - mat2x2f: 'mat2', - - 'mat3x3': 'mat3', - mat3x3f: 'mat3', - - 'mat4x4': 'mat4', - mat4x4f: 'mat4', - - sampler: 'sampler', - texture_2d: 'texture', - texture_cube: 'cubeTexture', - texture_depth_2d: 'depthTexture', - texture_storage_2d: 'storageTexture', - texture_3d: 'texture3D', -}; - -const parse = source => { - source = source.trim(); - - const declaration = source.match(declarationRegexp); - - if (declaration !== null && declaration.length === 4) { - const inputsCode = declaration[2]; - const propsMatches = []; - let match = null; - - while ((match = propertiesRegexp.exec(inputsCode)) !== null) { - propsMatches.push({ name: match[1], type: match[2] }); - } - - // Process matches to correctly pair names and types - const inputs = []; - for (let i = 0; i < propsMatches.length; i++) { - const { name, type } = propsMatches[i]; - - let resolvedType = type; - - if (resolvedType.startsWith('texture')) { - resolvedType = type.split('<')[0]; - } - - resolvedType = wgslTypeLib[resolvedType] || resolvedType; - - inputs.push(new NodeFunctionInput(resolvedType, name)); - } - - const blockCode = source.substring(declaration[0].length); - const outputType = declaration[3] || 'void'; - - const name = declaration[1] !== undefined ? declaration[1] : ''; - const type = wgslTypeLib[outputType] || outputType; - - return { - type, - inputs, - name, - inputsCode, - blockCode, - outputType, - }; - } else { - throw new Error('FunctionNode: Function is not a WGSL code.'); - } -}; - -class WGSLNodeFunction extends NodeFunction { - constructor(source) { - const { type, inputs, name, inputsCode, blockCode, outputType } = parse(source); - - super(type, inputs, name); - - this.inputsCode = inputsCode; - this.blockCode = blockCode; - this.outputType = outputType; - } - - getCode(name = this.name) { - const outputType = this.outputType !== 'void' ? '-> ' + this.outputType : ''; - - return `fn ${name} ( ${this.inputsCode.trim()} ) ${outputType}` + this.blockCode; - } -} - -export default WGSLNodeFunction; diff --git a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts b/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts deleted file mode 100644 index c32133df4..000000000 --- a/examples-jsm/examples/renderers/webgpu/nodes/WGSLNodeParser.ts +++ /dev/null @@ -1,10 +0,0 @@ -import NodeParser from '../../../nodes/core/NodeParser.js'; -import WGSLNodeFunction from './WGSLNodeFunction.js'; - -class WGSLNodeParser extends NodeParser { - parseFunction(source) { - return new WGSLNodeFunction(source); - } -} - -export default WGSLNodeParser; From c3ec82da407b190f6af6ca7493fdbb017183c1ff Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Tue, 16 Jul 2024 22:56:58 -0400 Subject: [PATCH 67/72] Update declaration --- types/three/examples/jsm/renderers/common/nodes/Nodes.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/types/three/examples/jsm/renderers/common/nodes/Nodes.d.ts b/types/three/examples/jsm/renderers/common/nodes/Nodes.d.ts index 6c264cd4c..cb7da5ac2 100644 --- a/types/three/examples/jsm/renderers/common/nodes/Nodes.d.ts +++ b/types/three/examples/jsm/renderers/common/nodes/Nodes.d.ts @@ -1,4 +1,4 @@ -import { Camera, Color, CubeTexture, FogBase, Material, Object3D, Scene, Texture } from "three"; +import { Camera, Color, CubeTexture, Fog, FogExp2, Material, Object3D, Scene, Texture } from "three"; import Node from "../../../nodes/core/Node.js"; import NodeBuilder from "../../../nodes/core/NodeBuilder.js"; import UniformGroupNode from "../../../nodes/core/UniformGroupNode.js"; @@ -25,7 +25,7 @@ interface ComputeNodeData { interface SceneData { background?: Color | Texture | CubeTexture | undefined; backgroundNode?: Node | undefined; - fog?: FogBase | undefined; + fog?: Fog | FogExp2 | undefined; fogNode?: Node | undefined; environment?: Texture | undefined; environmentNode?: Node | undefined; From 9ffd1472fbafbd5cbb0790d33996658e8c41597e Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:37:13 -0400 Subject: [PATCH 68/72] Upgrade Object3D JSON schema for improved data structure consistency Upgraded the JSON schema for the Object3D hierarchy. This includes updating interface and type definitions to use the new Object3DJSON utility type and extending it to incorporate Object3DRootJSON. This modification will create a more consistent and modular data structure across various objects like OrthographicCamera, PerspectiveCamera, LOD, InstancedMesh, SkinnedMesh, and Mesh. Additionally, this change allows for the inclusion of new fields like "geometries", "materials", and "textures" in the Object3DRootJSON schema. --- .../three/src/cameras/OrthographicCamera.d.ts | 9 ++++----- .../three/src/cameras/PerspectiveCamera.d.ts | 9 ++++----- types/three/src/core/Object3D.d.ts | 20 ++++++++++++++++--- types/three/src/objects/InstancedMesh.d.ts | 9 ++++----- types/three/src/objects/LOD.d.ts | 9 ++++----- types/three/src/objects/Mesh.d.ts | 9 ++++----- types/three/src/objects/SkinnedMesh.d.ts | 12 +++++------ types/three/src/scenes/Scene.d.ts | 9 ++++----- 8 files changed, 47 insertions(+), 39 deletions(-) diff --git a/types/three/src/cameras/OrthographicCamera.d.ts b/types/three/src/cameras/OrthographicCamera.d.ts index 745d11416..cadba0f0e 100644 --- a/types/three/src/cameras/OrthographicCamera.d.ts +++ b/types/three/src/cameras/OrthographicCamera.d.ts @@ -1,4 +1,4 @@ -import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { JSONMeta, Object3DJSON, Object3DJSONObject, Object3DRootJSON } from "../core/Object3D.js"; import { Camera } from "./Camera.js"; export interface OrthographicCameraJSONObject extends Object3DJSONObject { @@ -21,9 +21,7 @@ export interface OrthographicCameraJSONObject extends Object3DJSONObject { }; } -export interface OrthographicCameraJSON extends Object3DJSON { - object: OrthographicCameraJSONObject; -} +export type OrthographicCameraJSON = Object3DJSON; /** * Camera that uses {@link https://en.wikipedia.org/wiki/Orthographic_projection | orthographic projection}. @@ -170,5 +168,6 @@ export class OrthographicCamera extends Camera { */ clearViewOffset(): void; - toJSON(meta?: JSONMeta): OrthographicCameraJSON; + toJSON(meta: JSONMeta): OrthographicCameraJSON; + toJSON(): Object3DRootJSON } diff --git a/types/three/src/cameras/PerspectiveCamera.d.ts b/types/three/src/cameras/PerspectiveCamera.d.ts index 60567105f..4fa04bc9b 100644 --- a/types/three/src/cameras/PerspectiveCamera.d.ts +++ b/types/three/src/cameras/PerspectiveCamera.d.ts @@ -1,4 +1,4 @@ -import { JSONMeta, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { JSONMeta, Object3DJSON, Object3DJSONObject, Object3DRootJSON } from "../core/Object3D.js"; import { Vector2 } from "../math/Vector2.js"; import { Camera } from "./Camera.js"; @@ -26,9 +26,7 @@ export interface PerspectiveCameraJSONObject extends Object3DJSONObject { filmOffset: number; } -export interface PerspectiveCameraJSON extends Object3DJSON { - object: PerspectiveCameraJSONObject; -} +export type PerspectiveCameraJSON = Object3DJSON; /** * Camera that uses {@link https://en.wikipedia.org/wiki/Perspective_(graphical) | perspective projection}. @@ -250,5 +248,6 @@ export class PerspectiveCamera extends Camera { */ setLens(focalLength: number, frameHeight?: number): void; - toJSON(meta?: JSONMeta): PerspectiveCameraJSON; + toJSON(meta: JSONMeta): PerspectiveCameraJSON; + toJSON(): Object3DRootJSON; } diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index 58ecc8b77..4ac26aa7f 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -42,9 +42,20 @@ export interface Object3DJSONObject { animations?: string[]; } -export interface Object3DJSON { +export interface Object3DJSON { + object: O +} + +export interface Object3DRootJSON extends Object3DJSON { metadata?: { version: number; type: string; generator: string }; - object: Object3DJSONObject; + geometries?: Omit[] + materials?: unknown[] + textures?: Omit[] + images?: SourceJSON[] + shapes?: unknown[] + skeletons?: Omit[] + animations?: AnimationClipJSON[] + nodes?: unknown[] } export interface JSONMeta { @@ -58,6 +69,7 @@ export interface JSONMeta { nodes: Record; } + export interface Object3DEventMap { /** * Fires when the object has been added to its parent object. @@ -652,7 +664,9 @@ export class Object3D ext * Convert the object to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Object containing metadata such as materials, textures or images for the object. */ - toJSON(meta?: JSONMeta): Object3DJSON; + toJSON(): Object3DJSON; + toJSON(meta: JSONMeta): Object3DRootJSON; + /** * Returns a clone of `this` object and optionally all descendants. diff --git a/types/three/src/objects/InstancedMesh.d.ts b/types/three/src/objects/InstancedMesh.d.ts index b239afb7a..e4fa1a619 100644 --- a/types/three/src/objects/InstancedMesh.d.ts +++ b/types/three/src/objects/InstancedMesh.d.ts @@ -1,7 +1,7 @@ import { BufferAttributeJSON } from "./../core/BufferAttribute.js"; import { BufferGeometry } from "../core/BufferGeometry.js"; import { InstancedBufferAttribute } from "../core/InstancedBufferAttribute.js"; -import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; +import { JSONMeta, Object3DEventMap, Object3DJSON, Object3DRootJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Box3 } from "../math/Box3.js"; import { Color } from "../math/Color.js"; @@ -16,9 +16,7 @@ export interface InstancedMeshJSONObject extends MeshJSONObject { instanceColor?: BufferAttributeJSON; } -export interface InstancedMeshJSON extends MeshJSONObject { - object: InstancedMeshJSONObject; -} +export type InstancedMeshJSON = Object3DJSON export interface InstancedMeshEventMap extends Object3DEventMap { dispose: {}; @@ -175,5 +173,6 @@ export class InstancedMesh< */ dispose(): this; - toJSON(meta?: JSONMeta): InstancedMeshJSON; + toJSON(meta: JSONMeta): InstancedMeshJSON; + toJSON(): Object3DRootJSON } diff --git a/types/three/src/objects/LOD.d.ts b/types/three/src/objects/LOD.d.ts index ec6657c7f..1aa306e35 100644 --- a/types/three/src/objects/LOD.d.ts +++ b/types/three/src/objects/LOD.d.ts @@ -1,5 +1,5 @@ import { Camera } from "../cameras/Camera.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject, Object3DRootJSON } from "../core/Object3D.js"; export interface LODJSONObject extends Object3DJSONObject { autoUpdate?: boolean; @@ -11,9 +11,7 @@ export interface LODJSONObject extends Object3DJSONObject { }>; } -export interface LODJSON extends Object3DJSON { - object: LODJSONObject; -} +export type LODJSON = Object3DJSON /** * Every level is associated with an object, and rendering can be switched between them at the distances specified @@ -100,5 +98,6 @@ export class LOD extends */ update(camera: Camera): void; - toJSON(meta?: JSONMeta): LODJSON; + toJSON(meta: JSONMeta): LODJSON; + toJSON(): Object3DRootJSON } diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index 38dad1c73..3b91fd0bf 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -1,5 +1,5 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject, Object3DRootJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Vector3 } from "../math/Vector3.js"; @@ -7,9 +7,7 @@ export interface MeshJSONObject extends Object3DJSONObject { geometry: string; } -export interface MeshJSON extends Object3DJSON { - object: MeshJSONObject; -} +export type MeshJSON = Object3DJSON; /** * Class representing triangular {@link https://en.wikipedia.org/wiki/Polygon_mesh | polygon mesh} based objects. @@ -90,5 +88,6 @@ export class Mesh< */ getVertexPosition(index: number, target: Vector3): Vector3; - toJSON(meta?: JSONMeta): MeshJSON; + toJSON(meta: JSONMeta): MeshJSON; + toJSON(): Object3DRootJSON } diff --git a/types/three/src/objects/SkinnedMesh.d.ts b/types/three/src/objects/SkinnedMesh.d.ts index 35149c5d1..5177a1fb0 100644 --- a/types/three/src/objects/SkinnedMesh.d.ts +++ b/types/three/src/objects/SkinnedMesh.d.ts @@ -1,12 +1,12 @@ import { BindMode } from "../constants.js"; import { BufferGeometry } from "../core/BufferGeometry.js"; -import { JSONMeta, Object3DEventMap } from "../core/Object3D.js"; +import { JSONMeta, Object3DEventMap, Object3DJSON, Object3DRootJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Box3 } from "../math/Box3.js"; import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js"; import { Sphere } from "../math/Sphere.js"; import { Vector3 } from "../math/Vector3.js"; -import { Mesh, MeshJSON, MeshJSONObject } from "./Mesh.js"; +import { Mesh, MeshJSONObject } from "./Mesh.js"; import { Skeleton } from "./Skeleton.js"; export interface SkinnedMeshJSONObject extends MeshJSONObject { @@ -15,9 +15,8 @@ export interface SkinnedMeshJSONObject extends MeshJSONObject { skeleton?: string; } -export interface SkinnedMeshJSON extends MeshJSON { - object: SkinnedMeshJSONObject; -} +export type SkinnedMeshJSON = Object3DJSON + /** * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry. @@ -156,5 +155,6 @@ export class SkinnedMesh< */ applyBoneTransform(index: number, vector: Vector3): Vector3; - toJSON(meta?: JSONMeta): SkinnedMeshJSON; + toJSON(meta: JSONMeta): SkinnedMeshJSON; + toJSON(): Object3DRootJSON } diff --git a/types/three/src/scenes/Scene.d.ts b/types/three/src/scenes/Scene.d.ts index c2f43afd7..10199aca7 100644 --- a/types/three/src/scenes/Scene.d.ts +++ b/types/three/src/scenes/Scene.d.ts @@ -1,4 +1,4 @@ -import { JSONMeta, Object3D, Object3DJSON, Object3DJSONObject } from "../core/Object3D.js"; +import { JSONMeta, Object3D, Object3DJSON, Object3DJSONObject, Object3DRootJSON } from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Color } from "../math/Color.js"; import { Euler, EulerTuple } from "../math/Euler.js"; @@ -18,9 +18,7 @@ export interface SceneJSONObject extends Object3DJSONObject { environmentRotation: EulerTuple; } -export interface SceneJSON extends Object3DJSON { - object: SceneJSONObject; -} +export type SceneJSON = Object3DJSON /** * Scenes allow you to set up what and where is to be rendered by three.js @@ -114,5 +112,6 @@ export class Scene extends Object3D { * Convert the {@link Scene} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Object containing metadata such as textures or images for the scene. */ - toJSON(meta?: JSONMeta): SceneJSON; + toJSON(meta: JSONMeta): SceneJSON; + toJSON(): Object3DRootJSON } From 3304943a23090404c0cdbfe5785431708e7e5387 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 17 Jul 2024 16:43:57 -0400 Subject: [PATCH 69/72] Format --- .../three/src/cameras/OrthographicCamera.d.ts | 2 +- types/three/src/core/Object3D.d.ts | 20 +++++++++---------- types/three/src/objects/InstancedMesh.d.ts | 4 ++-- types/three/src/objects/LOD.d.ts | 13 +++++++++--- types/three/src/objects/Mesh.d.ts | 11 ++++++++-- types/three/src/objects/SkinnedMesh.d.ts | 5 ++--- types/three/src/scenes/Scene.d.ts | 4 ++-- 7 files changed, 35 insertions(+), 24 deletions(-) diff --git a/types/three/src/cameras/OrthographicCamera.d.ts b/types/three/src/cameras/OrthographicCamera.d.ts index cadba0f0e..aeccdf110 100644 --- a/types/three/src/cameras/OrthographicCamera.d.ts +++ b/types/three/src/cameras/OrthographicCamera.d.ts @@ -169,5 +169,5 @@ export class OrthographicCamera extends Camera { clearViewOffset(): void; toJSON(meta: JSONMeta): OrthographicCameraJSON; - toJSON(): Object3DRootJSON + toJSON(): Object3DRootJSON; } diff --git a/types/three/src/core/Object3D.d.ts b/types/three/src/core/Object3D.d.ts index 4ac26aa7f..ab0363ead 100644 --- a/types/three/src/core/Object3D.d.ts +++ b/types/three/src/core/Object3D.d.ts @@ -43,19 +43,19 @@ export interface Object3DJSONObject { } export interface Object3DJSON { - object: O + object: O; } export interface Object3DRootJSON extends Object3DJSON { metadata?: { version: number; type: string; generator: string }; - geometries?: Omit[] - materials?: unknown[] - textures?: Omit[] - images?: SourceJSON[] - shapes?: unknown[] - skeletons?: Omit[] - animations?: AnimationClipJSON[] - nodes?: unknown[] + geometries?: Omit[]; + materials?: unknown[]; + textures?: Omit[]; + images?: SourceJSON[]; + shapes?: unknown[]; + skeletons?: Omit[]; + animations?: AnimationClipJSON[]; + nodes?: unknown[]; } export interface JSONMeta { @@ -69,7 +69,6 @@ export interface JSONMeta { nodes: Record; } - export interface Object3DEventMap { /** * Fires when the object has been added to its parent object. @@ -667,7 +666,6 @@ export class Object3D ext toJSON(): Object3DJSON; toJSON(meta: JSONMeta): Object3DRootJSON; - /** * Returns a clone of `this` object and optionally all descendants. * @param recursive If true, descendants of the object are also cloned. Default `true` diff --git a/types/three/src/objects/InstancedMesh.d.ts b/types/three/src/objects/InstancedMesh.d.ts index e4fa1a619..afcc8a924 100644 --- a/types/three/src/objects/InstancedMesh.d.ts +++ b/types/three/src/objects/InstancedMesh.d.ts @@ -16,7 +16,7 @@ export interface InstancedMeshJSONObject extends MeshJSONObject { instanceColor?: BufferAttributeJSON; } -export type InstancedMeshJSON = Object3DJSON +export type InstancedMeshJSON = Object3DJSON; export interface InstancedMeshEventMap extends Object3DEventMap { dispose: {}; @@ -174,5 +174,5 @@ export class InstancedMesh< dispose(): this; toJSON(meta: JSONMeta): InstancedMeshJSON; - toJSON(): Object3DRootJSON + toJSON(): Object3DRootJSON; } diff --git a/types/three/src/objects/LOD.d.ts b/types/three/src/objects/LOD.d.ts index 1aa306e35..9119b89aa 100644 --- a/types/three/src/objects/LOD.d.ts +++ b/types/three/src/objects/LOD.d.ts @@ -1,5 +1,12 @@ import { Camera } from "../cameras/Camera.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject, Object3DRootJSON } from "../core/Object3D.js"; +import { + JSONMeta, + Object3D, + Object3DEventMap, + Object3DJSON, + Object3DJSONObject, + Object3DRootJSON, +} from "../core/Object3D.js"; export interface LODJSONObject extends Object3DJSONObject { autoUpdate?: boolean; @@ -11,7 +18,7 @@ export interface LODJSONObject extends Object3DJSONObject { }>; } -export type LODJSON = Object3DJSON +export type LODJSON = Object3DJSON; /** * Every level is associated with an object, and rendering can be switched between them at the distances specified @@ -99,5 +106,5 @@ export class LOD extends update(camera: Camera): void; toJSON(meta: JSONMeta): LODJSON; - toJSON(): Object3DRootJSON + toJSON(): Object3DRootJSON; } diff --git a/types/three/src/objects/Mesh.d.ts b/types/three/src/objects/Mesh.d.ts index 3b91fd0bf..7f6f01db7 100644 --- a/types/three/src/objects/Mesh.d.ts +++ b/types/three/src/objects/Mesh.d.ts @@ -1,5 +1,12 @@ import { BufferGeometry } from "../core/BufferGeometry.js"; -import { JSONMeta, Object3D, Object3DEventMap, Object3DJSON, Object3DJSONObject, Object3DRootJSON } from "../core/Object3D.js"; +import { + JSONMeta, + Object3D, + Object3DEventMap, + Object3DJSON, + Object3DJSONObject, + Object3DRootJSON, +} from "../core/Object3D.js"; import { Material } from "../materials/Material.js"; import { Vector3 } from "../math/Vector3.js"; @@ -89,5 +96,5 @@ export class Mesh< getVertexPosition(index: number, target: Vector3): Vector3; toJSON(meta: JSONMeta): MeshJSON; - toJSON(): Object3DRootJSON + toJSON(): Object3DRootJSON; } diff --git a/types/three/src/objects/SkinnedMesh.d.ts b/types/three/src/objects/SkinnedMesh.d.ts index 5177a1fb0..60bd224b6 100644 --- a/types/three/src/objects/SkinnedMesh.d.ts +++ b/types/three/src/objects/SkinnedMesh.d.ts @@ -15,8 +15,7 @@ export interface SkinnedMeshJSONObject extends MeshJSONObject { skeleton?: string; } -export type SkinnedMeshJSON = Object3DJSON - +export type SkinnedMeshJSON = Object3DJSON; /** * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry. @@ -156,5 +155,5 @@ export class SkinnedMesh< applyBoneTransform(index: number, vector: Vector3): Vector3; toJSON(meta: JSONMeta): SkinnedMeshJSON; - toJSON(): Object3DRootJSON + toJSON(): Object3DRootJSON; } diff --git a/types/three/src/scenes/Scene.d.ts b/types/three/src/scenes/Scene.d.ts index 10199aca7..bcbe8b88e 100644 --- a/types/three/src/scenes/Scene.d.ts +++ b/types/three/src/scenes/Scene.d.ts @@ -18,7 +18,7 @@ export interface SceneJSONObject extends Object3DJSONObject { environmentRotation: EulerTuple; } -export type SceneJSON = Object3DJSON +export type SceneJSON = Object3DJSON; /** * Scenes allow you to set up what and where is to be rendered by three.js @@ -113,5 +113,5 @@ export class Scene extends Object3D { * @param meta Object containing metadata such as textures or images for the scene. */ toJSON(meta: JSONMeta): SceneJSON; - toJSON(): Object3DRootJSON + toJSON(): Object3DRootJSON; } From f290493bdb921c061bbbed5bd1e0abfc87c1b8a6 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:19:19 -0400 Subject: [PATCH 70/72] Refactor KeyframeTrack base class and related types for better type safety Generic types to the KeyframeTrack base class and its derived types (BooleanKeyframeTrack, ColorKeyframeTrack, etc.). The updates involve altering the exported interfaces (KeyframeTrackJSON and KeyframeTrack) to accept and maintain more specific types (boolean, number, string, or array-like), and adjusting the constructors accordingly. --- types/three/src/animation/KeyframeTrack.d.ts | 20 ++++++++++--------- .../tracks/BooleanKeyframeTrack.d.ts | 6 +++--- .../animation/tracks/ColorKeyframeTrack.d.ts | 4 ++-- .../animation/tracks/NumberKeyframeTrack.d.ts | 4 ++-- .../tracks/QuaternionKeyframeTrack.d.ts | 4 ++-- .../animation/tracks/StringKeyframeTrack.d.ts | 6 +++--- .../animation/tracks/VectorKeyframeTrack.d.ts | 4 ++-- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/types/three/src/animation/KeyframeTrack.d.ts b/types/three/src/animation/KeyframeTrack.d.ts index 2a48e2651..4e39621de 100644 --- a/types/three/src/animation/KeyframeTrack.d.ts +++ b/types/three/src/animation/KeyframeTrack.d.ts @@ -4,30 +4,30 @@ import { CubicInterpolant } from "../math/interpolants/CubicInterpolant.js"; import { DiscreteInterpolant } from "../math/interpolants/DiscreteInterpolant.js"; import { LinearInterpolant } from "../math/interpolants/LinearInterpolant.js"; -export interface KeyframeTrackJSON { +export interface KeyframeTrackJSON { name: string; times: number[]; - values: number[]; + values: V[]; interpolation?: InterpolationModes; - type: string; + type: T; } -export class KeyframeTrack { +export class KeyframeTrack { /** * @param name * @param times * @param values * @param [interpolation=THREE.InterpolateLinear] */ - constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); + constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); name: string; times: Float32Array; - values: Float32Array; + values: ArrayLike; ValueTypeName: string; - TimeBufferType: Float32Array; - ValueBufferType: Float32Array; + TimeBufferType: typeof Float32Array; + ValueBufferType: typeof Float32Array | typeof Array; /** * @default THREE.InterpolateLinear @@ -51,5 +51,7 @@ export class KeyframeTrack { optimize(): KeyframeTrack; clone(): this; - static toJSON(track: KeyframeTrack): KeyframeTrackJSON; + static toJSON( + track: Track, + ): KeyframeTrackJSON ? V : never, Track["ValueTypeName"]>; } diff --git a/types/three/src/animation/tracks/BooleanKeyframeTrack.d.ts b/types/three/src/animation/tracks/BooleanKeyframeTrack.d.ts index 45b65448a..c3656e75f 100644 --- a/types/three/src/animation/tracks/BooleanKeyframeTrack.d.ts +++ b/types/three/src/animation/tracks/BooleanKeyframeTrack.d.ts @@ -1,10 +1,10 @@ import { KeyframeTrack } from "../KeyframeTrack.js"; -export class BooleanKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike); +export class BooleanKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike); /** * @default 'bool' */ - ValueTypeName: string; + ValueTypeName: "bool"; } diff --git a/types/three/src/animation/tracks/ColorKeyframeTrack.d.ts b/types/three/src/animation/tracks/ColorKeyframeTrack.d.ts index 60d0fe9f7..58428a916 100644 --- a/types/three/src/animation/tracks/ColorKeyframeTrack.d.ts +++ b/types/three/src/animation/tracks/ColorKeyframeTrack.d.ts @@ -1,11 +1,11 @@ import { InterpolationModes } from "../../constants.js"; import { KeyframeTrack } from "../KeyframeTrack.js"; -export class ColorKeyframeTrack extends KeyframeTrack { +export class ColorKeyframeTrack extends KeyframeTrack { constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); /** * @default 'color' */ - ValueTypeName: string; + ValueTypeName: "color"; } diff --git a/types/three/src/animation/tracks/NumberKeyframeTrack.d.ts b/types/three/src/animation/tracks/NumberKeyframeTrack.d.ts index e27ff0337..8e18bee74 100644 --- a/types/three/src/animation/tracks/NumberKeyframeTrack.d.ts +++ b/types/three/src/animation/tracks/NumberKeyframeTrack.d.ts @@ -1,11 +1,11 @@ import { InterpolationModes } from "../../constants.js"; import { KeyframeTrack } from "../KeyframeTrack.js"; -export class NumberKeyframeTrack extends KeyframeTrack { +export class NumberKeyframeTrack extends KeyframeTrack { constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); /** * @default 'number' */ - ValueTypeName: string; + ValueTypeName: "number"; } diff --git a/types/three/src/animation/tracks/QuaternionKeyframeTrack.d.ts b/types/three/src/animation/tracks/QuaternionKeyframeTrack.d.ts index 29942bad5..6a60fd29c 100644 --- a/types/three/src/animation/tracks/QuaternionKeyframeTrack.d.ts +++ b/types/three/src/animation/tracks/QuaternionKeyframeTrack.d.ts @@ -1,11 +1,11 @@ import { InterpolationModes } from "../../constants.js"; import { KeyframeTrack } from "../KeyframeTrack.js"; -export class QuaternionKeyframeTrack extends KeyframeTrack { +export class QuaternionKeyframeTrack extends KeyframeTrack { constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); /** * @default 'quaternion' */ - ValueTypeName: string; + ValueTypeName: "quaternion"; } diff --git a/types/three/src/animation/tracks/StringKeyframeTrack.d.ts b/types/three/src/animation/tracks/StringKeyframeTrack.d.ts index 9bbfd2027..a3d2c1e88 100644 --- a/types/three/src/animation/tracks/StringKeyframeTrack.d.ts +++ b/types/three/src/animation/tracks/StringKeyframeTrack.d.ts @@ -1,10 +1,10 @@ import { KeyframeTrack } from "../KeyframeTrack.js"; -export class StringKeyframeTrack extends KeyframeTrack { - constructor(name: string, times: ArrayLike, values: ArrayLike); +export class StringKeyframeTrack extends KeyframeTrack { + constructor(name: string, times: ArrayLike, values: ArrayLike); /** * @default 'string' */ - ValueTypeName: string; + ValueTypeName: "string"; } diff --git a/types/three/src/animation/tracks/VectorKeyframeTrack.d.ts b/types/three/src/animation/tracks/VectorKeyframeTrack.d.ts index 0909d4493..626dce316 100644 --- a/types/three/src/animation/tracks/VectorKeyframeTrack.d.ts +++ b/types/three/src/animation/tracks/VectorKeyframeTrack.d.ts @@ -1,11 +1,11 @@ import { InterpolationModes } from "../../constants.js"; import { KeyframeTrack } from "../KeyframeTrack.js"; -export class VectorKeyframeTrack extends KeyframeTrack { +export class VectorKeyframeTrack extends KeyframeTrack { constructor(name: string, times: ArrayLike, values: ArrayLike, interpolation?: InterpolationModes); /** * @default 'vector' */ - ValueTypeName: string; + ValueTypeName: "vector"; } From f0189801c44f089626f8cb96f079f9933e0489c9 Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:33:33 -0400 Subject: [PATCH 71/72] Add JSONMeta to Texture.toJSON meta arg --- types/three/src/textures/Texture.d.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/types/three/src/textures/Texture.d.ts b/types/three/src/textures/Texture.d.ts index 48a178966..80699218e 100644 --- a/types/three/src/textures/Texture.d.ts +++ b/types/three/src/textures/Texture.d.ts @@ -13,6 +13,7 @@ import { import { EventDispatcher } from "../core/EventDispatcher.js"; import { Matrix3 } from "../math/Matrix3.js"; import { Vector2 } from "../math/Vector2.js"; +import { JSONMeta } from "../Three.js"; import { CompressedTextureMipmap } from "./CompressedTexture.js"; import { CubeTexture } from "./CubeTexture.js"; import { Source } from "./Source.js"; @@ -55,7 +56,7 @@ export interface TextureJSON { /** Shim for OffscreenCanvas. */ // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface OffscreenCanvas extends EventTarget {} +export interface OffscreenCanvas extends EventTarget { } /** * Create a {@link Texture} to apply to a surface or as a reflection or refraction map. @@ -467,7 +468,7 @@ export class Texture extends EventDispatcher<{ dispose: {} }> { * Convert the texture to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Optional object containing metadata. */ - toJSON(meta?: string | {}): TextureJSON; + toJSON(meta?: string | JSONMeta): TextureJSON; /** * Frees the GPU-related resources allocated by this instance From 8641cd5fcb358724570bac772e89bb27bf0b513b Mon Sep 17 00:00:00 2001 From: Drex Benjamin <45743294+Hoodgail@users.noreply.github.com> Date: Wed, 17 Jul 2024 17:34:28 -0400 Subject: [PATCH 72/72] Add JSONMeta to Source.toJSON meta arg --- types/three/src/textures/Source.d.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/types/three/src/textures/Source.d.ts b/types/three/src/textures/Source.d.ts index 404d1d8a1..6a95dd1dd 100644 --- a/types/three/src/textures/Source.d.ts +++ b/types/three/src/textures/Source.d.ts @@ -1,3 +1,5 @@ +import { JSONMeta } from "../Three.js"; + export type SerializedImage = | string | { @@ -71,5 +73,5 @@ export class Source { * Convert the data {@link Source} to three.js {@link https://github.com/mrdoob/three.js/wiki/JSON-Object-Scene-format-4 | JSON Object/Scene format}. * @param meta Optional object containing metadata. */ - toJSON(meta?: string | {}): SourceJSON; + toJSON(meta?: string | JSONMeta): SourceJSON; }