diff --git a/editor/package.json b/editor/package.json index f0598bd6a..3f53640b8 100644 --- a/editor/package.json +++ b/editor/package.json @@ -23,6 +23,7 @@ "license": "(Apache-2.0)", "devDependencies": { "@electron/rebuild": "4.0.2", + "@types/adm-zip": "^0.5.7", "@types/decompress": "4.2.7", "@types/fluent-ffmpeg": "^2.1.27", "@types/node": "^22", @@ -59,6 +60,8 @@ "@radix-ui/react-menubar": "^1.0.4", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", + "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slider": "^1.2.0", @@ -68,11 +71,11 @@ "@radix-ui/react-toggle": "^1.1.1", "@radix-ui/react-toggle-group": "1.1.11", "@radix-ui/react-tooltip": "^1.0.7", - "@radix-ui/react-radio-group": "^1.1.3", "@recast-navigation/core": "0.43.0", "@recast-navigation/generators": "0.43.0", "@xterm/addon-fit": "0.11.0", "@xterm/xterm": "6.1.0-beta.22", + "adm-zip": "^0.5.16", "assimpjs": "0.0.10", "axios": "1.12.0", "babylonjs": "8.41.0", @@ -103,6 +106,7 @@ "framer-motion": "12.23.24", "fs-extra": "11.2.0", "glob": "11.1.0", + "js-yaml": "^4.1.1", "markdown-to-jsx": "7.6.2", "math-expression-evaluator": "^2.0.6", "md5": "2.3.0", diff --git a/editor/src/editor/layout/assets-browser.tsx b/editor/src/editor/layout/assets-browser.tsx index b741b5135..7993aa350 100644 --- a/editor/src/editor/layout/assets-browser.tsx +++ b/editor/src/editor/layout/assets-browser.tsx @@ -1,4 +1,4 @@ -import { clipboard, webUtils } from "electron"; +import { clipboard, webUtils, ipcRenderer } from "electron"; import { dirname, join, extname, basename } from "path/posix"; import { copyFile, copy, mkdir, move, pathExists, readdir, stat, writeFile, writeJSON } from "fs-extra"; @@ -818,6 +818,8 @@ export class EditorAssetsBrowser extends Component this._handleAddFullScreenGUI()}>Fullscreen GUI + + this._handleAddFX()}>FX ); } @@ -1259,6 +1261,25 @@ export class EditorAssetsBrowser extends Component { + if (!this.state.browsedPath) { + return; + } + + const name = await findAvailableFilename(this.state.browsedPath, "New Effect", ".fx"); + const defaultEffectFile = { + version: "1.0.0", + effects: [], + }; + + await writeJSON(join(this.state.browsedPath, name), defaultEffectFile, { + spaces: "\t", + encoding: "utf-8", + }); + + return this._refreshItems(this.state.browsedPath); + } + private async _handleAddFullScreenGUI(): Promise { if (!this.state.browsedPath) { return; @@ -1421,9 +1442,14 @@ export class EditorAssetsBrowser extends Component void; +} + +export interface IEditorInspectorGeometryFieldState { + dragOver: boolean; + loading: boolean; +} + +export class EditorInspectorGeometryField extends Component { + public constructor(props: IEditorInspectorGeometryFieldProps) { + super(props); + + this.state = { + dragOver: false, + loading: false, + }; + } + + public render(): ReactNode { + const mesh = this.props.object[this.props.property] as Mesh | null | undefined; + + return ( +
this._handleDrop(ev)} + onDragOver={(ev) => this._handleDragOver(ev)} + onDragLeave={(ev) => this._handleDragLeave(ev)} + className={`flex flex-col w-full p-5 rounded-lg ${this.state.dragOver ? "bg-muted-foreground/75 dark:bg-muted-foreground/20" : "bg-muted-foreground/10 dark:bg-muted-foreground/5"} transition-all duration-300 ease-in-out`} + > +
+ {this._getPreviewComponent(mesh)} + +
+
+
{this.props.title}
+ {mesh &&
{mesh.name}
} +
+ + {mesh && ( +
+
+
Vertices
+
+
{mesh.getTotalVertices()}
+
+
+
+
Faces
+
+
{mesh.getTotalIndices() ? mesh.getTotalIndices() / 3 : 0}
+
+
+
+ )} +
+
{ + const oldMesh = this.props.object[this.props.property]; + + this.props.object[this.props.property] = null; + this.props.onChange?.(null); + + if (!this.props.noUndoRedo) { + registerUndoRedo({ + executeRedo: true, + undo: () => { + this.props.object[this.props.property] = oldMesh; + }, + redo: () => { + this.props.object[this.props.property] = null; + }, + }); + } + + this.forceUpdate(); + }} + className="flex justify-center items-center w-24 h-full hover:bg-muted-foreground rounded-lg transition-all duration-300" + > + {mesh && } +
+
+ + {mesh && this.props.children} +
+ ); + } + + private _getPreviewComponent(mesh: Mesh | null | undefined): ReactNode { + return ( +
+ {mesh ? ( +
+
{mesh.name}
+
+ ) : ( + + )} +
+ ); + } + + private _handleDragOver(ev: DragEvent): void { + ev.preventDefault(); + this.setState({ dragOver: true }); + } + + private _handleDragLeave(ev: DragEvent): void { + ev.preventDefault(); + this.setState({ dragOver: false }); + } + + private async _handleDrop(ev: DragEvent): Promise { + ev.preventDefault(); + this.setState({ dragOver: false, loading: true }); + + try { + const absolutePath = JSON.parse(ev.dataTransfer.getData("assets"))[0]; + const extension = extname(absolutePath).toLowerCase(); + + const supportedExtensions = [".x", ".b3d", ".dae", ".glb", ".gltf", ".fbx", ".stl", ".lwo", ".dxf", ".obj", ".3ds", ".ms3d", ".blend", ".babylon"]; + + if (!supportedExtensions.includes(extension)) { + toast.error(`Unsupported geometry format: ${extension}`); + this.setState({ loading: false }); + return; + } + + const scene = this.props.scene ?? (isScene(this.props.object) ? this.props.object : this.props.object.getScene?.()); + + if (!scene) { + toast.error("Scene is not available"); + this.setState({ loading: false }); + return; + } + + const result = await loadImportedSceneFile(scene, absolutePath); + + if (!result || !result.meshes || result.meshes.length === 0) { + toast.error("Failed to load geometry file"); + this.setState({ loading: false }); + return; + } + + // Use the first mesh or find a mesh without parent + let importedMesh: Mesh | null = null; + for (const m of result.meshes) { + if (m instanceof Mesh && !m.parent) { + importedMesh = m; + break; + } + } + + if (!importedMesh && result.meshes.length > 0 && result.meshes[0] instanceof Mesh) { + importedMesh = result.meshes[0]; + } + + if (!importedMesh) { + toast.error("No valid mesh found in geometry file"); + this.setState({ loading: false }); + return; + } + + // Configure imported mesh + configureImportedNodeIds(importedMesh); + importedMesh.setEnabled(false); // Hide the source mesh + + const oldMesh = this.props.object[this.props.property]; + + this.props.object[this.props.property] = importedMesh; + this.props.onChange?.(importedMesh); + + if (!this.props.noUndoRedo) { + registerUndoRedo({ + executeRedo: true, + undo: () => { + this.props.object[this.props.property] = oldMesh; + if (importedMesh && importedMesh !== oldMesh) { + importedMesh.dispose(); + } + }, + redo: () => { + this.props.object[this.props.property] = importedMesh; + }, + onLost: () => { + if (importedMesh && importedMesh !== oldMesh) { + importedMesh.dispose(); + } + }, + }); + } + + // Dispose other meshes from the imported file + for (const m of result.meshes) { + if (m !== importedMesh) { + m.dispose(); + } + } + + // Dispose transform nodes + for (const tn of result.transformNodes) { + tn.dispose(); + } + + this.forceUpdate(); + } catch (error) { + console.error("Failed to load geometry:", error); + toast.error(`Failed to load geometry: ${error instanceof Error ? error.message : String(error)}`); + } finally { + this.setState({ loading: false }); + } + } +} diff --git a/editor/src/editor/layout/inspector/fields/gradient.tsx b/editor/src/editor/layout/inspector/fields/gradient.tsx new file mode 100644 index 000000000..2c51755d6 --- /dev/null +++ b/editor/src/editor/layout/inspector/fields/gradient.tsx @@ -0,0 +1,179 @@ +import { useState } from "react"; +import { Button, Popover } from "@blueprintjs/core"; +import { GradientPicker, type IGradientKey } from "../../../../ui/gradient-picker"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../../../../ui/shadcn/ui/tooltip"; +import { MdOutlineInfo } from "react-icons/md"; +import { registerUndoRedo } from "../../../../tools/undoredo"; +import { getInspectorPropertyValue } from "../../../../tools/property"; +import { IEditorInspectorFieldProps } from "./field"; + +export interface IEditorInspectorColorGradientFieldProps extends IEditorInspectorFieldProps { + onChange?: (colorKeys: IGradientKey[], alphaKeys?: IGradientKey[]) => void; + onFinishChange?: (colorKeys: IGradientKey[], alphaKeys?: IGradientKey[], oldColorKeys?: IGradientKey[], oldAlphaKeys?: IGradientKey[]) => void; +} + +/** + * Inspector field for editing color gradients + * Works with objects that have colorKeys and alphaKeys properties + * Similar to EditorInspectorColorField but for gradients + */ +export function EditorInspectorColorGradientField(props: IEditorInspectorColorGradientFieldProps) { + // Get colorKeys and alphaKeys from object + const getColorKeys = (): IGradientKey[] => { + if (props.property) { + return (getInspectorPropertyValue(props.object, `${props.property}.colorKeys`) || []) as IGradientKey[]; + } + return ((props.object as any)?.colorKeys || []) as IGradientKey[]; + }; + + const getAlphaKeys = (): IGradientKey[] => { + if (props.property) { + return (getInspectorPropertyValue(props.object, `${props.property}.alphaKeys`) || []) as IGradientKey[]; + } + return ((props.object as any)?.alphaKeys || []) as IGradientKey[]; + }; + + const colorKeys = getColorKeys(); + const alphaKeys = getAlphaKeys(); + + const [value, setValue] = useState({ colorKeys, alphaKeys }); + const [oldValue, setOldValue] = useState({ colorKeys: [...colorKeys], alphaKeys: [...alphaKeys] }); + + // Generate preview gradient CSS + const generatePreview = (): string => { + const sorted = [...value.colorKeys].sort((a, b) => (a.pos || 0) - (b.pos || 0)); + if (sorted.length === 0) { + return "linear-gradient(to right, rgba(0, 0, 0, 1) 0%, rgba(1, 1, 1, 1) 100%)"; + } + + const stops = sorted.map((key) => { + const pos = (key.pos || 0) * 100; + let color = "rgba(0, 0, 0, 1)"; + if (Array.isArray(key.value)) { + const [r, g, b, a = 1] = key.value; + color = `rgba(${r * 255}, ${g * 255}, ${b * 255}, ${a})`; + } else if (typeof key.value === "object" && "r" in key.value) { + const r = key.value.r * 255; + const g = key.value.g * 255; + const b = key.value.b * 255; + const a = ("a" in key.value && key.value.a !== undefined ? key.value.a : 1) * 255; + color = `rgba(${r}, ${g}, ${b}, ${a / 255})`; + } + return `${color} ${pos}%`; + }); + return `linear-gradient(to right, ${stops.join(", ")})`; + }; + + function getPopoverContent() { + return ( + { + const updatedValue = { colorKeys: newColorKeys, alphaKeys: newAlphaKeys || value.alphaKeys }; + setValue(updatedValue); + + // Update object properties + if (props.object && props.property) { + (props.object as any)[props.property] = { + ...(props.object as any)[props.property], + colorKeys: newColorKeys, + alphaKeys: newAlphaKeys || value.alphaKeys, + }; + } + + props.onChange?.(newColorKeys, newAlphaKeys); + }} + onFinish={(newColorKeys, newAlphaKeys) => { + const updatedValue = { colorKeys: newColorKeys, alphaKeys: newAlphaKeys || value.alphaKeys }; + setValue(updatedValue); + + // Update object properties + if (props.object) { + if (props.property) { + (props.object as any)[props.property] = { + ...(props.object as any)[props.property], + colorKeys: newColorKeys, + alphaKeys: newAlphaKeys || value.alphaKeys, + }; + } else { + (props.object as any).colorKeys = newColorKeys; + (props.object as any).alphaKeys = newAlphaKeys || value.alphaKeys; + } + } + + if (!props.noUndoRedo) { + const newValue = { colorKeys: [...newColorKeys], alphaKeys: [...(newAlphaKeys || value.alphaKeys)] }; + + registerUndoRedo({ + undo: () => { + if (props.object) { + if (props.property) { + (props.object as any)[props.property] = { + ...(props.object as any)[props.property], + colorKeys: oldValue.colorKeys, + alphaKeys: oldValue.alphaKeys, + }; + } else { + (props.object as any).colorKeys = oldValue.colorKeys; + (props.object as any).alphaKeys = oldValue.alphaKeys; + } + } + setValue(oldValue); + }, + redo: () => { + if (props.object) { + if (props.property) { + (props.object as any)[props.property] = { + ...(props.object as any)[props.property], + colorKeys: newValue.colorKeys, + alphaKeys: newValue.alphaKeys, + }; + } else { + (props.object as any).colorKeys = newValue.colorKeys; + (props.object as any).alphaKeys = newValue.alphaKeys; + } + } + setValue(newValue); + }, + }); + + setOldValue(newValue); + } + + props.onFinishChange?.(newColorKeys, newAlphaKeys || value.alphaKeys, oldValue.colorKeys, oldValue.alphaKeys); + }} + /> + ); + } + + return ( +
+
+ {props.label} + + {props.tooltip && ( + + + + + + {props.tooltip} + + + )} +
+ +
+ +
+
+ ); +} diff --git a/editor/src/editor/layout/inspector/fields/vector.tsx b/editor/src/editor/layout/inspector/fields/vector.tsx index e2447bbb1..24977e195 100644 --- a/editor/src/editor/layout/inspector/fields/vector.tsx +++ b/editor/src/editor/layout/inspector/fields/vector.tsx @@ -22,10 +22,15 @@ export interface IEditorInspectorVectorFieldProps extends IEditorInspectorFieldP } export function EditorInspectorVectorField(props: IEditorInspectorVectorFieldProps) { - const value = props.object[props.property] as IVector4Like; + const value = props.object?.[props.property] as IVector4Like | undefined; const [pointerOver, setPointerOver] = useState(false); + // Return null if value is undefined or null + if (!value || typeof value !== "object") { + return null; + } + return (
setPointerOver(true)} onMouseLeave={() => setPointerOver(false)}>
{ + public render(): ReactNode { + return ( +
+
Animation Panel
+
Animation timeline will be displayed here
+
+ ); + } +} diff --git a/editor/src/editor/windows/effect-editor/converters/index.ts b/editor/src/editor/windows/effect-editor/converters/index.ts new file mode 100644 index 000000000..76a222ac3 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/index.ts @@ -0,0 +1,2 @@ +export * from "./quarksConverter"; +export * from "./unityConverter"; diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/behaviorConverter.ts b/editor/src/editor/windows/effect-editor/converters/quarks/behaviorConverter.ts new file mode 100644 index 000000000..bd53059d3 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/behaviorConverter.ts @@ -0,0 +1,295 @@ +import type { + IQuarksBehavior, + IQuarksColorOverLifeBehavior, + IQuarksSizeOverLifeBehavior, + IQuarksRotationOverLifeBehavior, + IQuarksForceOverLifeBehavior, + IQuarksGravityForceBehavior, + IQuarksSpeedOverLifeBehavior, + IQuarksFrameOverLifeBehavior, + IQuarksLimitSpeedOverLifeBehavior, + IQuarksColorBySpeedBehavior, + IQuarksSizeBySpeedBehavior, + IQuarksRotationBySpeedBehavior, + IQuarksOrbitOverLifeBehavior, + IQuarksGradientColor, + IQuarksConstantColorColor, + IQuarksRandomColorBetweenGradient, + IQuarksGradientKey, +} from "./types"; +import type { Behavior, IColorFunction, IForceOverLifeBehavior, ISpeedOverLifeBehavior, ILimitSpeedOverLifeBehavior, ISizeBySpeedBehavior } from "babylonjs-editor-tools"; +import { convertOptionalValue } from "./valueConverter"; +import { convertGradientKeys, convertSpeedOrFrameValue } from "./resourceConverter"; +import { extractConstantColor } from "./colorConverter"; + +/** + * Convert IQuarks behavior to behavior + */ +export function convertBehavior(behavior: IQuarksBehavior): Behavior { + switch (behavior.type) { + case "ColorOverLife": + return convertColorOverLifeBehavior(behavior as IQuarksColorOverLifeBehavior); + case "SizeOverLife": + return convertSizeOverLifeBehavior(behavior as IQuarksSizeOverLifeBehavior); + case "RotationOverLife": + case "Rotation3DOverLife": + return convertRotationOverLifeBehavior(behavior as IQuarksRotationOverLifeBehavior); + case "ForceOverLife": + case "ApplyForce": + return convertForceOverLifeBehavior(behavior as IQuarksForceOverLifeBehavior); + case "GravityForce": + return convertGravityForceBehavior(behavior as IQuarksGravityForceBehavior); + case "SpeedOverLife": + return convertSpeedOverLifeBehavior(behavior as IQuarksSpeedOverLifeBehavior); + case "FrameOverLife": + return convertFrameOverLifeBehavior(behavior as IQuarksFrameOverLifeBehavior); + case "LimitSpeedOverLife": + return convertLimitSpeedOverLifeBehavior(behavior as IQuarksLimitSpeedOverLifeBehavior); + case "ColorBySpeed": + return convertColorBySpeedBehavior(behavior as IQuarksColorBySpeedBehavior); + case "SizeBySpeed": + return convertSizeBySpeedBehavior(behavior as IQuarksSizeBySpeedBehavior); + case "RotationBySpeed": + return convertRotationBySpeedBehavior(behavior as IQuarksRotationBySpeedBehavior); + case "OrbitOverLife": + return convertOrbitOverLifeBehavior(behavior as IQuarksOrbitOverLifeBehavior); + default: + // Fallback for unknown behaviors - copy as-is + return behavior as Behavior; + } +} + +/** + * Convert ColorOverLife behavior + */ +function convertColorOverLifeBehavior(behavior: IQuarksColorOverLifeBehavior): Behavior { + if (!behavior.color) { + return { + type: "ColorOverLife", + color: { + colorFunctionType: "ConstantColor", + data: {}, + }, + }; + } + + const colorType = behavior.color.type; + let colorFunction: IColorFunction; + + if (colorType === "Gradient") { + const gradientColor = behavior.color as IQuarksGradientColor; + colorFunction = { + colorFunctionType: "Gradient", + data: { + colorKeys: convertGradientKeys(gradientColor.color?.keys), + alphaKeys: convertGradientKeys(gradientColor.alpha?.keys), + }, + }; + } else if (colorType === "ConstantColor") { + const constantColor = behavior.color as IQuarksConstantColorColor; + const color = extractConstantColor(constantColor); + colorFunction = { + colorFunctionType: "ConstantColor", + data: { + color: { + r: color.r ?? 1, + g: color.g ?? 1, + b: color.b ?? 1, + a: color.a !== undefined ? color.a : 1, + }, + }, + }; + } else if (colorType === "RandomColorBetweenGradient") { + const randomColor = behavior.color as IQuarksRandomColorBetweenGradient; + colorFunction = { + colorFunctionType: "RandomColorBetweenGradient", + data: { + gradient1: { + colorKeys: convertGradientKeys(randomColor.gradient1?.color?.keys), + alphaKeys: convertGradientKeys(randomColor.gradient1?.alpha?.keys), + }, + gradient2: { + colorKeys: convertGradientKeys(randomColor.gradient2?.color?.keys), + alphaKeys: convertGradientKeys(randomColor.gradient2?.alpha?.keys), + }, + }, + }; + } else { + // Fallback: try to detect format from keys + const colorData = behavior.color as { + color?: { keys?: IQuarksGradientKey[] }; + alpha?: { keys?: IQuarksGradientKey[] }; + keys?: IQuarksGradientKey[]; + }; + const hasColorKeys = colorData.color?.keys && colorData.color.keys.length > 0; + const hasAlphaKeys = colorData.alpha?.keys && colorData.alpha.keys.length > 0; + const hasKeys = colorData.keys && colorData.keys.length > 0; + + if (hasColorKeys || hasAlphaKeys || hasKeys) { + const colorKeys = hasColorKeys ? convertGradientKeys(colorData.color?.keys) : hasKeys ? convertGradientKeys(colorData.keys) : []; + const alphaKeys = hasAlphaKeys ? convertGradientKeys(colorData.alpha?.keys) : []; + colorFunction = { + colorFunctionType: "Gradient", + data: { + colorKeys, + alphaKeys, + }, + }; + } else { + // Default to ConstantColor + colorFunction = { + colorFunctionType: "ConstantColor", + data: {}, + }; + } + } + + return { + type: "ColorOverLife", + color: colorFunction, + }; +} + +/** + * Convert SizeOverLife behavior + */ +function convertSizeOverLifeBehavior(behavior: IQuarksSizeOverLifeBehavior): Behavior { + if (!behavior.size) { + return { type: "SizeOverLife" }; + } + return { + type: "SizeOverLife", + size: { + ...(behavior.size.keys && { keys: convertGradientKeys(behavior.size.keys) }), + ...(behavior.size.functions && { functions: behavior.size.functions }), + }, + }; +} + +/** + * Convert RotationOverLife behavior + */ +function convertRotationOverLifeBehavior(behavior: IQuarksRotationOverLifeBehavior): Behavior { + return { + type: behavior.type, + angularVelocity: convertOptionalValue(behavior.angularVelocity), + }; +} + +/** + * Convert ForceOverLife behavior + */ +function convertForceOverLifeBehavior(behavior: IQuarksForceOverLifeBehavior): Behavior { + const result: IForceOverLifeBehavior = { type: behavior.type }; + if (behavior.force) { + result.force = { + x: convertOptionalValue(behavior.force.x), + y: convertOptionalValue(behavior.force.y), + z: convertOptionalValue(behavior.force.z), + }; + } + result.x = convertOptionalValue(behavior.x); + result.y = convertOptionalValue(behavior.y); + result.z = convertOptionalValue(behavior.z); + return result; +} + +/** + * Convert GravityForce behavior + */ +function convertGravityForceBehavior(behavior: IQuarksGravityForceBehavior): Behavior { + return { + type: "GravityForce", + gravity: convertOptionalValue(behavior.gravity), + } as Behavior; +} + +/** + * Convert SpeedOverLife behavior + */ +function convertSpeedOverLifeBehavior(behavior: IQuarksSpeedOverLifeBehavior): Behavior { + const speed = convertSpeedOrFrameValue(behavior.speed); + return { type: "SpeedOverLife", ...(speed !== undefined && { speed }) } as ISpeedOverLifeBehavior; +} + +/** + * Convert FrameOverLife behavior + */ +function convertFrameOverLifeBehavior(behavior: IQuarksFrameOverLifeBehavior): Behavior { + const frame = convertSpeedOrFrameValue(behavior.frame); + return { type: "FrameOverLife", ...(frame !== undefined && { frame }) } as Behavior; +} + +/** + * Convert LimitSpeedOverLife behavior + */ +function convertLimitSpeedOverLifeBehavior(behavior: IQuarksLimitSpeedOverLifeBehavior): Behavior { + const speed = convertSpeedOrFrameValue(behavior.speed); + return { + type: "LimitSpeedOverLife", + maxSpeed: convertOptionalValue(behavior.maxSpeed), + ...(speed !== undefined && { speed }), + dampen: convertOptionalValue(behavior.dampen), + } as ILimitSpeedOverLifeBehavior; +} + +/** + * Convert ColorBySpeed behavior + */ +function convertColorBySpeedBehavior(behavior: IQuarksColorBySpeedBehavior): Behavior { + const colorFunction: IColorFunction = behavior.color?.keys + ? { + colorFunctionType: "Gradient", + data: { + colorKeys: convertGradientKeys(behavior.color.keys), + alphaKeys: [], + }, + } + : { + colorFunctionType: "ConstantColor", + data: {}, + }; + + return { + type: "ColorBySpeed", + color: colorFunction, + minSpeed: convertOptionalValue(behavior.minSpeed), + maxSpeed: convertOptionalValue(behavior.maxSpeed), + }; +} + +/** + * Convert SizeBySpeed behavior + */ +function convertSizeBySpeedBehavior(behavior: IQuarksSizeBySpeedBehavior): Behavior { + return { + type: "SizeBySpeed", + minSpeed: convertOptionalValue(behavior.minSpeed), + maxSpeed: convertOptionalValue(behavior.maxSpeed), + ...(behavior.size?.keys && { size: { keys: convertGradientKeys(behavior.size.keys) } }), + } as ISizeBySpeedBehavior; +} + +/** + * Convert RotationBySpeed behavior + */ +function convertRotationBySpeedBehavior(behavior: IQuarksRotationBySpeedBehavior): Behavior { + return { + type: "RotationBySpeed", + angularVelocity: convertOptionalValue(behavior.angularVelocity), + minSpeed: convertOptionalValue(behavior.minSpeed), + maxSpeed: convertOptionalValue(behavior.maxSpeed), + } as Behavior; +} + +/** + * Convert OrbitOverLife behavior + */ +function convertOrbitOverLifeBehavior(behavior: IQuarksOrbitOverLifeBehavior): Behavior { + return { + type: "OrbitOverLife", + center: behavior.center, + radius: convertOptionalValue(behavior.radius), + speed: convertOptionalValue(behavior.speed), + } as Behavior; +} diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/colorConverter.ts b/editor/src/editor/windows/effect-editor/converters/quarks/colorConverter.ts new file mode 100644 index 000000000..adafbd332 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/colorConverter.ts @@ -0,0 +1,139 @@ +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import type { IQuarksColor, IQuarksStartColor, IQuarksGradientKey, IQuarksGradientColor, IQuarksConstantColorColor } from "./types"; +import type { IGradientKey } from "babylonjs-editor-tools"; +import { DEFAULT_COLOR } from "./constants"; + +/** + * Helper: Create Color4 from RGBA with fallbacks + */ +export function createColor4(r: number | undefined, g: number | undefined, b: number | undefined, a: number | undefined = 1): Color4 { + return new Color4(r ?? 1, g ?? 1, b ?? 1, a ?? 1); +} + +/** + * Helper: Create Color4 from array + */ +export function createColor4FromArray(arr: [number, number, number, number] | undefined): Color4 { + return createColor4(arr?.[0], arr?.[1], arr?.[2], arr?.[3]); +} + +/** + * Helper: Create Color4 from RGBA object + */ +export function createColor4FromRGBA(rgba: { r: number; g: number; b: number; a?: number } | undefined): Color4 { + return rgba ? createColor4(rgba.r, rgba.g, rgba.b, rgba.a) : createColor4(1, 1, 1, 1); +} + +/** + * Extract color from ConstantColor behavior + */ +export function extractConstantColor(constantColor: IQuarksConstantColorColor): { r: number; g: number; b: number; a: number } { + if (constantColor.color) { + return { + r: constantColor.color.r, + g: constantColor.color.g, + b: constantColor.color.b, + a: constantColor.color.a ?? 1, + }; + } + if (constantColor.value && Array.isArray(constantColor.value) && constantColor.value.length >= 4) { + return { + r: constantColor.value[0], + g: constantColor.value[1], + b: constantColor.value[2], + a: constantColor.value[3], + }; + } + return DEFAULT_COLOR; +} + +/** + * Extract Color4 from gradient key value + */ +export function extractColorFromGradientKey(key: IQuarksGradientKey): Color4 { + if (Array.isArray(key.value)) { + return createColor4FromArray(key.value as [number, number, number, number]); + } + if (typeof key.value === "object" && key.value !== null && "r" in key.value) { + return createColor4FromRGBA(key.value as { r: number; g: number; b: number; a?: number }); + } + return createColor4(1, 1, 1, 1); +} + +/** + * Convert IQuarks gradient key to gradient key + */ +export function convertGradientKey(key: IQuarksGradientKey): IGradientKey { + return { + time: key.time, + value: key.value, + pos: key.pos, + }; +} + +/** + * Convert IQuarks color to native Babylon.js Color4 (color1, color2) + */ +export function convertColorToColor4(color: IQuarksColor): { color1: Color4; color2: Color4 } { + if (Array.isArray(color)) { + const c = createColor4FromArray(color as [number, number, number, number]); + return { color1: c, color2: c }; + } + + if (typeof color === "object" && color !== null && "type" in color) { + if (color.type === "ConstantColor") { + const constColor = color as IQuarksConstantColorColor; + if (constColor.value && Array.isArray(constColor.value)) { + const c = createColor4FromArray(constColor.value); + return { color1: c, color2: c }; + } + if (constColor.color) { + const c = createColor4FromRGBA(constColor.color); + return { color1: c, color2: c }; + } + } + // Handle RandomColor (interpolation between two colors) + const randomColor = color as { type: string; a?: [number, number, number, number]; b?: [number, number, number, number] }; + if (randomColor.type === "RandomColor" && randomColor.a && randomColor.b) { + const color1 = createColor4FromArray(randomColor.a); + const color2 = createColor4FromArray(randomColor.b); + return { color1, color2 }; + } + } + + const white = createColor4(1, 1, 1, 1); + return { color1: white, color2: white }; +} + +/** + * Convert IQuarksStartColor to native Babylon.js Color4 (color1, color2) + */ +export function convertStartColorToColor4(startColor: IQuarksStartColor): { color1: Color4; color2: Color4 } { + // Handle Gradient type + if (typeof startColor === "object" && startColor !== null && "type" in startColor) { + if (startColor.type === "Gradient") { + // For Gradient, extract color from CLinearFunction if available + const gradientColor = startColor as IQuarksGradientColor; + if (gradientColor.color?.keys && gradientColor.color.keys.length > 0) { + const firstKey = gradientColor.color.keys[0]; + const lastKey = gradientColor.color.keys[gradientColor.color.keys.length - 1]; + const color1 = extractColorFromGradientKey(firstKey); + const color2 = extractColorFromGradientKey(lastKey); + return { color1, color2 }; + } + } + if (startColor.type === "ColorRange") { + // For ColorRange, use a and b colors + const colorRange = startColor as { + type: string; + a?: { r: number; g: number; b: number; a?: number }; + b?: { r: number; g: number; b: number; a?: number }; + }; + const color1 = createColor4FromRGBA(colorRange.a); + const color2 = createColor4FromRGBA(colorRange.b); + return { color1, color2 }; + } + } + // Otherwise treat as IQuarksColor + return convertColorToColor4(startColor as IQuarksColor); +} diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/constants.ts b/editor/src/editor/windows/effect-editor/converters/quarks/constants.ts new file mode 100644 index 000000000..b6b1951aa --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/constants.ts @@ -0,0 +1,17 @@ +/** + * Constants used in Quarks converter + */ +export const DEFAULT_DURATION = 5; +export const DEFAULT_COLOR = { r: 1, g: 1, b: 1, a: 1 }; +export const DEFAULT_COLOR_HEX = 0xffffff; +export const PREWARM_FPS = 60; +export const DEFAULT_PREWARM_STEP_OFFSET = 1 / PREWARM_FPS; + +// Three.js constants +export const THREE_REPEAT_WRAPPING = 1000; +export const THREE_CLAMP_TO_EDGE_WRAPPING = 1001; +export const THREE_MIRRORED_REPEAT_WRAPPING = 1002; +export const THREE_LINEAR_FILTER = 1006; +export const THREE_NEAREST_MIPMAP_NEAREST_FILTER = 1007; +export const THREE_LINEAR_MIPMAP_NEAREST_FILTER = 1008; +export const THREE_NEAREST_MIPMAP_LINEAR_FILTER = 1009; diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/emitterConfigConverter.ts b/editor/src/editor/windows/effect-editor/converters/quarks/emitterConfigConverter.ts new file mode 100644 index 000000000..4ff92a2e9 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/emitterConfigConverter.ts @@ -0,0 +1,173 @@ +import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem"; +import type { IQuarksParticleEmitterConfig } from "./types"; +import type { IParticleSystemConfig } from "babylonjs-editor-tools"; +import { DEFAULT_DURATION, DEFAULT_PREWARM_STEP_OFFSET, PREWARM_FPS } from "./constants"; +import { convertValue, convertValueToMinMax, convertStartSizeToMinMax, convertRotationToMinMax } from "./valueConverter"; +import { convertStartColorToColor4 } from "./colorConverter"; +import { convertShape } from "./resourceConverter"; +import { convertBehavior } from "./behaviorConverter"; + +/** + * Convert emitter config from IQuarks to format + */ +export function convertEmitterConfig(config: IQuarksParticleEmitterConfig): IParticleSystemConfig { + const result = convertBasicEmitterConfig(config); + convertLifeProperties(config, result); + convertEmissionProperties(config, result); + convertVisualProperties(config, result); + convertBehaviorsAndShape(config, result); + convertBillboardConfig(config, result); + return result; +} + +/** + * Convert basic emitter configuration (system type, duration, prewarm, etc.) + */ +function convertBasicEmitterConfig(config: IQuarksParticleEmitterConfig): IParticleSystemConfig { + const systemType: "solid" | "base" = config.renderMode === 2 ? "solid" : "base"; + const duration = config.duration ?? DEFAULT_DURATION; + const targetStopDuration = config.looping ? 0 : duration; + + // Convert prewarm to native preWarmCycles + let preWarmCycles = 0; + let preWarmStepOffset = DEFAULT_PREWARM_STEP_OFFSET; + if (config.prewarm) { + preWarmCycles = Math.ceil(duration * PREWARM_FPS); + preWarmStepOffset = DEFAULT_PREWARM_STEP_OFFSET; + } + + const isLocal = config.worldSpace === undefined ? false : !config.worldSpace; + const disposeOnStop = config.autoDestroy ?? false; + + return { + version: config.version, + systemType, + targetStopDuration, + preWarmCycles, + preWarmStepOffset, + isLocal, + disposeOnStop, + instancingGeometry: config.instancingGeometry, + renderOrder: config.renderOrder, + layers: config.layers, + uTileCount: config.uTileCount, + vTileCount: config.vTileCount, + }; +} + +/** + * Convert life-related properties (lifeTime, size, rotation, color) + */ +function convertLifeProperties(config: IQuarksParticleEmitterConfig, result: IParticleSystemConfig): void { + if (config.startLife !== undefined) { + const lifeResult = convertValueToMinMax(config.startLife); + result.minLifeTime = lifeResult.min; + result.maxLifeTime = lifeResult.max; + if (lifeResult.gradients) { + result.lifeTimeGradients = lifeResult.gradients; + } + } + + if (config.startSize !== undefined) { + const sizeResult = convertStartSizeToMinMax(config.startSize); + result.minSize = sizeResult.min; + result.maxSize = sizeResult.max; + if (sizeResult.gradients) { + result.startSizeGradients = sizeResult.gradients; + } + } + + if (config.startRotation !== undefined) { + const rotResult = convertRotationToMinMax(config.startRotation); + result.minInitialRotation = rotResult.min; + result.maxInitialRotation = rotResult.max; + } + + if (config.startColor !== undefined) { + const colorResult = convertStartColorToColor4(config.startColor); + result.color1 = colorResult.color1; + result.color2 = colorResult.color2; + } +} + +/** + * Convert emission-related properties (speed, rate, bursts) + */ +function convertEmissionProperties(config: IQuarksParticleEmitterConfig, result: IParticleSystemConfig): void { + if (config.startSpeed !== undefined) { + const speedResult = convertValueToMinMax(config.startSpeed); + result.minEmitPower = speedResult.min; + result.maxEmitPower = speedResult.max; + } + + if (config.emissionOverTime !== undefined) { + const emitResult = convertValueToMinMax(config.emissionOverTime); + result.emitRate = emitResult.min; + if (emitResult.gradients) { + result.emitRateGradients = emitResult.gradients; + } + } + + if (config.emissionOverDistance !== undefined) { + result.emissionOverDistance = convertValue(config.emissionOverDistance); + } + + if (config.emissionBursts !== undefined && Array.isArray(config.emissionBursts)) { + result.emissionBursts = config.emissionBursts.map((burst) => ({ + time: convertValue(burst.time), + count: convertValue(burst.count), + })); + } +} + +/** + * Convert visual properties (sprite animation, shape) + */ +function convertVisualProperties(config: IQuarksParticleEmitterConfig, result: IParticleSystemConfig): void { + if (config.startTileIndex !== undefined) { + result.startTileIndex = convertValue(config.startTileIndex); + } + + if (config.shape !== undefined) { + result.shape = convertShape(config.shape); + } +} + +/** + * Convert behaviors and shape + */ +function convertBehaviorsAndShape(config: IQuarksParticleEmitterConfig, result: IParticleSystemConfig): void { + if (config.behaviors !== undefined && Array.isArray(config.behaviors)) { + result.behaviors = config.behaviors.map((behavior) => convertBehavior(behavior)); + } +} + +/** + * Convert billboard configuration from renderMode + */ +function convertBillboardConfig(config: IQuarksParticleEmitterConfig, result: IParticleSystemConfig): void { + const billboardConfig = convertRenderMode(config.renderMode); + result.isBillboardBased = billboardConfig.isBillboardBased; + if (billboardConfig.billboardMode !== undefined) { + result.billboardMode = billboardConfig.billboardMode; + } +} + +/** + * Helper: Convert renderMode to billboard config + */ +function convertRenderMode(renderMode: number | undefined): { isBillboardBased: boolean; billboardMode?: number } { + const renderModeMap: Record = { + 0: { isBillboardBased: true, billboardMode: ParticleSystem.BILLBOARDMODE_ALL }, + 1: { isBillboardBased: true, billboardMode: ParticleSystem.BILLBOARDMODE_STRETCHED }, + 2: { isBillboardBased: false, billboardMode: ParticleSystem.BILLBOARDMODE_ALL }, + 3: { isBillboardBased: true, billboardMode: ParticleSystem.BILLBOARDMODE_ALL }, + 4: { isBillboardBased: true, billboardMode: ParticleSystem.BILLBOARDMODE_Y }, + 5: { isBillboardBased: true, billboardMode: ParticleSystem.BILLBOARDMODE_Y }, + }; + + if (renderMode !== undefined && renderMode in renderModeMap) { + return renderModeMap[renderMode]; + } + return { isBillboardBased: true, billboardMode: ParticleSystem.BILLBOARDMODE_ALL }; +} diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/resourceConverter.ts b/editor/src/editor/windows/effect-editor/converters/quarks/resourceConverter.ts new file mode 100644 index 000000000..f9710c606 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/resourceConverter.ts @@ -0,0 +1,275 @@ +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Texture as BabylonTexture } from "@babylonjs/core/Materials/Textures"; +import type { IQuarksMaterial, IQuarksTexture, IQuarksImage, IQuarksGeometry, IQuarksShape, IQuarksGradientKey, IQuarksValue } from "./types"; +import type { IMaterial, ITexture, IImage, IGeometry, IGeometryData, IGradientKey, IShape, Value } from "babylonjs-editor-tools"; +import { + THREE_REPEAT_WRAPPING, + THREE_CLAMP_TO_EDGE_WRAPPING, + THREE_MIRRORED_REPEAT_WRAPPING, + THREE_LINEAR_FILTER, + THREE_NEAREST_MIPMAP_NEAREST_FILTER, + THREE_LINEAR_MIPMAP_NEAREST_FILTER, + THREE_NEAREST_MIPMAP_LINEAR_FILTER, + DEFAULT_COLOR_HEX, +} from "./constants"; +import { convertValue } from "./valueConverter"; +import { convertGradientKey } from "./colorConverter"; + +/** + * Helper: Convert array of gradient keys + */ +export function convertGradientKeys(keys: IQuarksGradientKey[] | undefined): IGradientKey[] { + return keys ? keys.map((k) => convertGradientKey(k)) : []; +} + +/** + * Helper: Convert speed/frame value (can be Value or object with keys) + */ +export function convertSpeedOrFrameValue( + value: IQuarksValue | { keys?: IQuarksGradientKey[]; functions?: unknown[] } | undefined +): Value | { keys?: IGradientKey[]; functions?: unknown[] } | undefined { + if (value === undefined) { + return undefined; + } + if (typeof value === "object" && value !== null && "keys" in value) { + const result: { keys?: IGradientKey[]; functions?: unknown[] } = {}; + if (value.keys) { + result.keys = convertGradientKeys(value.keys); + } + if ("functions" in value && value.functions) { + result.functions = value.functions; + } + return result; + } + if (typeof value === "number" || (typeof value === "object" && value !== null && "type" in value)) { + return convertValue(value as IQuarksValue); + } + return undefined; +} + +/** + * Helper: Flip Z coordinate in array (for left-handed conversion) + */ +function flipZCoordinate(array: number[], itemSize: number = 3): number[] { + const result = Array.from(array); + for (let i = itemSize - 1; i < result.length; i += itemSize) { + result[i] = -result[i]; + } + return result; +} + +/** + * Helper: Convert attribute array + */ +function convertAttribute(attr: { array: number[]; itemSize: number } | undefined, flipZ: boolean = false): { array: number[]; itemSize: number } | undefined { + if (!attr) { + return undefined; + } + return { + array: flipZ ? flipZCoordinate(attr.array, attr.itemSize) : Array.from(attr.array), + itemSize: attr.itemSize, + }; +} + +/** + * Convert IQuarks shape to shape + */ +export function convertShape(shape: IQuarksShape): IShape { + const result: IShape = { + type: shape.type, + radius: shape.radius, + arc: shape.arc, + thickness: shape.thickness, + angle: shape.angle, + mode: shape.mode, + spread: shape.spread, + size: shape.size, + height: shape.height, + }; + if (shape.speed !== undefined) { + result.speed = convertValue(shape.speed); + } + return result; +} + +/** + * Convert IQuarks materials to materials + */ +export function convertMaterial(material: IQuarksMaterial): IMaterial { + const babylonMaterial: IMaterial = { + uuid: material.uuid, + type: material.type, + transparent: material.transparent, + depthWrite: material.depthWrite, + side: material.side, + map: material.map, + }; + + // Convert color from hex to Color3 + if (material.color !== undefined) { + const colorHex = typeof material.color === "number" ? material.color : parseInt(String(material.color).replace("#", ""), 16) || DEFAULT_COLOR_HEX; + const r = ((colorHex >> 16) & 0xff) / 255; + const g = ((colorHex >> 8) & 0xff) / 255; + const b = (colorHex & 0xff) / 255; + babylonMaterial.color = new Color3(r, g, b); + } + + // Convert blending mode (Three.js → Babylon.js) + if (material.blending !== undefined) { + const blendModeMap: Record = { + 0: 0, // NoBlending → ALPHA_DISABLE + 1: 1, // NormalBlending → ALPHA_COMBINE + 2: 2, // AdditiveBlending → ALPHA_ADD + }; + babylonMaterial.blending = blendModeMap[material.blending] ?? material.blending; + } + + return babylonMaterial; +} + +/** + * Convert IQuarks textures to textures + */ +export function convertTexture(texture: IQuarksTexture): ITexture { + const babylonTexture: ITexture = { + uuid: texture.uuid, + image: texture.image, + generateMipmaps: texture.generateMipmaps, + flipY: texture.flipY, + }; + + // Convert wrap mode (Three.js → Babylon.js) + if (texture.wrap && Array.isArray(texture.wrap)) { + const wrapModeMap: Record = { + [THREE_REPEAT_WRAPPING]: BabylonTexture.WRAP_ADDRESSMODE, + [THREE_CLAMP_TO_EDGE_WRAPPING]: BabylonTexture.CLAMP_ADDRESSMODE, + [THREE_MIRRORED_REPEAT_WRAPPING]: BabylonTexture.MIRROR_ADDRESSMODE, + }; + babylonTexture.wrapU = wrapModeMap[texture.wrap[0]] ?? BabylonTexture.WRAP_ADDRESSMODE; + babylonTexture.wrapV = wrapModeMap[texture.wrap[1]] ?? BabylonTexture.WRAP_ADDRESSMODE; + } + + // Convert repeat to scale + if (texture.repeat && Array.isArray(texture.repeat)) { + babylonTexture.uScale = texture.repeat[0] || 1; + babylonTexture.vScale = texture.repeat[1] || 1; + } + + // Convert offset + if (texture.offset && Array.isArray(texture.offset)) { + babylonTexture.uOffset = texture.offset[0] || 0; + babylonTexture.vOffset = texture.offset[1] || 0; + } + + // Convert rotation + if (texture.rotation !== undefined) { + babylonTexture.uAng = texture.rotation; + } + + // Convert channel + if (typeof texture.channel === "number") { + babylonTexture.coordinatesIndex = texture.channel; + } + + // Convert sampling mode (Three.js filters → Babylon.js sampling mode) + if (texture.minFilter !== undefined) { + if (texture.minFilter === THREE_LINEAR_MIPMAP_NEAREST_FILTER || texture.minFilter === THREE_NEAREST_MIPMAP_LINEAR_FILTER) { + babylonTexture.samplingMode = BabylonTexture.TRILINEAR_SAMPLINGMODE; + } else if (texture.minFilter === THREE_NEAREST_MIPMAP_NEAREST_FILTER || texture.minFilter === THREE_LINEAR_FILTER) { + babylonTexture.samplingMode = BabylonTexture.BILINEAR_SAMPLINGMODE; + } else { + babylonTexture.samplingMode = BabylonTexture.NEAREST_SAMPLINGMODE; + } + } else if (texture.magFilter !== undefined) { + babylonTexture.samplingMode = texture.magFilter === THREE_LINEAR_FILTER ? BabylonTexture.BILINEAR_SAMPLINGMODE : BabylonTexture.NEAREST_SAMPLINGMODE; + } else { + babylonTexture.samplingMode = BabylonTexture.TRILINEAR_SAMPLINGMODE; + } + + return babylonTexture; +} + +/** + * Convert IQuarks images to images (normalize URLs) + */ +export function convertImage(image: IQuarksImage): IImage { + return { + uuid: image.uuid, + url: image.url || "", + }; +} + +/** + * Convert IQuarks geometries to geometries (convert to left-handed) + */ +export function convertGeometry(geometry: IQuarksGeometry): IGeometry { + if (geometry.type === "PlaneGeometry") { + // PlaneGeometry - simple properties + const planeGeometry = geometry as IQuarksGeometry & { width?: number; height?: number }; + return { + uuid: geometry.uuid, + type: "PlaneGeometry" as const, + width: planeGeometry.width ?? 1, + height: planeGeometry.height ?? 1, + }; + } else if (geometry.type === "BufferGeometry") { + // BufferGeometry - convert attributes to left-handed + const result: IGeometry = { + uuid: geometry.uuid, + type: "BufferGeometry", + }; + + if (geometry.data?.attributes) { + const attributes: IGeometryData["attributes"] = {}; + const sourceAttrs = geometry.data.attributes; + + // Convert position and normal (right-hand → left-hand: flip Z) + const positionAttr = convertAttribute(sourceAttrs.position, true); + if (positionAttr) { + attributes.position = positionAttr; + } + + const normalAttr = convertAttribute(sourceAttrs.normal, true); + if (normalAttr) { + attributes.normal = normalAttr; + } + + // UV and color - no conversion needed + const uvAttr = convertAttribute(sourceAttrs.uv, false); + if (uvAttr) { + attributes.uv = uvAttr; + } + + const colorAttr = convertAttribute(sourceAttrs.color, false); + if (colorAttr) { + attributes.color = colorAttr; + } + + result.data = { + attributes, + }; + + // Convert indices (reverse winding order for left-handed) + if (geometry.data.index) { + const indices = Array.from(geometry.data.index.array); + // Reverse winding: swap every 2nd and 3rd index in each triangle + for (let i = 0; i < indices.length; i += 3) { + const temp = indices[i + 1]; + indices[i + 1] = indices[i + 2]; + indices[i + 2] = temp; + } + result.data.index = { + array: indices, + }; + } + } + + return result; + } + + // Unknown geometry type - return as-is + return { + uuid: geometry.uuid, + type: geometry.type as "PlaneGeometry" | "BufferGeometry", + }; +} diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/transformConverter.ts b/editor/src/editor/windows/effect-editor/converters/quarks/transformConverter.ts new file mode 100644 index 000000000..a5ab88d5e --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/transformConverter.ts @@ -0,0 +1,86 @@ +import { Matrix, Vector3, Quaternion } from "@babylonjs/core/Maths/math.vector"; +import type { ITransform } from "babylonjs-editor-tools"; + +/** + * Z-axis reflection matrix for RH → LH conversion + */ +const RH_TO_LH = Matrix.Scaling(1, 1, -1); + +/** + * Convert right-handed matrix to left-handed using: + * C * M * C + */ +function convertMatrixRHtoLH(sourceMatrix: Matrix): Matrix { + return RH_TO_LH.multiply(sourceMatrix).multiply(RH_TO_LH); +} + +/** + * Convert transform from Three.js / Quarks (RH) to Babylon.js (LH) + * Matrix space conversion only. + */ +export function convertTransform(matrixArray?: number[], positionArray?: number[], rotationArray?: number[], scaleArray?: number[]): ITransform { + const position = Vector3.Zero(); + const rotation = Quaternion.Identity(); + const scale = Vector3.One(); + + let sourceMatrix: Matrix; + + // ========================= + // MATRIX PATH (Preferred) + // ========================= + if (matrixArray && matrixArray.length >= 16) { + // IMPORTANT: + // Babylon Matrix.FromArray expects column-major already + sourceMatrix = Matrix.FromArray(matrixArray); + } else { + // ========================= + // TRS PATH (Fallback) + // ========================= + + const tempPos = Vector3.Zero(); + const tempRot = Quaternion.Identity(); + const tempScale = Vector3.One(); + + if (positionArray?.length === 3) { + tempPos.set(positionArray[0] ?? 0, positionArray[1] ?? 0, positionArray[2] ?? 0); + } + + if (rotationArray?.length === 3) { + // Three.js Euler is XYZ intrinsic + // Babylon FromEulerAngles expects same logical order + tempRot.copyFrom(Quaternion.FromEulerAngles(rotationArray[0] ?? 0, rotationArray[1] ?? 0, rotationArray[2] ?? 0)); + } + + if (scaleArray?.length === 3) { + tempScale.set(scaleArray[0] ?? 1, scaleArray[1] ?? 1, scaleArray[2] ?? 1); + } + + sourceMatrix = Matrix.Compose(tempScale, tempRot, tempPos); + } + + // ========================= + // HANDEDNESS CONVERSION + // ========================= + + const convertedMatrix = convertMatrixRHtoLH(sourceMatrix); + + // ========================= + // SAFE DECOMPOSE + // ========================= + + const outPos = Vector3.Zero(); + const outRot = Quaternion.Identity(); + const outScale = Vector3.One(); + + convertedMatrix.decompose(outScale, outRot, outPos); + + position.copyFrom(outPos); + scale.copyFrom(outScale); + rotation.copyFrom(outRot); + + return { + position, + rotation, + scale, + }; +} diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/types.ts b/editor/src/editor/windows/effect-editor/converters/quarks/types.ts new file mode 100644 index 000000000..0ebc564f1 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/types.ts @@ -0,0 +1,481 @@ +/** + * Type definitions for Quarks JSON structures + * These represent the incoming format from Quarks + */ + +/** + * Common Bezier function structure used across multiple types + */ +export interface IQuarksBezierFunction { + p0: number; + p1: number; + p2: number; + p3: number; +} + +export interface IQuarksBezierFunctionSegment { + function: IQuarksBezierFunction; + start: number; +} + +/** + * Common RGBA color structure + */ +export interface IQuarksRGBA { + r: number; + g: number; + b: number; + a?: number; +} + +/** + * Quarks value types + */ +export interface IQuarksConstantValue { + type: "ConstantValue"; + value: number; +} + +export interface IQuarksIntervalValue { + type: "IntervalValue"; + a: number; // min + b: number; // max +} + +export interface IQuarksPiecewiseBezier { + type: "PiecewiseBezier"; + functions: IQuarksBezierFunctionSegment[]; +} + +export type IQuarksValue = IQuarksConstantValue | IQuarksIntervalValue | IQuarksPiecewiseBezier | number; + +/** + * Quarks color types + */ +export interface IQuarksConstantColor { + type: "ConstantColor"; + color?: IQuarksRGBA; + value?: [number, number, number, number]; // RGBA array alternative +} + +export type IQuarksColor = IQuarksConstantColor | [number, number, number, number] | string; + +/** + * Quarks rotation types + */ +export interface IQuarksEulerRotation { + type: "Euler"; + angleX?: IQuarksValue; + angleY?: IQuarksValue; + angleZ?: IQuarksValue; + eulerOrder?: string; + functions?: IQuarksBezierFunctionSegment[]; + a?: number; + b?: number; + value?: number; +} + +export type IQuarksRotation = IQuarksEulerRotation | IQuarksValue; + +/** + * Quarks gradient key + */ +export interface IQuarksGradientKey { + time?: number; + value: number | [number, number, number, number] | IQuarksRGBA; + pos?: number; +} + +/** + * Quarks shape configuration + */ +export interface IQuarksShape { + type: string; + radius?: number; + arc?: number; + thickness?: number; + angle?: number; + mode?: number; + spread?: number; + speed?: IQuarksValue; + size?: number[]; + height?: number; +} + +/** + * Quarks emission burst + */ +export interface IQuarksEmissionBurst { + time: IQuarksValue; + count: IQuarksValue; + cycle?: number; + interval?: number; + probability?: number; +} + +/** + * Quarks behavior types + */ +export interface IQuarksCLinearFunction { + type: "CLinearFunction"; + subType: "Color" | "Number"; + keys: IQuarksGradientKey[]; +} + +export interface IQuarksGradientColor { + type: "Gradient"; + color?: IQuarksCLinearFunction; + alpha?: IQuarksCLinearFunction; +} + +export interface IQuarksConstantColorColor { + type: "ConstantColor"; + color?: IQuarksRGBA; + value?: [number, number, number, number]; +} + +export interface IQuarksRandomColorBetweenGradient { + type: "RandomColorBetweenGradient"; + gradient1?: IQuarksGradientColor; + gradient2?: IQuarksGradientColor; +} + +export type IQuarksColorOverLifeColor = IQuarksGradientColor | IQuarksConstantColorColor | IQuarksRandomColorBetweenGradient; + +export interface IQuarksColorOverLifeBehavior { + type: "ColorOverLife"; + color?: IQuarksColorOverLifeColor; +} + +export interface IQuarksSizeOverLifeBehavior { + type: "SizeOverLife"; + size?: { + keys?: IQuarksGradientKey[]; + functions?: IQuarksBezierFunctionSegment[]; + type?: string; + }; +} + +export interface IQuarksRotationOverLifeBehavior { + type: "RotationOverLife" | "Rotation3DOverLife"; + angularVelocity?: IQuarksValue; +} + +export interface IQuarksForceOverLifeBehavior { + type: "ForceOverLife" | "ApplyForce"; + force?: { + x?: IQuarksValue; + y?: IQuarksValue; + z?: IQuarksValue; + }; + x?: IQuarksValue; + y?: IQuarksValue; + z?: IQuarksValue; +} + +export interface IQuarksGravityForceBehavior { + type: "GravityForce"; + gravity?: IQuarksValue; +} + +export interface IQuarksSpeedOverLifeBehavior { + type: "SpeedOverLife"; + speed?: + | { + keys?: IQuarksGradientKey[]; + functions?: Array<{ + start: number; + function: { + p0?: number; + p3?: number; + }; + }>; + } + | IQuarksValue; +} + +export interface IQuarksFrameOverLifeBehavior { + type: "FrameOverLife"; + frame?: + | { + keys?: IQuarksGradientKey[]; + } + | IQuarksValue; +} + +export interface IQuarksLimitSpeedOverLifeBehavior { + type: "LimitSpeedOverLife"; + maxSpeed?: IQuarksValue; + speed?: IQuarksValue | { keys?: IQuarksGradientKey[] }; + dampen?: IQuarksValue; +} + +/** + * Base interface for speed-based behaviors + */ +interface IQuarksSpeedBasedBehavior { + minSpeed?: IQuarksValue; + maxSpeed?: IQuarksValue; +} + +export interface IQuarksColorBySpeedBehavior extends IQuarksSpeedBasedBehavior { + type: "ColorBySpeed"; + color?: { + keys: IQuarksGradientKey[]; + }; +} + +export interface IQuarksSizeBySpeedBehavior extends IQuarksSpeedBasedBehavior { + type: "SizeBySpeed"; + size?: { + keys: IQuarksGradientKey[]; + }; +} + +export interface IQuarksRotationBySpeedBehavior extends IQuarksSpeedBasedBehavior { + type: "RotationBySpeed"; + angularVelocity?: IQuarksValue; +} + +export interface IQuarksOrbitOverLifeBehavior { + type: "OrbitOverLife"; + center?: { + x?: number; + y?: number; + z?: number; + }; + radius?: IQuarksValue; + speed?: IQuarksValue; +} + +export interface IQuarksNoiseBehavior { + type: "Noise"; + frequency?: IQuarksValue; + power?: IQuarksValue; + positionAmount?: IQuarksValue; + rotationAmount?: IQuarksValue; + x?: IQuarksValue; + y?: IQuarksValue; + z?: IQuarksValue; +} + +export type IQuarksBehavior = + | IQuarksColorOverLifeBehavior + | IQuarksSizeOverLifeBehavior + | IQuarksRotationOverLifeBehavior + | IQuarksForceOverLifeBehavior + | IQuarksGravityForceBehavior + | IQuarksSpeedOverLifeBehavior + | IQuarksFrameOverLifeBehavior + | IQuarksLimitSpeedOverLifeBehavior + | IQuarksColorBySpeedBehavior + | IQuarksSizeBySpeedBehavior + | IQuarksRotationBySpeedBehavior + | IQuarksOrbitOverLifeBehavior + | IQuarksNoiseBehavior + | { type: string; [key: string]: unknown }; // Fallback for unknown behaviors + +/** + * Quarks start size with Vector3Function support + */ +export interface IQuarksVector3FunctionSize { + type: "Vector3Function"; + x?: IQuarksValue; + y?: IQuarksValue; + z?: IQuarksValue; + functions?: IQuarksBezierFunctionSegment[]; + a?: number; + b?: number; + value?: number; +} + +export type IQuarksStartSize = IQuarksValue | IQuarksVector3FunctionSize; + +/** + * Quarks start color with Gradient and ColorRange support + */ +export interface IQuarksGradientStartColor { + type: "Gradient"; + alpha?: IQuarksCLinearFunction; + color?: IQuarksCLinearFunction; +} + +export interface IQuarksColorRangeStartColor { + type: "ColorRange"; + a?: IQuarksRGBA; + b?: IQuarksRGBA; + color?: IQuarksCLinearFunction; + alpha?: IQuarksCLinearFunction; +} + +export type IQuarksStartColor = IQuarksColor | IQuarksGradientStartColor | IQuarksColorRangeStartColor; + +/** + * Quarks particle emitter configuration + */ +export interface IQuarksParticleEmitterConfig { + version?: string; + autoDestroy?: boolean; + looping?: boolean; + prewarm?: boolean; + duration?: number; + shape?: IQuarksShape; + startLife?: IQuarksValue; + startSpeed?: IQuarksValue; + startRotation?: IQuarksRotation; + startSize?: IQuarksStartSize; + startColor?: IQuarksStartColor; + emissionOverTime?: IQuarksValue; + emissionOverDistance?: IQuarksValue; + emissionBursts?: IQuarksEmissionBurst[]; + onlyUsedByOther?: boolean; + instancingGeometry?: string; + renderOrder?: number; + renderMode?: number; + rendererEmitterSettings?: Record; + material?: string; + layers?: number; + startTileIndex?: IQuarksValue; + uTileCount?: number; + vTileCount?: number; + blendTiles?: boolean; + softParticles?: boolean; + softFarFade?: number; + softNearFade?: number; + behaviors?: IQuarksBehavior[]; + worldSpace?: boolean; +} + +/** + * Base interface for Quarks objects with common transform properties + */ +interface IQuarksObjectBase { + uuid: string; + name: string; + matrix: number[]; + layers: number; + up: number[]; + children: IQuarksObject[]; + position?: number[]; + rotation?: number[]; + scale?: number[]; +} + +/** + * Quarks object types + */ +export interface IQuarksGroup extends IQuarksObjectBase { + type: "Group"; +} + +export interface IQuarksParticleEmitter extends IQuarksObjectBase { + type: "ParticleEmitter"; + ps: IQuarksParticleEmitterConfig; +} + +export type IQuarksObject = IQuarksGroup | IQuarksParticleEmitter; + +/** + * Base interface for Quarks resources (materials, textures, images, geometries) + */ +interface IQuarksResource { + uuid: string; + name?: string; +} + +/** + * Quarks material + */ +export interface IQuarksMaterial extends IQuarksResource { + type: string; + color?: number; + map?: string; + blending?: number; + blendColor?: number; + side?: number; + transparent?: boolean; + depthWrite?: boolean; + envMapRotation?: number[]; + reflectivity?: number; + refractionRatio?: number; +} + +/** + * Quarks texture + */ +export interface IQuarksTexture extends IQuarksResource { + image?: string; + mapping?: number; + wrap?: number[]; + repeat?: number[]; + offset?: number[]; + center?: number[]; + rotation?: number; + minFilter?: number; + magFilter?: number; + flipY?: boolean; + generateMipmaps?: boolean; + format?: number; + internalFormat?: number | null; + type?: number; + channel?: number; + anisotropy?: number; + colorSpace?: string; + premultiplyAlpha?: boolean; + unpackAlignment?: number; +} + +/** + * Quarks image + */ +export interface IQuarksImage extends IQuarksResource { + url?: string; +} + +/** + * Quarks geometry + */ +export interface IQuarksGeometry extends IQuarksResource { + type: string; + data?: { + attributes?: Record< + string, + { + itemSize: number; + type: string; + array: number[]; + normalized?: boolean; + } + >; + index?: { + type: string; + array: number[]; + }; + }; + // Geometry-specific properties (for different geometry types) + height?: number; + heightSegments?: number; + width?: number; + widthSegments?: number; + radius?: number; + phiLength?: number; + phiStart?: number; + thetaLength?: number; + thetaStart?: number; +} + +/** + * Quarks JSON structure + */ +export interface IQuarksJSON { + metadata: { + version: number; + type: string; + generator: string; + }; + geometries: IQuarksGeometry[]; + materials: IQuarksMaterial[]; + textures: IQuarksTexture[]; + images: IQuarksImage[]; + object: IQuarksObject; +} diff --git a/editor/src/editor/windows/effect-editor/converters/quarks/valueConverter.ts b/editor/src/editor/windows/effect-editor/converters/quarks/valueConverter.ts new file mode 100644 index 000000000..f386c7a4d --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarks/valueConverter.ts @@ -0,0 +1,189 @@ +import type { IQuarksValue, IQuarksStartSize, IQuarksRotation } from "./types"; +import type { Value } from "babylonjs-editor-tools"; + +/** + * Convert IQuarks value to Value + */ +export function convertValue(value: IQuarksValue): Value { + if (typeof value === "number") { + return value; + } + if (value.type === "ConstantValue") { + return { + type: "ConstantValue", + value: value.value, + }; + } + if (value.type === "IntervalValue") { + return { + type: "IntervalValue", + min: value.a ?? 0, + max: value.b ?? 0, + }; + } + if (value.type === "PiecewiseBezier") { + return { + type: "PiecewiseBezier", + functions: value.functions.map((f) => ({ + function: f.function, + start: f.start, + })), + }; + } + // Fallback: return as Value (should not happen with proper types) + return value as Value; +} + +/** + * Helper: Convert optional IQuarksValue to optional Value + */ +export function convertOptionalValue(value: IQuarksValue | undefined): Value | undefined { + return value !== undefined ? convertValue(value) : undefined; +} + +/** + * Evaluate bezier curve at time t + * Bezier format: { p0, p1, p2, p3 } for cubic bezier + */ +export function evaluateBezierAt(bezier: { p0: number; p1: number; p2: number; p3: number }, t: number): number { + const { p0, p1, p2, p3 } = bezier; + const t2 = t * t; + const t3 = t2 * t; + const mt = 1 - t; + const mt2 = mt * mt; + const mt3 = mt2 * mt; + return mt3 * p0 + 3 * mt2 * t * p1 + 3 * mt * t2 * p2 + t3 * p3; +} + +/** + * Helper: Extract min/max from IQuarksValue + */ +export function extractMinMaxFromValue(value: IQuarksValue | undefined): { min: number; max: number } { + if (value === undefined) { + return { min: 0, max: 0 }; + } + if (typeof value === "number") { + return { min: value, max: value }; + } + if (value.type === "ConstantValue") { + return { min: value.value, max: value.value }; + } + if (value.type === "IntervalValue") { + return { min: value.a ?? 0, max: value.b ?? 0 }; + } + return { min: 0, max: 0 }; +} + +/** + * Convert IQuarks value to min/max (handles PiecewiseBezier gradients) + */ +export function convertValueToMinMax(value: IQuarksValue): { + min: number; + max: number; + gradients?: Array<{ gradient: number; factor: number; factor2?: number }>; +} { + if (typeof value === "number") { + return { min: value, max: value }; + } + if (value.type === "ConstantValue") { + return { min: value.value, max: value.value }; + } + if (value.type === "IntervalValue") { + return { min: value.a ?? 0, max: value.b ?? 0 }; + } + if (value.type === "PiecewiseBezier" && value.functions) { + // Convert PiecewiseBezier to gradients + const gradients: Array<{ gradient: number; factor: number; factor2?: number }> = []; + let minVal = Infinity; + let maxVal = -Infinity; + + for (const func of value.functions) { + const startTime = func.start; + // Evaluate bezier at start and end points + const startValue = evaluateBezierAt(func.function, 0); + const endValue = evaluateBezierAt(func.function, 1); + + gradients.push({ gradient: startTime, factor: startValue }); + + // Track min/max for fallback + minVal = Math.min(minVal, startValue, endValue); + maxVal = Math.max(maxVal, startValue, endValue); + } + + // Add final point at gradient 1.0 if not present + if (gradients.length > 0 && gradients[gradients.length - 1].gradient < 1) { + const lastFunc = value.functions[value.functions.length - 1]; + const endValue = evaluateBezierAt(lastFunc.function, 1); + gradients.push({ gradient: 1, factor: endValue }); + } + + return { + min: minVal === Infinity ? 1 : minVal, + max: maxVal === -Infinity ? 1 : maxVal, + gradients: gradients.length > 0 ? gradients : undefined, + }; + } + return { min: 1, max: 1 }; +} + +/** + * Convert IQuarksStartSize to min/max (handles Vector3Function) + * - ConstantValue → min = max = value + * - IntervalValue → min = a, max = b + * - PiecewiseBezier → gradients array + */ +export function convertStartSizeToMinMax(startSize: IQuarksStartSize): { + min: number; + max: number; + gradients?: Array<{ gradient: number; factor: number; factor2?: number }>; +} { + // Handle Vector3Function type + if (typeof startSize === "object" && startSize !== null && "type" in startSize && startSize.type === "Vector3Function") { + // For Vector3Function, use the main value or average of x, y, z + if (startSize.value !== undefined) { + return convertValueToMinMax(startSize.value); + } + // Fallback: use x value if available + if (startSize.x !== undefined) { + return convertValueToMinMax(startSize.x); + } + return { min: 1, max: 1 }; + } + // Otherwise treat as IQuarksValue + return convertValueToMinMax(startSize as IQuarksValue); +} + +/** + * Convert IQuarks rotation to native min/max radians + * Supports: number, ConstantValue, IntervalValue, Euler, AxisAngle, RandomQuat + */ +export function convertRotationToMinMax(rotation: IQuarksRotation): { min: number; max: number } { + if (typeof rotation === "number") { + return { min: rotation, max: rotation }; + } + + if (typeof rotation === "object" && rotation !== null && "type" in rotation) { + const rotationType = rotation.type; + + if (rotationType === "ConstantValue") { + return extractMinMaxFromValue(rotation as IQuarksValue); + } + + if (rotationType === "IntervalValue") { + return extractMinMaxFromValue(rotation as IQuarksValue); + } + + // Handle Euler type - for 2D/billboard particles we use angleZ, fallback to angleX + if (rotationType === "Euler") { + const euler = rotation as { type: string; angleZ?: IQuarksValue; angleX?: IQuarksValue }; + if (euler.angleZ !== undefined) { + return extractMinMaxFromValue(euler.angleZ); + } + if (euler.angleX !== undefined) { + return extractMinMaxFromValue(euler.angleX); + } + } + } + + return { min: 0, max: 0 }; +} diff --git a/editor/src/editor/windows/effect-editor/converters/quarksConverter.ts b/editor/src/editor/windows/effect-editor/converters/quarksConverter.ts new file mode 100644 index 000000000..1c67d72de --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/quarksConverter.ts @@ -0,0 +1,102 @@ +import { Tools } from "@babylonjs/core/Misc/tools"; +import type { IQuarksJSON, IQuarksObject } from "./quarks/types"; +import type { IGroup, IEmitter, IData } from "babylonjs-editor-tools"; +import { convertTransform } from "./quarks/transformConverter"; +import { convertEmitterConfig } from "./quarks/emitterConfigConverter"; +import { convertMaterial, convertTexture, convertImage, convertGeometry } from "./quarks/resourceConverter"; + +/** + * Converts Quarks Effect to Babylon.js Effect format + * All coordinate system conversions happen here, once + */ +export class QuarksConverter { + /** + * Convert Quarks Effect to Babylon.js Effect format + * Handles errors gracefully and returns partial data if conversion fails + */ + public convert(data: IQuarksJSON): IData { + let root: IGroup | IEmitter | null = null; + + try { + root = this._convertObject(data.object, null); + } catch (error) { + console.error(`Failed to convert root object: ${error instanceof Error ? error.message : String(error)}`); + } + + // Convert all resources with error handling + const materials = this._convertResources(data.materials, (m) => convertMaterial(m), "materials"); + const textures = this._convertResources(data.textures, (t) => convertTexture(t), "textures"); + const images = this._convertResources(data.images, (i) => convertImage(i), "images"); + const geometries = this._convertResources(data.geometries, (g) => convertGeometry(g), "geometries"); + + return { + root, + materials, + textures, + images, + geometries, + }; + } + + /** + * Helper: Convert resources array with error handling + */ + private _convertResources(items: T[] | undefined, converter: (item: T) => R, resourceName: string): R[] { + try { + return (items || []).map(converter); + } catch (error) { + console.error(`Failed to convert ${resourceName}: ${error instanceof Error ? error.message : String(error)}`); + return []; + } + } + + /** + * Convert a IQuarks object to Babylon.js format + */ + private _convertObject(obj: IQuarksObject, parentUuid: string | null): IGroup | IEmitter | null { + if (!obj || typeof obj !== "object") { + return null; + } + + const transform = convertTransform(obj.matrix, obj.position, obj.rotation, obj.scale); + + if (obj.type === "Group") { + const group: IGroup = { + uuid: obj.uuid || Tools.RandomId(), + name: obj.name || "Group", + transform, + children: [], + }; + + // Convert children + if (obj.children && Array.isArray(obj.children)) { + for (const child of obj.children) { + const convertedChild = this._convertObject(child, group.uuid); + if (convertedChild) { + group.children.push(convertedChild); + } + } + } + + return group; + } else if (obj.type === "ParticleEmitter" && obj.ps) { + // Convert emitter config from IQuarks to format + const config = convertEmitterConfig(obj.ps); + + const emitter: IEmitter = { + uuid: obj.uuid || Tools.RandomId(), + name: obj.name || "ParticleEmitter", + transform, + config, + materialId: obj.ps.material, + parentUuid: parentUuid ?? undefined, + systemType: config.systemType, // systemType is set in convertEmitterConfig + matrix: obj.matrix, // Store original matrix for rotation extraction + }; + + return emitter; + } + + return null; + } +} diff --git a/editor/src/editor/windows/effect-editor/converters/unity/colorConverter.ts b/editor/src/editor/windows/effect-editor/converters/unity/colorConverter.ts new file mode 100644 index 000000000..f20f59d6c --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unity/colorConverter.ts @@ -0,0 +1,110 @@ +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import type { IConstantColor, IGradientColor, IRandomColor, IRandomColorBetweenGradient } from "babylonjs-editor-tools/src/effect/types"; + +/** + * Convert Unity Color to our Color4 + */ +export function convertColor(unityColor: { r: string; g: string; b: string; a: string }): Color4 { + return new Color4(parseFloat(unityColor.r), parseFloat(unityColor.g), parseFloat(unityColor.b), parseFloat(unityColor.a)); +} + +/** + * Convert Unity Gradient to our Color + */ +export function convertGradient(gradient: any): IConstantColor | IGradientColor { + const colorKeys: Array<{ time: number; value: [number, number, number, number] }> = []; + + // Parse color keys + for (let i = 0; i < gradient.m_NumColorKeys; i++) { + const key = gradient[`key${i}`]; + const time = parseFloat(gradient[`ctime${i}`]) / 65535; // Unity stores time as 0-65535 + colorKeys.push({ + time, + value: [parseFloat(key.r), parseFloat(key.g), parseFloat(key.b), 1], + }); + } + + // Parse alpha keys + const alphaKeys: Array<{ time: number; value: number }> = []; + for (let i = 0; i < gradient.m_NumAlphaKeys; i++) { + const key = gradient[`key${i}`]; + const time = parseFloat(gradient[`atime${i}`]) / 65535; + alphaKeys.push({ + time, + value: parseFloat(key.a), + }); + } + + // If only one color key and one alpha key, return constant color + if (colorKeys.length === 1 && alphaKeys.length === 1) { + return { + type: "ConstantColor", + value: [...colorKeys[0].value.slice(0, 3), alphaKeys[0].value] as [number, number, number, number], + }; + } + + // Return gradient + return { + type: "Gradient", + colorKeys: colorKeys.map((k) => ({ time: k.time, value: k.value as [number, number, number, number] })), + alphaKeys: alphaKeys.map((k) => ({ time: k.time, value: k.value })), + }; +} + +/** + * Convert Unity MinMaxGradient to our Color + */ +export function convertMinMaxGradient(minMaxGradient: any): IConstantColor | IGradientColor | IRandomColor | IRandomColorBetweenGradient { + const minMaxState = minMaxGradient.minMaxState; + + switch (minMaxState) { + case "0": // Constant color + return { + type: "ConstantColor", + value: [ + parseFloat(minMaxGradient.maxColor.r), + parseFloat(minMaxGradient.maxColor.g), + parseFloat(minMaxGradient.maxColor.b), + parseFloat(minMaxGradient.maxColor.a), + ] as [number, number, number, number], + }; + case "1": // Gradient + return convertGradient(minMaxGradient.maxGradient); + case "2": // Random between two colors + return { + type: "RandomColor", + colorA: [ + parseFloat(minMaxGradient.minColor.r), + parseFloat(minMaxGradient.minColor.g), + parseFloat(minMaxGradient.minColor.b), + parseFloat(minMaxGradient.minColor.a), + ] as [number, number, number, number], + colorB: [ + parseFloat(minMaxGradient.maxColor.r), + parseFloat(minMaxGradient.maxColor.g), + parseFloat(minMaxGradient.maxColor.b), + parseFloat(minMaxGradient.maxColor.a), + ] as [number, number, number, number], + }; + case "3": // Random between two gradients + const grad1 = convertGradient(minMaxGradient.minGradient); + const grad2 = convertGradient(minMaxGradient.maxGradient); + if (grad1.type === "Gradient" && grad2.type === "Gradient") { + return { + type: "RandomColorBetweenGradient", + gradient1: { + colorKeys: grad1.colorKeys, + alphaKeys: grad1.alphaKeys, + }, + gradient2: { + colorKeys: grad2.colorKeys, + alphaKeys: grad2.alphaKeys, + }, + }; + } + // Fallback to constant color if conversion failed + return { type: "ConstantColor", value: [1, 1, 1, 1] }; + default: + return { type: "ConstantColor", value: [1, 1, 1, 1] }; + } +} diff --git a/editor/src/editor/windows/effect-editor/converters/unity/gameObjectConverter.ts b/editor/src/editor/windows/effect-editor/converters/unity/gameObjectConverter.ts new file mode 100644 index 000000000..43780c6ef --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unity/gameObjectConverter.ts @@ -0,0 +1,176 @@ +import { Quaternion, Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Tools } from "@babylonjs/core/Misc/tools"; +import type { IGroup, IEmitter, IParticleSystemConfig } from "babylonjs-editor-tools/src/effect/types"; +import { getComponentByType, convertVector3 } from "./utils"; +import { convertParticleSystem } from "./particleSystemConverter"; + +/** + * Intermediate format for convertGameObject (before conversion to IData format) + */ +export interface IIntermediateGameObject { + type: "emitter" | "group"; + name: string; + position: [number, number, number]; + scale: [number, number, number]; + rotation: [number, number, number, number]; + emitter?: IParticleSystemConfig; + renderMode?: number; + materialId?: string; // GUID of material from ParticleSystemRenderer + children?: IIntermediateGameObject[]; +} + +/** + * Convert Unity GameObject hierarchy to our IGroup/IEmitter structure + */ +export function convertGameObject(gameObject: any, components: Map): IIntermediateGameObject { + // Get Transform component + const transform = getComponentByType(gameObject, "Transform", components); + + const position = transform ? convertVector3(transform.m_LocalPosition) : ([0, 0, 0] as [number, number, number]); + const scale = transform ? convertVector3(transform.m_LocalScale) : ([1, 1, 1] as [number, number, number]); + const rotation = transform + ? ([parseFloat(transform.m_LocalRotation.x), parseFloat(transform.m_LocalRotation.y), parseFloat(transform.m_LocalRotation.z), parseFloat(transform.m_LocalRotation.w)] as [ + number, + number, + number, + number, + ]) + : ([0, 0, 0, 1] as [number, number, number, number]); + + // Check if this GameObject has a ParticleSystem component + const ps = getComponentByType(gameObject, "ParticleSystem", components); + + if (ps) { + // It's a particle emitter + const renderer = getComponentByType(gameObject, "ParticleSystemRenderer", components); + const emitterConfig = convertParticleSystem(ps, renderer); + + // Determine render mode from renderer + let renderMode = 0; // Default: BillBoard + let materialId: string | undefined; + if (renderer) { + const m_RenderMode = parseInt(renderer.m_RenderMode || "0"); + switch (m_RenderMode) { + case 0: + renderMode = 0; // BillBoard + break; + case 1: + renderMode = 1; // StretchedBillBoard + break; + case 2: + renderMode = 2; // HorizontalBillBoard + break; + case 3: + renderMode = 3; // VerticalBillBoard + break; + case 4: + renderMode = 4; // Mesh + break; + } + + // Extract material GUID from renderer + if (renderer.m_Materials && Array.isArray(renderer.m_Materials) && renderer.m_Materials.length > 0) { + const materialRef = renderer.m_Materials[0]; + if (materialRef && materialRef.guid) { + materialId = materialRef.guid; + } + } + } + + const emitter: IIntermediateGameObject = { + type: "emitter", + name: gameObject.m_Name || "ParticleSystem", + position, + scale, + rotation, + emitter: emitterConfig, + renderMode, + materialId, + }; + + return emitter; + } + const group: IIntermediateGameObject = { + type: "group", + name: gameObject.m_Name || "Group", + position, + scale, + rotation, + children: [], + }; + + // Recursively convert children + if (transform && transform.m_Children) { + for (const childRef of transform.m_Children) { + const childTransform = components.get(childRef.fileID); + if (childTransform && childTransform.Transform) { + const childGORef = childTransform.Transform.m_GameObject; + const childGOId = childGORef?.fileID || childGORef; + const childGO = components.get(childGOId); + + if (childGO && childGO.GameObject) { + if (!group.children) { + group.children = []; + } + group.children.push(convertGameObject(childGO.GameObject, components)); + } + } + } + } + + return group; +} + +/** + * Convert convertGameObject result to IGroup or IEmitter format + * Recursively processes children + */ +export function convertToIDataFormat(converted: IIntermediateGameObject): IGroup | IEmitter | null { + if (!converted) { + return null; + } + + const uuid = Tools.RandomId(); + + if (converted.type === "group") { + // Convert children recursively + const children: (IGroup | IEmitter)[] = []; + if (converted.children && Array.isArray(converted.children)) { + for (const child of converted.children) { + const childConverted = convertToIDataFormat(child); + if (childConverted) { + children.push(childConverted); + } + } + } + + const group: IGroup = { + uuid, + name: converted.name, + transform: { + position: new Vector3(converted.position[0], converted.position[1], converted.position[2]), + rotation: new Quaternion(converted.rotation[0], converted.rotation[1], converted.rotation[2], converted.rotation[3]), + scale: new Vector3(converted.scale[0], converted.scale[1], converted.scale[2]), + }, + children: children, + }; + return group; + } + if (!converted.emitter) { + console.warn("Emitter config is missing for", converted.name); + return null; + } + const emitter: IEmitter = { + uuid, + name: converted.name, + transform: { + position: new Vector3(converted.position[0], converted.position[1], converted.position[2]), + rotation: new Quaternion(converted.rotation[0], converted.rotation[1], converted.rotation[2], converted.rotation[3]), + scale: new Vector3(converted.scale[0], converted.scale[1], converted.scale[2]), + }, + config: converted.emitter, + systemType: converted.renderMode === 4 ? "solid" : "base", // Mesh = solid, others = base + materialId: converted.materialId, // Link material to emitter + }; + return emitter; +} diff --git a/editor/src/editor/windows/effect-editor/converters/unity/particleSystemConverter.ts b/editor/src/editor/windows/effect-editor/converters/unity/particleSystemConverter.ts new file mode 100644 index 000000000..6ed9e4f62 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unity/particleSystemConverter.ts @@ -0,0 +1,244 @@ +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import type { IParticleSystemConfig, Behavior } from "babylonjs-editor-tools/src/effect/types"; +import { convertColor, convertMinMaxGradient } from "./colorConverter"; +import { convertShape } from "./shapeConverter"; +import { convertMinMaxCurve } from "./valueConverter"; + +/** + * Convert Unity ParticleSystem to our IParticleSystemConfig + */ +export function convertParticleSystem(unityPS: any, _renderer: any): IParticleSystemConfig { + const main = unityPS.InitialModule; + + const config: IParticleSystemConfig = { + version: "2.0", + systemType: "base", // Unity uses GPU particles, similar to our base system + + // Basic properties + minLifeTime: parseFloat(main.startLifetime?.minScalar || main.startLifetime?.scalar || "5"), + maxLifeTime: parseFloat(main.startLifetime?.scalar || "5"), + minSize: parseFloat(main.startSize?.minScalar || main.startSize?.scalar || "1"), + maxSize: parseFloat(main.startSize?.scalar || "1"), + minEmitPower: parseFloat(main.startSpeed?.minScalar || main.startSpeed?.scalar || "5"), + maxEmitPower: parseFloat(main.startSpeed?.scalar || "5"), + emitRate: parseFloat(unityPS.EmissionModule?.rateOverTime?.scalar || "10"), + + // Duration and looping + targetStopDuration: main.looping === "1" ? 0 : parseFloat(main.duration?.scalar || "5"), + preWarmCycles: main.prewarm === "1" ? 100 : 0, + isLocal: main.simulationSpace === "0", // 0 = Local, 1 = World + + // Color + color1: convertColor({ + r: main.startColor?.maxColor?.r || "1", + g: main.startColor?.maxColor?.g || "1", + b: main.startColor?.maxColor?.b || "1", + a: main.startColor?.maxColor?.a || "1", + }), + color2: convertColor({ + r: main.startColor?.maxColor?.r || "1", + g: main.startColor?.maxColor?.g || "1", + b: main.startColor?.maxColor?.b || "1", + a: main.startColor?.maxColor?.a || "1", + }), + + // Rotation + minInitialRotation: parseFloat(main.startRotation?.minScalar || main.startRotation?.scalar || "0"), + maxInitialRotation: parseFloat(main.startRotation?.scalar || "0"), + + // Gravity (if enabled) + gravity: main.gravityModifier?.scalar ? new Vector3(0, parseFloat(main.gravityModifier.scalar) * -9.81, 0) : undefined, + + // Shape/Emitter + shape: convertShape(unityPS.ShapeModule), + + // Behaviors + behaviors: [], + }; + + // Convert modules to behaviors + const behaviors: Behavior[] = []; + + // ColorOverLife + if (unityPS.ColorModule && unityPS.ColorModule.enabled === "1") { + const colorGradient = convertMinMaxGradient(unityPS.ColorModule.gradient); + + // Convert Color type to IColorFunction + let colorFunction: { colorFunctionType: string; data: any }; + if (colorGradient.type === "ConstantColor") { + colorFunction = { + colorFunctionType: "ConstantColor", + data: { + color: { + r: colorGradient.value[0], + g: colorGradient.value[1], + b: colorGradient.value[2], + a: colorGradient.value[3], + }, + }, + }; + } else if (colorGradient.type === "Gradient") { + colorFunction = { + colorFunctionType: "Gradient", + data: { + colorKeys: colorGradient.colorKeys, + alphaKeys: colorGradient.alphaKeys || [], + }, + }; + } else if (colorGradient.type === "RandomColor") { + colorFunction = { + colorFunctionType: "ColorRange", + data: { + colorA: colorGradient.colorA, + colorB: colorGradient.colorB, + }, + }; + } else if (colorGradient.type === "RandomColorBetweenGradient") { + colorFunction = { + colorFunctionType: "RandomColorBetweenGradient", + data: { + gradient1: { + colorKeys: colorGradient.gradient1.colorKeys, + alphaKeys: colorGradient.gradient1.alphaKeys || [], + }, + gradient2: { + colorKeys: colorGradient.gradient2.colorKeys, + alphaKeys: colorGradient.gradient2.alphaKeys || [], + }, + }, + }; + } else { + colorFunction = { + colorFunctionType: "ConstantColor", + data: { color: { r: 1, g: 1, b: 1, a: 1 } }, + }; + } + + behaviors.push({ + type: "ColorOverLife", + color: colorFunction, + }); + } + + // SizeOverLife + if (unityPS.SizeModule && unityPS.SizeModule.enabled === "1") { + const sizeValue = convertMinMaxCurve(unityPS.SizeModule.curve); + behaviors.push({ + type: "SizeOverLife", + size: sizeValue, + }); + } + + // RotationOverLife + if (unityPS.RotationOverLifetimeModule && unityPS.RotationOverLifetimeModule.enabled === "1") { + const rotationZ = convertMinMaxCurve(unityPS.RotationOverLifetimeModule.z || unityPS.RotationOverLifetimeModule.curve); + behaviors.push({ + type: "RotationOverLife", + angularVelocity: rotationZ, + }); + } + + // Rotation3DOverLife (if separate X, Y, Z) + if (unityPS.RotationOverLifetimeModule && unityPS.RotationOverLifetimeModule.enabled === "1" && unityPS.RotationOverLifetimeModule.separateAxes === "1") { + behaviors.push({ + type: "Rotation3DOverLife", + angularVelocityX: convertMinMaxCurve(unityPS.RotationOverLifetimeModule.x), + angularVelocityY: convertMinMaxCurve(unityPS.RotationOverLifetimeModule.y), + angularVelocityZ: convertMinMaxCurve(unityPS.RotationOverLifetimeModule.z), + }); + } + + // VelocityOverLife (SpeedOverLife) + if (unityPS.VelocityModule && unityPS.VelocityModule.enabled === "1") { + const speedModifier = unityPS.VelocityModule.speedModifier || { minMaxState: "0", scalar: "1" }; + behaviors.push({ + type: "SpeedOverLife", + speed: convertMinMaxCurve(speedModifier), + }); + } + + // LimitVelocityOverLife + if (unityPS.ClampVelocityModule && unityPS.ClampVelocityModule.enabled === "1") { + behaviors.push({ + type: "LimitSpeedOverLife", + limitVelocity: convertMinMaxCurve(unityPS.ClampVelocityModule.magnitude), + dampen: parseFloat(unityPS.ClampVelocityModule.dampen || "0.1"), + }); + } + + // ForceOverLife (from Unity's Force module or gravity) + if (unityPS.ForceModule && unityPS.ForceModule.enabled === "1") { + behaviors.push({ + type: "ForceOverLife", + force: { + x: parseFloat(unityPS.ForceModule.x?.scalar || "0"), + y: parseFloat(unityPS.ForceModule.y?.scalar || "0"), + z: parseFloat(unityPS.ForceModule.z?.scalar || "0"), + }, + }); + } + + // ColorBySpeed + if (unityPS.ColorBySpeedModule && unityPS.ColorBySpeedModule.enabled === "1") { + const range = unityPS.ColorBySpeedModule.range; + const colorGradient = convertMinMaxGradient(unityPS.ColorBySpeedModule.gradient); + + let colorFunction: { colorFunctionType: string; data: any }; + if (colorGradient.type === "Gradient") { + colorFunction = { + colorFunctionType: "Gradient", + data: { + colorKeys: colorGradient.colorKeys, + alphaKeys: colorGradient.alphaKeys || [], + }, + }; + } else { + colorFunction = { + colorFunctionType: "ConstantColor", + data: { color: { r: 1, g: 1, b: 1, a: 1 } }, + }; + } + + behaviors.push({ + type: "ColorBySpeed", + color: colorFunction, + minSpeed: { type: "ConstantValue", value: parseFloat(range?.x || "0") }, + maxSpeed: { type: "ConstantValue", value: parseFloat(range?.y || "1") }, + }); + } + + // SizeBySpeed + if (unityPS.SizeBySpeedModule && unityPS.SizeBySpeedModule.enabled === "1") { + const range = unityPS.SizeBySpeedModule.range; + behaviors.push({ + type: "SizeBySpeed", + size: convertMinMaxCurve(unityPS.SizeBySpeedModule.curve), + minSpeed: { type: "ConstantValue", value: parseFloat(range?.x || "0") }, + maxSpeed: { type: "ConstantValue", value: parseFloat(range?.y || "1") }, + }); + } + + // RotationBySpeed + if (unityPS.RotationBySpeedModule && unityPS.RotationBySpeedModule.enabled === "1") { + const range = unityPS.RotationBySpeedModule.range; + behaviors.push({ + type: "RotationBySpeed", + angularVelocity: convertMinMaxCurve(unityPS.RotationBySpeedModule.curve), + minSpeed: { type: "ConstantValue", value: parseFloat(range?.x || "0") }, + maxSpeed: { type: "ConstantValue", value: parseFloat(range?.y || "1") }, + }); + } + + // NoiseModule (approximation) + if (unityPS.NoiseModule && unityPS.NoiseModule.enabled === "1") { + config.noiseStrength = new Vector3( + parseFloat(unityPS.NoiseModule.strengthX?.scalar || "0"), + parseFloat(unityPS.NoiseModule.strengthY?.scalar || "0"), + parseFloat(unityPS.NoiseModule.strengthZ?.scalar || "0") + ); + } + + config.behaviors = behaviors; + + return config; +} diff --git a/editor/src/editor/windows/effect-editor/converters/unity/resourceConverter.ts b/editor/src/editor/windows/effect-editor/converters/unity/resourceConverter.ts new file mode 100644 index 000000000..63430f129 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unity/resourceConverter.ts @@ -0,0 +1,168 @@ +import { Color3 } from "@babylonjs/core/Maths/math.color"; +import { Scene } from "@babylonjs/core/scene"; +import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader"; +import { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; +import type { IMaterial, IGeometry } from "babylonjs-editor-tools/src/effect/types"; +import * as yaml from "js-yaml"; + +/** + * Convert Unity model buffer to IGeometry using Babylon.js loaders + */ +export async function convertUnityModel(guid: string, buffer: Buffer, extension: string, scene: Scene): Promise { + try { + // Determine MIME type based on extension + let mimeType = "application/octet-stream"; + if (extension === "obj") { + mimeType = "text/plain"; + } else if (extension === "fbx") { + mimeType = "application/octet-stream"; + } + + // Create data URL from buffer + const dataUrl = `data:${mimeType};base64,${buffer.toString("base64")}`; + + // Import mesh using Babylon.js SceneLoader + const result = await SceneLoader.ImportMeshAsync("", dataUrl, "", scene); + + if (!result || !result.meshes || result.meshes.length === 0) { + return null; + } + + // Find the first mesh + const mesh = result.meshes.find((m) => m instanceof Mesh) as Mesh | undefined; + if (!mesh || !mesh.geometry) { + return null; + } + + // Extract vertex data + const vertexData = VertexData.ExtractFromMesh(mesh); + if (!vertexData) { + return null; + } + + // Convert to IGeometry format + const geometry: IGeometry = { + uuid: guid, + type: "BufferGeometry", + data: { + attributes: {}, + }, + }; + + // Convert positions + if (vertexData.positions) { + geometry.data!.attributes.position = { + array: Array.from(vertexData.positions), + itemSize: 3, + }; + } + + // Convert normals + if (vertexData.normals) { + geometry.data!.attributes.normal = { + array: Array.from(vertexData.normals), + itemSize: 3, + }; + } + + // Convert UVs + if (vertexData.uvs) { + geometry.data!.attributes.uv = { + array: Array.from(vertexData.uvs), + itemSize: 2, + }; + } + + // Convert indices + if (vertexData.indices) { + geometry.data!.index = { + array: Array.from(vertexData.indices), + }; + } + + // Cleanup: dispose imported meshes + for (const m of result.meshes) { + m.dispose(); + } + + return geometry; + } catch (error) { + console.warn(`Failed to convert Unity model ${guid}:`, error); + return null; + } +} + +/** + * Convert Unity Material YAML to IMaterial + */ +export function convertUnityMaterial(guid: string, yamlContent: string, dependencies: any): IMaterial | null { + try { + // Parse Unity material YAML + const parsed = yaml.load(yamlContent) as any; + if (!parsed || !parsed.Material) { + return null; + } + + const unityMat = parsed.Material; + const material: IMaterial = { + uuid: guid, + }; + + // Extract color + if (unityMat.m_SavedProperties?.m_Colors) { + const colorProps = unityMat.m_SavedProperties.m_Colors; + for (const colorProp of colorProps) { + if (colorProp._Color) { + const r = parseFloat(colorProp._Color.r || "1"); + const g = parseFloat(colorProp._Color.g || "1"); + const b = parseFloat(colorProp._Color.b || "1"); + material.color = new Color3(r, g, b); + break; + } + } + } + + // Extract texture (MainTex) + if (unityMat.m_SavedProperties?.m_TexEnvs) { + for (const texEnv of unityMat.m_SavedProperties.m_TexEnvs) { + if (texEnv._MainTex && texEnv._MainTex.m_Texture) { + const texRef = texEnv._MainTex.m_Texture; + const textureGuid = texRef.guid || texRef.fileID; + if (textureGuid && dependencies.textures?.has(textureGuid)) { + material.map = textureGuid; // Reference to texture UUID + } + break; + } + } + } + + // Extract transparency + if (unityMat.stringTagMap?.RenderType === "Transparent") { + material.transparent = true; + } + + // Extract opacity + if (unityMat.m_SavedProperties?.m_Colors) { + for (const colorProp of unityMat.m_SavedProperties.m_Colors) { + if (colorProp._Color && colorProp._Color.a !== undefined) { + material.opacity = parseFloat(colorProp._Color.a || "1"); + break; + } + } + } + + // Extract blending mode from shader + const shaderFileID = unityMat.m_Shader?.fileID; + if (shaderFileID) { + // Unity shader IDs: 200 = Standard, 203 = Unlit, etc. + // For now, use default blending + material.blending = 0; // Normal blending + } + + return material; + } catch (error) { + console.warn(`Failed to parse Unity material ${guid}:`, error); + return null; + } +} diff --git a/editor/src/editor/windows/effect-editor/converters/unity/shapeConverter.ts b/editor/src/editor/windows/effect-editor/converters/unity/shapeConverter.ts new file mode 100644 index 000000000..410bc4933 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unity/shapeConverter.ts @@ -0,0 +1,43 @@ +/** + * Convert Unity ParticleSystem shape to our emitter shape + */ +export function convertShape(shapeModule: any): any { + if (!shapeModule || shapeModule.enabled !== "1") { + return { type: "point" }; // Default to point emitter + } + + const shapeType = shapeModule.type; + + switch (shapeType) { + case "0": // Sphere + return { + type: "sphere", + radius: parseFloat(shapeModule.radius?.value || "1"), + arc: (parseFloat(shapeModule.arc?.value || "360") / 180) * Math.PI, + thickness: parseFloat(shapeModule.radiusThickness || "1"), + }; + case "4": // Cone + return { + type: "cone", + radius: parseFloat(shapeModule.radius?.value || "1"), + arc: (parseFloat(shapeModule.arc?.value || "360") / 180) * Math.PI, + thickness: parseFloat(shapeModule.radiusThickness || "1"), + angle: (parseFloat(shapeModule.angle?.value || "25") / 180) * Math.PI, + }; + case "5": // Box + return { + type: "box", + width: parseFloat(shapeModule.boxThickness?.x || "1"), + height: parseFloat(shapeModule.boxThickness?.y || "1"), + depth: parseFloat(shapeModule.boxThickness?.z || "1"), + }; + case "10": // Circle + return { + type: "sphere", // Use sphere with arc for circle + radius: parseFloat(shapeModule.radius?.value || "1"), + arc: (parseFloat(shapeModule.arc?.value || "360") / 180) * Math.PI, + }; + default: + return { type: "point" }; + } +} diff --git a/editor/src/editor/windows/effect-editor/converters/unity/utils.ts b/editor/src/editor/windows/effect-editor/converters/unity/utils.ts new file mode 100644 index 000000000..f9c970753 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unity/utils.ts @@ -0,0 +1,105 @@ +/** + * Helper utilities for Unity converter + */ + +/** + * Helper to get component by type from GameObject + */ +export function getComponentByType(gameObject: any, componentType: string, components: Map): any | null { + if (!gameObject.m_Component) { + return null; + } + + for (const compRef of gameObject.m_Component) { + const compId = compRef.component?.fileID || compRef.component; + const comp = components.get(compId); + if (comp && comp[componentType]) { + return comp[componentType]; + } + } + + return null; +} + +/** + * Find root GameObject in hierarchy (Transform with no parent) + * Based on original Unity converter logic + */ +export function findRootGameObject(components: Map): string | null { + // Look for Transform component with m_Father.fileID === "0" + let transformCount = 0; + let gameObjectCount = 0; + + for (const [_id, comp] of components) { + if (comp.Transform) { + transformCount++; + } + if (comp.GameObject) { + gameObjectCount++; + } + + // Check if this component is a Transform + if (comp.Transform) { + // Check if Transform has m_Father with fileID === "0" (no parent = root) + if (comp.Transform.m_Father !== undefined && comp.Transform.m_Father !== null) { + const fatherFileID = typeof comp.Transform.m_Father === "object" ? comp.Transform.m_Father.fileID : comp.Transform.m_Father; + const fatherFileIDStr = String(fatherFileID); + + if (fatherFileIDStr === "0") { + // Found root Transform, get the GameObject it belongs to + const gameObjectRef = comp.Transform.m_GameObject; + if (gameObjectRef) { + const gameObjectFileID = typeof gameObjectRef === "object" ? gameObjectRef.fileID : gameObjectRef; + const gameObjectFileIDStr = String(gameObjectFileID); + + // IMPORTANT: Return the component ID (key in Map) that contains this GameObject + // The gameObjectFileIDStr is the fileID reference, but we need to find the component with that ID + // Components are stored with their YAML anchor ID as the key (e.g., "195608") + const gameObjectComponent = components.get(gameObjectFileIDStr); + if (gameObjectComponent && gameObjectComponent.GameObject) { + return gameObjectFileIDStr; // This is the component ID/key + } + } + } + } else if (comp.Transform.m_GameObject) { + // If no m_Father, it might be root (check if it's the only Transform) + const gameObjectRef = comp.Transform.m_GameObject; + const gameObjectFileID = typeof gameObjectRef === "object" ? gameObjectRef.fileID : gameObjectRef; + // Try this as root if we don't find one with m_Father === "0" + const candidate = String(gameObjectFileID); + // But first check if there's a Transform with explicit m_Father === "0" + let hasExplicitRoot = false; + for (const [_id2, comp2] of components) { + if (comp2.Transform && comp2.Transform.m_Father !== undefined && comp2.Transform.m_Father !== null) { + const fatherFileID2 = typeof comp2.Transform.m_Father === "object" ? comp2.Transform.m_Father.fileID : comp2.Transform.m_Father; + if (String(fatherFileID2) === "0") { + hasExplicitRoot = true; + break; + } + } + } + if (!hasExplicitRoot) { + return candidate; + } + } + } + } + + // Fallback: find first GameObject if no root Transform found + for (const [_id, comp] of components) { + if (comp.GameObject) { + return _id; // Use component ID as GameObject ID + } + } + + return null; +} + +/** + * Unity to Babylon.js coordinate system conversion + * Unity: Y-up, left-handed → Babylon.js: Y-up, left-handed (same!) + * But Quarks was Three.js (right-handed), so no conversion needed for us + */ +export function convertVector3(unityVec: { x: string; y: string; z: string }): [number, number, number] { + return [parseFloat(unityVec.x), parseFloat(unityVec.y), parseFloat(unityVec.z)]; +} diff --git a/editor/src/editor/windows/effect-editor/converters/unity/valueConverter.ts b/editor/src/editor/windows/effect-editor/converters/unity/valueConverter.ts new file mode 100644 index 000000000..77831d8eb --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unity/valueConverter.ts @@ -0,0 +1,108 @@ +import type { Value } from "babylonjs-editor-tools"; + +/** + * Convert Unity AnimationCurve to our PiecewiseBezier Value + */ +export function convertAnimationCurve(curve: any, scalar: number = 1): Value { + const m_Curve = curve.m_Curve; + if (!m_Curve || m_Curve.length === 0) { + return { type: "ConstantValue", value: 0 }; + } + + // If only one key, return constant + if (m_Curve.length === 1) { + return { type: "ConstantValue", value: parseFloat(m_Curve[0].value) * scalar }; + } + + // Convert to PiecewiseBezier + const functions: Array<{ + function: { + p0: number; + p1: number; + p2: number; + p3: number; + }; + start: number; + }> = []; + + // Add initial key if curve doesn't start at 0 + if (m_Curve.length >= 1 && parseFloat(m_Curve[0].time) > 0) { + const val = parseFloat(m_Curve[0].value) * scalar; + functions.push({ + function: { + p0: val, + p1: val, + p2: val, + p3: val, + }, + start: 0, + }); + } + + // Convert each segment + for (let i = 0; i < m_Curve.length - 1; i++) { + const curr = m_Curve[i]; + const next = m_Curve[i + 1]; + const segmentDuration = parseFloat(next.time) - parseFloat(curr.time); + + const p0 = parseFloat(curr.value) * scalar; + const p1 = (parseFloat(curr.value) + (parseFloat(curr.outSlope) * segmentDuration) / 3) * scalar; + const p2 = (parseFloat(next.value) - (parseFloat(next.inSlope) * segmentDuration) / 3) * scalar; + const p3 = parseFloat(next.value) * scalar; + + functions.push({ + function: { + p0, + p1, + p2, + p3, + }, + start: parseFloat(curr.time), + }); + } + + // Add final key if curve doesn't end at 1 + if (m_Curve.length >= 2 && parseFloat(m_Curve[m_Curve.length - 1].time) < 1) { + const val = parseFloat(m_Curve[m_Curve.length - 1].value) * scalar; + functions.push({ + function: { + p0: val, + p1: val, + p2: val, + p3: val, + }, + start: parseFloat(m_Curve[m_Curve.length - 1].time), + }); + } + + return { + type: "PiecewiseBezier", + functions, + }; +} + +/** + * Convert Unity MinMaxCurve to our Value + */ +export function convertMinMaxCurve(minMaxCurve: any): Value { + const minMaxState = minMaxCurve.minMaxState; + const scalar = parseFloat(minMaxCurve.scalar || "1"); + + switch (minMaxState) { + case "0": // Constant + return { type: "ConstantValue", value: scalar }; + case "1": // Curve + return convertAnimationCurve(minMaxCurve.maxCurve, scalar); + case "2": // Random between two constants + return { + type: "IntervalValue", + min: parseFloat(minMaxCurve.minScalar || "0") * scalar, + max: scalar, + }; + case "3": // Random between two curves + // For now, just use max curve (proper implementation would need RandomColor equivalent for Value) + return convertAnimationCurve(minMaxCurve.maxCurve, scalar); + default: + return { type: "ConstantValue", value: scalar }; + } +} diff --git a/editor/src/editor/windows/effect-editor/converters/unityConverter.ts b/editor/src/editor/windows/effect-editor/converters/unityConverter.ts new file mode 100644 index 000000000..046fb0abe --- /dev/null +++ b/editor/src/editor/windows/effect-editor/converters/unityConverter.ts @@ -0,0 +1,187 @@ +/** + * Unity Prefab → Babylon.js Effect Converter + * + * Converts Unity particle system prefabs directly to our Babylon.js effect format, + * bypassing the Quarks JSON intermediate step. + * + * Based on extracted Unity → Quarks converter logic, but outputs IData format. + */ + +import { Scene } from "@babylonjs/core/scene"; +import type { IData, IEmitter, IGroup, IMaterial, ITexture, IImage, IGeometry } from "babylonjs-editor-tools/src/effect/types"; +import { findRootGameObject } from "./unity/utils"; +import { convertGameObject, convertToIDataFormat } from "./unity/gameObjectConverter"; +import { convertUnityModel, convertUnityMaterial } from "./unity/resourceConverter"; + +/** + * Convert Unity prefab components to IData + * + * @param components - Already parsed Unity components Map (parsed in modal) + * @param dependencies - Optional dependencies (textures, materials, models, sounds) + * @param scene - Babylon.js Scene for loading models (required for model parsing) + * @returns IData structure ready for our Effect system + */ +export async function convertUnityPrefabToData( + components: Map, + dependencies?: { + textures?: Map; + materials?: Map; + models?: Map; + sounds?: Map; + meta?: Map; + }, + scene?: Scene +): Promise { + // Validate components is a Map + if (!(components instanceof Map)) { + console.error("convertUnityPrefabToData: components must be a Map, got:", typeof components, components); + throw new Error("components must be a Map"); + } + + let root: IGroup | IEmitter | null = null; + + // Find root GameObject + const rootGameObjectId = findRootGameObject(components); + if (!rootGameObjectId) { + console.warn("No root GameObject found in Unity prefab"); + return { + root: null, + materials: [], + textures: [], + images: [], + geometries: [], + }; + } + + const rootComponent = components.get(rootGameObjectId); + if (!rootComponent) { + return { + root: null, + materials: [], + textures: [], + images: [], + geometries: [], + }; + } + + // Get GameObject from component (could be rootComponent.GameObject or rootComponent itself) + const gameObject = rootComponent.GameObject || rootComponent; + if (!gameObject || (typeof gameObject === "object" && !gameObject.m_Name && !gameObject.m_Component)) { + // Try to find GameObject component directly + for (const [_id, comp] of components) { + if (comp.GameObject && comp.GameObject.m_Name) { + const foundGameObject = comp.GameObject; + if (foundGameObject.m_Component) { + const converted = convertGameObject(foundGameObject, components); + root = convertToIDataFormat(converted); + break; + } + } + } + + if (!root) { + return { + root: null, + materials: [], + textures: [], + images: [], + geometries: [], + }; + } + } else { + // Convert root GameObject and its hierarchy recursively + const converted = convertGameObject(gameObject, components); + root = convertToIDataFormat(converted); + } + + // Process dependencies if provided + const materials: IMaterial[] = []; + const textures: ITexture[] = []; + const images: IImage[] = []; + const geometries: IGeometry[] = []; + + if (dependencies) { + // Convert materials from YAML to IData format + if (dependencies.materials) { + for (const [guid, yamlContent] of dependencies.materials) { + try { + const material = convertUnityMaterial(guid, yamlContent, dependencies); + if (material) { + materials.push(material); + } + } catch (error) { + console.warn(`Failed to convert material ${guid}:`, error); + } + } + } + + // Convert textures to IData format + if (dependencies.textures) { + for (const [guid, buffer] of dependencies.textures) { + // Create image entry for texture + const imageId = `image-${guid}`; + images.push({ + uuid: imageId, + url: `data:image/png;base64,${buffer.toString("base64")}`, // Convert buffer to data URL + }); + + // Create texture entry + textures.push({ + uuid: guid, + image: imageId, + wrapU: 0, // Repeat + wrapV: 0, // Repeat + generateMipmaps: true, + flipY: false, + }); + } + } + + // Convert models to IData format (for mesh particles) + // Parse models using Babylon.js loaders if Scene is provided + if (dependencies.models && scene) { + for (const [guid, buffer] of dependencies.models) { + // Determine file extension from meta + const meta = dependencies.meta?.get(guid); + const path = meta?.path || ""; + const ext = path.split(".").pop()?.toLowerCase() || "fbx"; + + try { + const geometry = await convertUnityModel(guid, buffer, ext, scene); + if (geometry) { + geometries.push(geometry); + } else { + // Fallback: store placeholder if parsing failed + geometries.push({ + uuid: guid, + type: "BufferGeometry", + }); + } + } catch (error) { + console.warn(`Failed to parse model ${guid}:`, error); + // Fallback: store placeholder + geometries.push({ + uuid: guid, + type: "BufferGeometry", + }); + } + } + } else if (dependencies.models) { + // If no Scene provided, store placeholders (models will be loaded later) + for (const [guid] of dependencies.models) { + geometries.push({ + uuid: guid, + type: "BufferGeometry", + }); + } + } + } + + return { + root, + materials, + textures, + images, + geometries, + }; +} diff --git a/editor/src/editor/windows/effect-editor/editors/bezier.tsx b/editor/src/editor/windows/effect-editor/editors/bezier.tsx new file mode 100644 index 000000000..104acf0f7 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/editors/bezier.tsx @@ -0,0 +1,546 @@ +import { Component, ReactNode, MouseEvent } from "react"; +import { EditorInspectorNumberField } from "../../../layout/inspector/fields/number"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../../../ui/shadcn/ui/dropdown-menu"; +import { HiOutlineArrowPath } from "react-icons/hi2"; +import { Button } from "../../../../ui/shadcn/ui/button"; + +export interface IBezierCurve { + p0: number; + p1: number; + p2: number; + p3: number; + start: number; +} + +export interface IBezierEditorProps { + value: any; + onChange: () => void; +} + +export interface IBezierEditorState { + curve: IBezierCurve; + dragging: boolean; + dragPoint: "p0" | "p1" | "p2" | "p3" | null; + hoveredPoint: "p0" | "p1" | "p2" | "p3" | null; + width: number; + height: number; + showValues: boolean; +} + +type CurvePreset = "linear" | "easeIn" | "easeOut" | "easeInOut" | "easeInBack" | "easeOutBack"; + +const CURVE_PRESETS: Record = { + linear: { p0: 0, p1: 0, p2: 1, p3: 1, start: 0 }, + easeIn: { p0: 0, p1: 0.42, p2: 1, p3: 1, start: 0 }, + easeOut: { p0: 0, p1: 0, p2: 0.58, p3: 1, start: 0 }, + easeInOut: { p0: 0, p1: 0.42, p2: 0.58, p3: 1, start: 0 }, + easeInBack: { p0: 0, p1: -0.36, p2: 0.36, p3: 1, start: 0 }, + easeOutBack: { p0: 0, p1: 0.64, p2: 1.36, p3: 1, start: 0 }, +}; + +export class BezierEditor extends Component { + private _svgRef: SVGSVGElement | null = null; + private _containerRef: HTMLDivElement | null = null; + + public constructor(props: IBezierEditorProps) { + super(props); + this.state = { + curve: this._getCurveFromValue(), + dragging: false, + dragPoint: null, + hoveredPoint: null, + width: 400, + height: 250, + showValues: false, + }; + } + + public componentDidMount(): void { + this._updateDimensions(); + window.addEventListener("resize", this._updateDimensions); + } + + public componentWillUnmount(): void { + window.removeEventListener("resize", this._updateDimensions); + } + + private _updateDimensions = (): void => { + if (this._containerRef) { + const rect = this._containerRef.getBoundingClientRect(); + this.setState({ + width: Math.max(300, rect.width - 20), + height: 250, + }); + } + }; + + private _getCurveFromValue(): IBezierCurve { + if (!this.props.value || !this.props.value.data) { + return CURVE_PRESETS.linear; + } + + // Support both old format (array) and new format (direct object) + if (this.props.value.data.functions && Array.isArray(this.props.value.data.functions)) { + const firstFunction = this.props.value.data.functions[0]; + if (firstFunction && firstFunction.function) { + return { + p0: firstFunction.function.p0 ?? 0, + p1: firstFunction.function.p1 ?? 1.0 / 3, + p2: firstFunction.function.p2 ?? (1.0 / 3) * 2, + p3: firstFunction.function.p3 ?? 1, + start: 0, + }; + } + } + + // New format: direct function object + if (this.props.value.data.function) { + return { + p0: this.props.value.data.function.p0 ?? 0, + p1: this.props.value.data.function.p1 ?? 1.0 / 3, + p2: this.props.value.data.function.p2 ?? (1.0 / 3) * 2, + p3: this.props.value.data.function.p3 ?? 1, + start: 0, + }; + } + + return CURVE_PRESETS.linear; + } + + private _saveCurveToValue(): void { + if (!this.props.value) { + return; + } + + if (!this.props.value.data) { + this.props.value.data = {}; + } + + // Save as direct function object (not array) + this.props.value.data.function = { + p0: Math.max(0, Math.min(1, this.state.curve.p0)), + p1: Math.max(0, Math.min(1, this.state.curve.p1)), + p2: Math.max(0, Math.min(1, this.state.curve.p2)), + p3: Math.max(0, Math.min(1, this.state.curve.p3)), + }; + } + + private _applyPreset(preset: CurvePreset): void { + const presetCurve = CURVE_PRESETS[preset]; + this.setState({ curve: { ...presetCurve } }, () => { + this._saveCurveToValue(); + this.props.onChange(); + }); + } + + private _screenToSvg(clientX: number, clientY: number): { x: number; y: number } { + if (!this._svgRef) { + return { x: 0, y: 0 }; + } + + const rect = this._svgRef.getBoundingClientRect(); + const vb = this._svgRef.viewBox?.baseVal; + if (!vb) { + return { + x: clientX - rect.left, + y: clientY - rect.top, + }; + } + + const scaleX = rect.width / vb.width; + const scaleY = rect.height / vb.height; + const useScale = Math.min(scaleX, scaleY); + + const offsetX = (rect.width - vb.width * useScale) / 2; + const offsetY = (rect.height - vb.height * useScale) / 2; + + return { + x: (clientX - rect.left - offsetX) / useScale, + y: (clientY - rect.top - offsetY) / useScale, + }; + } + + private _valueToSvgY(value: number): number { + // Map value from [0, 1] to SVG Y coordinate + // Center is at height/2, full range is height * 0.8 (40% above and below center) + const padding = this.state.height * 0.1; + const range = this.state.height * 0.8; + return padding + (1 - value) * range; + } + + private _svgYToValue(svgY: number): number { + const padding = this.state.height * 0.1; + const range = this.state.height * 0.8; + return Math.max(0, Math.min(1, (this.state.height - svgY - padding) / range)); + } + + private _handleMouseDown = (ev: MouseEvent, point: "p0" | "p1" | "p2" | "p3"): void => { + ev.stopPropagation(); + if (ev.button !== 0) { + return; + } + + this.setState({ + dragging: true, + dragPoint: point, + }); + + let mouseMoveListener: (event: globalThis.MouseEvent) => void; + let mouseUpListener: (event: globalThis.MouseEvent) => void; + + mouseMoveListener = (ev: globalThis.MouseEvent) => { + if (!this.state.dragging || !this.state.dragPoint) { + return; + } + + const svgPos = this._screenToSvg(ev.clientX, ev.clientY); + const value = this._svgYToValue(svgPos.y); + + const curve = { ...this.state.curve }; + + if (this.state.dragPoint === "p0") { + curve.p0 = value; + } else if (this.state.dragPoint === "p1") { + curve.p1 = value; + } else if (this.state.dragPoint === "p2") { + curve.p2 = value; + } else if (this.state.dragPoint === "p3") { + curve.p3 = value; + } + + this.setState({ curve }); + }; + + mouseUpListener = () => { + document.body.removeEventListener("mousemove", mouseMoveListener); + document.body.removeEventListener("mouseup", mouseUpListener); + document.body.style.cursor = ""; + + this._saveCurveToValue(); + this.props.onChange(); + + this.setState({ + dragging: false, + dragPoint: null, + }); + }; + + document.body.style.cursor = "move"; + document.body.addEventListener("mousemove", mouseMoveListener); + document.body.addEventListener("mouseup", mouseUpListener); + }; + + private _bezierValue(t: number, p0: number, p1: number, p2: number, p3: number): number { + const t2 = t * t; + const t3 = t2 * t; + const mt = 1 - t; + const mt2 = mt * mt; + const mt3 = mt2 * mt; + return p0 * mt3 + p1 * mt2 * t * 3 + p2 * mt * t2 * 3 + p3 * t3; + } + + private _renderCurve(curve: IBezierCurve): ReactNode { + const segments = 100; + const pathData: string[] = []; + const gradientId = `gradient-${Math.random().toString(36).substr(2, 9)}`; + + // Calculate actual Bezier curve points + // For cubic Bezier: B(t) = (1-t)³P₀ + 3(1-t)²tP₁ + 3(1-t)t²P₂ + t³P₃ + // But we're using p0, p1, p2, p3 as control values, not positions + // We need to map them to actual control points + const p0X = 0; + const p0Y = this._valueToSvgY(curve.p0); + const p1X = this.state.width / 3; + const p1Y = this._valueToSvgY(curve.p1); + const p2X = (this.state.width * 2) / 3; + const p2Y = this._valueToSvgY(curve.p2); + const p3X = this.state.width; + const p3Y = this._valueToSvgY(curve.p3); + + // Generate curve path + for (let i = 0; i <= segments; i++) { + const t = i / segments; + const x = t * this.state.width; + const y = this._bezierValue(t, p0Y, p1Y, p2Y, p3Y); + + if (i === 0) { + pathData.push(`M ${x} ${y}`); + } else { + pathData.push(`L ${x} ${y}`); + } + } + + const isHovered = (point: "p0" | "p1" | "p2" | "p3") => this.state.hoveredPoint === point || this.state.dragPoint === point; + const getPointRadius = (point: "p0" | "p1" | "p2" | "p3") => { + if (point === "p0" || point === "p3") { + return isHovered(point) ? 7 : 5; + } + return isHovered(point) ? 6 : 4; + }; + const getPointColor = (point: "p0" | "p1" | "p2" | "p3") => { + if (point === "p0" || point === "p3") { + return isHovered(point) ? "#3b82f6" : "#2563eb"; + } + return isHovered(point) ? "#8b5cf6" : "#7c3aed"; + }; + + return ( + + + + + + + + + {/* Filled area under curve */} + + + {/* Curve line */} + + + {/* Control lines */} + + + + {/* Control points */} + {(["p0", "p1", "p2", "p3"] as const).map((point) => { + const x = point === "p0" ? p0X : point === "p1" ? p1X : point === "p2" ? p2X : p3X; + const y = point === "p0" ? p0Y : point === "p1" ? p1Y : point === "p2" ? p2Y : p3Y; + const value = curve[point]; + const radius = getPointRadius(point); + const color = getPointColor(point); + + return ( + + {/* Outer glow when hovered */} + {isHovered(point) && } + {/* Point circle */} + this._handleMouseDown(ev, point)} + onMouseEnter={() => this.setState({ hoveredPoint: point, showValues: true })} + onMouseLeave={() => this.setState({ hoveredPoint: null, showValues: false })} + /> + {/* Value label */} + {isHovered(point) && ( + + {value.toFixed(2)} + + )} + + ); + })} + + ); + } + + private _renderGrid(): ReactNode { + const gridLines: ReactNode[] = []; + + // Horizontal grid lines (value markers) + for (let i = 0; i <= 10; i++) { + const value = i / 10; + const y = this._valueToSvgY(value); + const isMainLine = i % 5 === 0; + + gridLines.push( + + + {isMainLine && ( + + {value.toFixed(1)} + + )} + + ); + } + + // Vertical grid lines (time markers) + for (let i = 0; i <= 10; i++) { + const t = i / 10; + const x = t * this.state.width; + const isMainLine = i % 5 === 0; + + gridLines.push( + + + {isMainLine && ( + + {t.toFixed(1)} + + )} + + ); + } + + // Center line (value = 0.5) + gridLines.push( + + ); + + return {gridLines}; + } + + public render(): ReactNode { + return ( +
(this._containerRef = ref)} className="flex flex-col gap-3 w-full"> + {/* Toolbar */} +
+
+ Curve Editor +
+
+ + + + + + this._applyPreset("linear")}>Linear + this._applyPreset("easeIn")}>Ease In + this._applyPreset("easeOut")}>Ease Out + this._applyPreset("easeInOut")}>Ease In-Out + this._applyPreset("easeInBack")}>Ease In Back + this._applyPreset("easeOutBack")}>Ease Out Back + + + +
+
+ + {/* SVG Canvas */} +
+ (this._svgRef = ref)} + width={this.state.width} + height={this.state.height} + viewBox={`0 0 ${this.state.width} ${this.state.height}`} + className="w-full h-full" + style={{ background: "var(--background)" }} + > + {/* Grid */} + {this._renderGrid()} + + {/* Curve */} + {this._renderCurve(this.state.curve)} + + + {/* Axis labels */} +
Time
+
Value
+
+ + {/* Value inputs */} + +
+
+ + { + this.setState({ curve: { ...this.state.curve } }); + this._saveCurveToValue(); + this.props.onChange(); + }} + /> +
+
+ + { + this.setState({ curve: { ...this.state.curve } }); + this._saveCurveToValue(); + this.props.onChange(); + }} + /> +
+
+ + { + this.setState({ curve: { ...this.state.curve } }); + this._saveCurveToValue(); + this.props.onChange(); + }} + /> +
+
+ + { + this.setState({ curve: { ...this.state.curve } }); + this._saveCurveToValue(); + this.props.onChange(); + }} + /> +
+
+
+
+ ); + } +} diff --git a/editor/src/editor/windows/effect-editor/editors/color-function.tsx b/editor/src/editor/windows/effect-editor/editors/color-function.tsx new file mode 100644 index 000000000..f177aaa75 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/editors/color-function.tsx @@ -0,0 +1,356 @@ +import { ReactNode } from "react"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; + +import { EditorInspectorColorField } from "../../../layout/inspector/fields/color"; +import { EditorInspectorColorGradientField } from "../../../layout/inspector/fields/gradient"; +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; +import type { IGradientKey } from "../../../../ui/gradient-picker"; + +export type ColorFunctionType = "ConstantColor" | "ColorRange" | "Gradient" | "RandomColor" | "RandomColorBetweenGradient"; + +export interface IColorFunctionEditorProps { + value: any; + onChange: () => void; + label: string; +} + +export function ColorFunctionEditor(props: IColorFunctionEditorProps): ReactNode { + const { value, onChange, label } = props; + + // Convert from Quarks format to UI format if needed + // Quarks format: { color: { type: "Gradient" | "ConstantColor" | "RandomColorBetweenGradient", ... } } + // UI format: { colorFunctionType: "Gradient" | "ConstantColor" | "RandomColorBetweenGradient", data: {...} } + if (value && !value.colorFunctionType) { + // Check if this is Quarks format + if (value.color && typeof value.color === "object" && "type" in value.color) { + const colorType = value.color.type; + + if (colorType === "Gradient") { + // Convert Gradient format + value.colorFunctionType = "Gradient"; + value.data = { + colorKeys: value.color.color?.keys || [], + alphaKeys: value.color.alpha?.keys || [], + }; + delete value.color; + } else if (colorType === "ConstantColor") { + // Convert ConstantColor format + value.colorFunctionType = "ConstantColor"; + const color = + value.color.color || + (value.color.value ? { r: value.color.value[0], g: value.color.value[1], b: value.color.value[2], a: value.color.value[3] } : { r: 1, g: 1, b: 1, a: 1 }); + value.data = { + color: { + r: color.r ?? 1, + g: color.g ?? 1, + b: color.b ?? 1, + a: color.a !== undefined ? color.a : 1, + }, + }; + delete value.color; + } else if (colorType === "RandomColorBetweenGradient") { + // Convert RandomColorBetweenGradient format + value.colorFunctionType = "RandomColorBetweenGradient"; + value.data = { + gradient1: { + colorKeys: value.color.gradient1?.color?.keys || [], + alphaKeys: value.color.gradient1?.alpha?.keys || [], + }, + gradient2: { + colorKeys: value.color.gradient2?.color?.keys || [], + alphaKeys: value.color.gradient2?.alpha?.keys || [], + }, + }; + delete value.color; + } else { + // Fallback: try old format + const hasColorKeys = value.color.color?.keys && value.color.color.keys.length > 0; + const hasAlphaKeys = value.color.alpha?.keys && value.color.alpha.keys.length > 0; + const hasKeys = value.color.keys && value.color.keys.length > 0; + + if (hasColorKeys || hasAlphaKeys || hasKeys) { + value.colorFunctionType = "Gradient"; + value.data = { + colorKeys: hasColorKeys ? value.color.color.keys : hasKeys ? value.color.keys : [], + alphaKeys: hasAlphaKeys ? value.color.alpha.keys : [], + }; + delete value.color; + } else { + value.colorFunctionType = "ConstantColor"; + value.data = {}; + } + } + } else if (value.color) { + // Old Quarks format without type + const hasColorKeys = value.color.color?.keys && value.color.color.keys.length > 0; + const hasAlphaKeys = value.color.alpha?.keys && value.color.alpha.keys.length > 0; + const hasKeys = value.color.keys && value.color.keys.length > 0; + + if (hasColorKeys || hasAlphaKeys || hasKeys) { + value.colorFunctionType = "Gradient"; + value.data = { + colorKeys: hasColorKeys ? value.color.color.keys : hasKeys ? value.color.keys : [], + alphaKeys: hasAlphaKeys ? value.color.alpha.keys : [], + }; + delete value.color; + } else { + value.colorFunctionType = "ConstantColor"; + value.data = {}; + } + } else { + // Initialize color function type if not set + value.colorFunctionType = "ConstantColor"; + value.data = {}; + } + } + + const functionType = value.colorFunctionType as ColorFunctionType; + + // Ensure data object exists + if (!value.data) { + value.data = {}; + } + + const typeItems = [ + { text: "Color", value: "ConstantColor" }, + { text: "Color Range", value: "ColorRange" }, + { text: "Gradient", value: "Gradient" }, + { text: "Random Color", value: "RandomColor" }, + { text: "Random Between Gradient", value: "RandomColorBetweenGradient" }, + ]; + + return ( + <> + { + // Reset data when type changes and initialize defaults + const newType = value.colorFunctionType; + value.data = {}; + if (newType === "ConstantColor") { + value.data.color = new Color4(1, 1, 1, 1); + } else if (newType === "ColorRange") { + value.data.colorA = new Color4(0, 0, 0, 1); + value.data.colorB = new Color4(1, 1, 1, 1); + } else if (newType === "Gradient") { + value.data.colorKeys = [ + { pos: 0, value: [0, 0, 0, 1] }, + { pos: 1, value: [1, 1, 1, 1] }, + ]; + value.data.alphaKeys = [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ]; + } else if (newType === "RandomColor") { + value.data.colorA = new Color4(0, 0, 0, 1); + value.data.colorB = new Color4(1, 1, 1, 1); + } else if (newType === "RandomColorBetweenGradient") { + value.data.gradient1 = { + colorKeys: [ + { pos: 0, value: [0, 0, 0, 1] }, + { pos: 1, value: [1, 1, 1, 1] }, + ], + alphaKeys: [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ], + }; + value.data.gradient2 = { + colorKeys: [ + { pos: 0, value: [1, 0, 0, 1] }, + { pos: 1, value: [0, 1, 0, 1] }, + ], + alphaKeys: [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ], + }; + } + onChange(); + }} + /> + + {functionType === "ConstantColor" && ( + <> + {!value.data.color && (value.data.color = new Color4(1, 1, 1, 1))} + + + )} + + {functionType === "ColorRange" && ( + <> + {!value.data.colorA && (value.data.colorA = new Color4(0, 0, 0, 1))} + {!value.data.colorB && (value.data.colorB = new Color4(1, 1, 1, 1))} + + + + )} + + {functionType === "Gradient" && + (() => { + // Convert old format (Vector3 + position) to new format (array + pos) if needed + const convertColorKeys = (keys: any[]): IGradientKey[] => { + if (!keys || keys.length === 0) { + return [ + { pos: 0, value: [0, 0, 0, 1] }, + { pos: 1, value: [1, 1, 1, 1] }, + ]; + } + return keys.map((key) => { + if (key.color && key.color instanceof Vector3) { + // Old format: { color: Vector3, position: number } + return { + pos: key.position ?? key.pos ?? 0, + value: [key.color.x, key.color.y, key.color.z, 1], + }; + } + // Already in new format or other format + return { + pos: key.pos ?? key.position ?? 0, + value: Array.isArray(key.value) + ? key.value + : typeof key.value === "object" && "r" in key.value + ? [key.value.r, key.value.g, key.value.b, key.value.a ?? 1] + : [0, 0, 0, 1], + }; + }); + }; + + const convertAlphaKeys = (keys: any[]): IGradientKey[] => { + if (!keys || keys.length === 0) { + return [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ]; + } + return keys.map((key) => ({ + pos: key.pos ?? key.position ?? 0, + value: typeof key.value === "number" ? key.value : 1, + })); + }; + + const wrapperGradient = { + colorKeys: convertColorKeys(value.data.colorKeys), + alphaKeys: convertAlphaKeys(value.data.alphaKeys), + }; + + return ( + { + value.data.colorKeys = newColorKeys; + value.data.alphaKeys = newAlphaKeys; + onChange(); + }} + /> + ); + })()} + + {functionType === "RandomColor" && ( + <> + {!value.data.colorA && (value.data.colorA = new Color4(0, 0, 0, 1))} + {!value.data.colorB && (value.data.colorB = new Color4(1, 1, 1, 1))} + + + + )} + + {functionType === "RandomColorBetweenGradient" && + (() => { + // Convert old format to new format if needed + const convertColorKeys = (keys: any[]): IGradientKey[] => { + if (!keys || keys.length === 0) { + return [ + { pos: 0, value: [0, 0, 0, 1] }, + { pos: 1, value: [1, 1, 1, 1] }, + ]; + } + return keys.map((key) => { + if (key.color && key.color instanceof Vector3) { + return { + pos: key.position ?? key.pos ?? 0, + value: [key.color.x, key.color.y, key.color.z, 1], + }; + } + return { + pos: key.pos ?? key.position ?? 0, + value: Array.isArray(key.value) + ? key.value + : typeof key.value === "object" && "r" in key.value + ? [key.value.r, key.value.g, key.value.b, key.value.a ?? 1] + : [0, 0, 0, 1], + }; + }); + }; + + const convertAlphaKeys = (keys: any[]): IGradientKey[] => { + if (!keys || keys.length === 0) { + return [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ]; + } + return keys.map((key) => ({ + pos: key.pos ?? key.position ?? 0, + value: typeof key.value === "number" ? key.value : 1, + })); + }; + + if (!value.data.gradient1) { + value.data.gradient1 = {}; + } + if (!value.data.gradient2) { + value.data.gradient2 = {}; + } + + const wrapperGradient1 = { + colorKeys: convertColorKeys(value.data.gradient1.colorKeys), + alphaKeys: convertAlphaKeys(value.data.gradient1.alphaKeys), + }; + + const wrapperGradient2 = { + colorKeys: convertColorKeys(value.data.gradient2.colorKeys), + alphaKeys: convertAlphaKeys(value.data.gradient2.alphaKeys), + }; + + return ( + <> + +
Gradient 1
+ { + value.data.gradient1.colorKeys = newColorKeys; + value.data.gradient1.alphaKeys = newAlphaKeys; + onChange(); + }} + /> +
+ +
Gradient 2
+ { + value.data.gradient2.colorKeys = newColorKeys; + value.data.gradient2.alphaKeys = newAlphaKeys; + onChange(); + }} + /> +
+ + ); + })()} + + ); +} diff --git a/editor/src/editor/windows/effect-editor/editors/color.tsx b/editor/src/editor/windows/effect-editor/editors/color.tsx new file mode 100644 index 000000000..3a412aa8f --- /dev/null +++ b/editor/src/editor/windows/effect-editor/editors/color.tsx @@ -0,0 +1,325 @@ +import { ReactNode } from "react"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; + +import { EditorInspectorColorField } from "../../../layout/inspector/fields/color"; +import { EditorInspectorColorGradientField } from "../../../layout/inspector/fields/gradient"; +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; + +import { type Color, parseConstantColor } from "babylonjs-editor-tools"; + +export type EffectColorType = "ConstantColor" | "ColorRange" | "Gradient" | "RandomColor" | "RandomColorBetweenGradient"; + +export interface IEffectColorEditorProps { + value: Color | undefined; + onChange: (newValue: Color) => void; + label?: string; +} + +/** + * Editor for VEffectColor (ConstantColor, ColorRange, Gradient, RandomColor, RandomColorBetweenGradient) + * Works directly with VEffectColor types, not wrappers + */ +export function EffectColorEditor(props: IEffectColorEditorProps): ReactNode { + const { value, onChange, label } = props; + + // Determine current type from value + let currentType: EffectColorType = "ConstantColor"; + if (value) { + if (typeof value === "string" || Array.isArray(value)) { + currentType = "ConstantColor"; + } else if ("type" in value) { + if (value.type === "ConstantColor") { + currentType = "ConstantColor"; + } else if (value.type === "ColorRange") { + currentType = "ColorRange"; + } else if (value.type === "Gradient") { + currentType = "Gradient"; + } else if (value.type === "RandomColor") { + currentType = "RandomColor"; + } else if (value.type === "RandomColorBetweenGradient") { + currentType = "RandomColorBetweenGradient"; + } + } + } + + const typeItems = [ + { text: "Color", value: "ConstantColor" }, + { text: "Color Range", value: "ColorRange" }, + { text: "Gradient", value: "Gradient" }, + { text: "Random Color", value: "RandomColor" }, + { text: "Random Between Gradient", value: "RandomColorBetweenGradient" }, + ]; + + // Wrapper object for EditorInspectorListField + const wrapper = { + get type() { + return currentType; + }, + set type(newType: EffectColorType) { + currentType = newType; + // Convert value to new type + let newValue: Color; + const currentColor = value ? parseConstantColor(value) : new Color4(1, 1, 1, 1); + if (newType === "ConstantColor") { + newValue = { type: "ConstantColor", value: [currentColor.r, currentColor.g, currentColor.b, currentColor.a] }; + } else if (newType === "ColorRange") { + newValue = { + type: "ColorRange", + colorA: [currentColor.r, currentColor.g, currentColor.b, currentColor.a], + colorB: [1, 1, 1, 1], + }; + } else if (newType === "Gradient") { + newValue = { + type: "Gradient", + colorKeys: [ + { pos: 0, value: [currentColor.r, currentColor.g, currentColor.b, currentColor.a] }, + { pos: 1, value: [1, 1, 1, 1] }, + ], + alphaKeys: [ + { pos: 0, value: currentColor.a }, + { pos: 1, value: 1 }, + ], + }; + } else if (newType === "RandomColor") { + newValue = { + type: "RandomColor", + colorA: [currentColor.r, currentColor.g, currentColor.b, currentColor.a], + colorB: [1, 1, 1, 1], + }; + } else { + // RandomColorBetweenGradient + newValue = { + type: "RandomColorBetweenGradient", + gradient1: { + colorKeys: [ + { pos: 0, value: [currentColor.r, currentColor.g, currentColor.b, currentColor.a] }, + { pos: 1, value: [1, 1, 1, 1] }, + ], + alphaKeys: [ + { pos: 0, value: currentColor.a }, + { pos: 1, value: 1 }, + ], + }, + gradient2: { + colorKeys: [ + { pos: 0, value: [1, 0, 0, 1] }, + { pos: 1, value: [0, 1, 0, 1] }, + ], + alphaKeys: [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ], + }, + }; + } + onChange(newValue); + }, + }; + + return ( + <> + { + // Type change is handled by setter + }} + /> + + {currentType === "ConstantColor" && ( + <> + {(() => { + const constantColor = value ? parseConstantColor(value) : new Color4(1, 1, 1, 1); + const wrapperColor = { + get color() { + return constantColor; + }, + set color(newColor: Color4) { + onChange({ type: "ConstantColor", value: [newColor.r, newColor.g, newColor.b, newColor.a] }); + }, + }; + return {}} />; + })()} + + )} + + {currentType === "ColorRange" && ( + <> + {(() => { + const colorRange = value && typeof value === "object" && "type" in value && value.type === "ColorRange" ? value : null; + const colorA = colorRange ? new Color4(colorRange.colorA[0], colorRange.colorA[1], colorRange.colorA[2], colorRange.colorA[3]) : new Color4(0, 0, 0, 1); + const colorB = colorRange ? new Color4(colorRange.colorB[0], colorRange.colorB[1], colorRange.colorB[2], colorRange.colorB[3]) : new Color4(1, 1, 1, 1); + const wrapperRange = { + get colorA() { + return colorA; + }, + set colorA(newColor: Color4) { + const currentB = colorRange ? colorRange.colorB : [1, 1, 1, 1]; + onChange({ type: "ColorRange", colorA: [newColor.r, newColor.g, newColor.b, newColor.a], colorB: currentB as [number, number, number, number] }); + }, + get colorB() { + return colorB; + }, + set colorB(newColor: Color4) { + const currentA = colorRange ? colorRange.colorA : [0, 0, 0, 1]; + onChange({ + type: "ColorRange", + colorA: currentA as [number, number, number, number], + colorB: [newColor.r, newColor.g, newColor.b, newColor.a] as [number, number, number, number], + }); + }, + }; + return ( + <> + {}} /> + {}} /> + + ); + })()} + + )} + + {currentType === "Gradient" && + (() => { + const gradientValue = value && typeof value === "object" && "type" in value && value.type === "Gradient" ? value : null; + const defaultColorKeys = [ + { pos: 0, value: [0, 0, 0, 1] }, + { pos: 1, value: [1, 1, 1, 1] }, + ]; + const defaultAlphaKeys = [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ]; + const wrapperGradient = { + colorKeys: gradientValue?.colorKeys || defaultColorKeys, + alphaKeys: gradientValue?.alphaKeys || defaultAlphaKeys, + }; + return ( + { + onChange({ + type: "Gradient", + colorKeys: newColorKeys, + alphaKeys: newAlphaKeys, + }); + }} + /> + ); + })()} + + {currentType === "RandomColor" && ( + <> + {(() => { + const randomColor = value && typeof value === "object" && "type" in value && value.type === "RandomColor" ? value : null; + const colorA = randomColor + ? new Color4(randomColor.colorA[0], randomColor.colorA[1], randomColor.colorA[2], randomColor.colorA[3]) + : new Color4(0, 0, 0, 1); + const colorB = randomColor + ? new Color4(randomColor.colorB[0], randomColor.colorB[1], randomColor.colorB[2], randomColor.colorB[3]) + : new Color4(1, 1, 1, 1); + const wrapperRandom = { + get colorA() { + return colorA; + }, + set colorA(newColor: Color4) { + const currentB = randomColor ? randomColor.colorB : [1, 1, 1, 1]; + onChange({ type: "RandomColor", colorA: [newColor.r, newColor.g, newColor.b, newColor.a], colorB: currentB as [number, number, number, number] }); + }, + get colorB() { + return colorB; + }, + set colorB(newColor: Color4) { + const currentA = randomColor ? randomColor.colorA : [0, 0, 0, 1]; + onChange({ + type: "RandomColor", + colorA: currentA as [number, number, number, number], + colorB: [newColor.r, newColor.g, newColor.b, newColor.a] as [number, number, number, number], + }); + }, + }; + return ( + <> + {}} /> + {}} /> + + ); + })()} + + )} + + {currentType === "RandomColorBetweenGradient" && + (() => { + const randomGradient = value && typeof value === "object" && "type" in value && value.type === "RandomColorBetweenGradient" ? value : null; + const defaultColorKeys = [ + { pos: 0, value: [0, 0, 0, 1] }, + { pos: 1, value: [1, 1, 1, 1] }, + ]; + const defaultAlphaKeys = [ + { pos: 0, value: 1 }, + { pos: 1, value: 1 }, + ]; + + const wrapperGradient1 = { + colorKeys: randomGradient?.gradient1?.colorKeys || defaultColorKeys, + alphaKeys: randomGradient?.gradient1?.alphaKeys || defaultAlphaKeys, + }; + + const wrapperGradient2 = { + colorKeys: randomGradient?.gradient2?.colorKeys || defaultColorKeys, + alphaKeys: randomGradient?.gradient2?.alphaKeys || defaultAlphaKeys, + }; + + return ( + <> + +
Gradient 1
+ { + if (randomGradient) { + onChange({ + type: "RandomColorBetweenGradient", + gradient1: { + colorKeys: newColorKeys, + alphaKeys: newAlphaKeys, + }, + gradient2: randomGradient.gradient2, + }); + } + }} + /> +
+ +
Gradient 2
+ { + if (randomGradient) { + onChange({ + type: "RandomColorBetweenGradient", + gradient1: randomGradient.gradient1, + gradient2: { + colorKeys: newColorKeys, + alphaKeys: newAlphaKeys, + }, + }); + } + }} + /> +
+ + ); + })()} + + ); +} diff --git a/editor/src/editor/windows/effect-editor/editors/function.tsx b/editor/src/editor/windows/effect-editor/editors/function.tsx new file mode 100644 index 000000000..88acb9d27 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/editors/function.tsx @@ -0,0 +1,130 @@ +import { ReactNode } from "react"; + +import { EditorInspectorNumberField } from "../../../layout/inspector/fields/number"; +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; + +import { BezierEditor } from "./bezier"; + +export type FunctionType = "ConstantValue" | "IntervalValue" | "PiecewiseBezier" | "Vector3Function"; + +export interface IFunctionEditorProps { + value: any; + onChange: () => void; + availableTypes?: FunctionType[]; + label: string; +} + +export function FunctionEditor(props: IFunctionEditorProps): ReactNode { + const { value, onChange, availableTypes, label } = props; + + // Default available types if not specified + const types = availableTypes || ["ConstantValue", "IntervalValue", "PiecewiseBezier", "Vector3Function"]; + + // Initialize function type if not set + if (!value || !value.functionType) { + value.functionType = types[0]; + value.data = {}; + } + + const functionType = value.functionType as FunctionType; + + // Ensure data object exists + if (!value.data) { + value.data = {}; + } + + const typeItems = types.map((type) => ({ + text: type, + value: type, + })); + + return ( + <> + { + // Reset data when type changes and initialize defaults + const newType = value.functionType; + value.data = {}; + if (newType === "ConstantValue") { + value.data.value = 1.0; + } else if (newType === "IntervalValue") { + value.data.min = 0; + value.data.max = 1; + } else if (newType === "PiecewiseBezier") { + value.data.function = { p0: 0, p1: 1.0 / 3, p2: (1.0 / 3) * 2, p3: 1 }; + } else if (newType === "Vector3Function") { + value.data.x = { functionType: "ConstantValue", data: { value: 0 } }; + value.data.y = { functionType: "ConstantValue", data: { value: 0 } }; + value.data.z = { functionType: "ConstantValue", data: { value: 0 } }; + } + onChange(); + }} + /> + + {functionType === "ConstantValue" && ( + <> + {value.data.value === undefined && (value.data.value = 1.0)} + + + )} + + {functionType === "IntervalValue" && ( + <> + {value.data.min === undefined && (value.data.min = 0)} + {value.data.max === undefined && (value.data.max = 1)} + +
{label ? "Range" : ""}
+
+ + +
+
+ + )} + + {functionType === "PiecewiseBezier" && ( + <> + {!value.data.function && (value.data.function = { p0: 0, p1: 1.0 / 3, p2: (1.0 / 3) * 2, p3: 1 })} + + + )} + + {functionType === "Vector3Function" && ( + <> + +
X
+ +
+ +
Y
+ +
+ +
Z
+ +
+ + )} + + ); +} diff --git a/editor/src/editor/windows/effect-editor/editors/index.ts b/editor/src/editor/windows/effect-editor/editors/index.ts new file mode 100644 index 000000000..15478b643 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/editors/index.ts @@ -0,0 +1,6 @@ +export * from "./value"; +export * from "./color"; +export * from "./rotation"; +export * from "./function"; +export * from "./color-function"; +export * from "./bezier"; diff --git a/editor/src/editor/windows/effect-editor/editors/rotation.tsx b/editor/src/editor/windows/effect-editor/editors/rotation.tsx new file mode 100644 index 000000000..6593efadd --- /dev/null +++ b/editor/src/editor/windows/effect-editor/editors/rotation.tsx @@ -0,0 +1,318 @@ +import { ReactNode } from "react"; + +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; + +import { type Rotation, type IEulerRotation, type IAxisAngleRotation, type IRandomQuatRotation, parseConstantValue, type Value } from "babylonjs-editor-tools"; +import { EffectValueEditor } from "./value"; + +export type EffectRotationType = IEulerRotation["type"] | IAxisAngleRotation["type"] | IRandomQuatRotation["type"]; + +export interface IEffectRotationEditorProps { + value: Rotation | undefined; + onChange: (newValue: Rotation) => void; + label?: string; +} + +/** + * Editor for VEffectRotation (Euler, AxisAngle, RandomQuat) + * Works directly with VEffectRotation types, not wrappers + */ +export function EffectRotationEditor(props: IEffectRotationEditorProps): ReactNode { + const { value, onChange, label } = props; + + // Determine current type from value + let currentType: EffectRotationType = "Euler"; + if (value) { + if ( + typeof value === "number" || + (typeof value === "object" && "type" in value && (value.type === "ConstantValue" || value.type === "IntervalValue" || value.type === "PiecewiseBezier")) + ) { + // Simple VEffectValue - convert to Euler + currentType = "Euler"; + } else if (typeof value === "object" && "type" in value) { + if (value.type === "Euler") { + currentType = "Euler"; + } else if (value.type === "AxisAngle") { + currentType = "AxisAngle"; + } else if (value.type === "RandomQuat") { + currentType = "RandomQuat"; + } + } + } + + const typeItems = [ + { text: "Euler", value: "Euler" }, + { text: "Axis Angle", value: "AxisAngle" }, + { text: "Random Quat", value: "RandomQuat" }, + ]; + + // Wrapper object for EditorInspectorListField + const wrapper = { + get type() { + return currentType; + }, + set type(newType: EffectRotationType) { + currentType = newType; + // Convert value to new type + let newValue: Rotation; + if (newType === "Euler") { + // Convert current value to Euler + if (value && typeof value === "object" && "type" in value && value.type === "Euler") { + newValue = value; + } else { + const angleZ = value ? (typeof value === "number" ? value : parseConstantValue(value as Value)) : 0; + newValue = { + type: "Euler", + angleZ: { type: "ConstantValue", value: angleZ }, + order: "xyz", + }; + } + } else if (newType === "AxisAngle") { + // Convert to AxisAngle + const angle = value ? (typeof value === "number" ? value : parseConstantValue(value as Value)) : 0; + newValue = { + type: "AxisAngle", + x: { type: "ConstantValue", value: 0 }, + y: { type: "ConstantValue", value: 0 }, + z: { type: "ConstantValue", value: 1 }, + angle: { type: "ConstantValue", value: angle }, + }; + } else { + // RandomQuat + newValue = { type: "RandomQuat" }; + } + onChange(newValue); + }, + }; + + return ( + <> + { + // Type change is handled by setter + }} + /> + + {currentType === "Euler" && ( + <> + {(() => { + const eulerValue = value && typeof value === "object" && "type" in value && value.type === "Euler" ? value : null; + const angleX = eulerValue?.angleX || { type: "ConstantValue" as const, value: 0 }; + const angleY = eulerValue?.angleY || { type: "ConstantValue" as const, value: 0 }; + const angleZ = eulerValue?.angleZ || { type: "ConstantValue" as const, value: 0 }; + const order = eulerValue?.order || "xyz"; + + const orderWrapper = { + get order() { + return order; + }, + set order(newOrder: "xyz" | "zyx") { + if (eulerValue) { + onChange({ ...eulerValue, order: newOrder }); + } else { + onChange({ + type: "Euler", + angleX, + angleY, + angleZ, + order: newOrder, + }); + } + }, + }; + + return ( + <> + {}} + /> + +
Angle X
+ { + if (eulerValue) { + onChange({ ...eulerValue, angleX: newAngleX as Value }); + } else { + onChange({ + type: "Euler", + angleX: newAngleX as Value, + angleY, + angleZ, + order, + }); + } + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> +
+ +
Angle Y
+ { + if (eulerValue) { + onChange({ ...eulerValue, angleY: newAngleY as Value }); + } else { + onChange({ + type: "Euler", + angleX, + angleY: newAngleY as Value, + angleZ, + order, + }); + } + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> +
+ +
Angle Z
+ { + if (eulerValue) { + onChange({ ...eulerValue, angleZ: newAngleZ as Value }); + } else { + onChange({ + type: "Euler", + angleX, + angleY, + angleZ: newAngleZ as Value, + order, + }); + } + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> +
+ + ); + })()} + + )} + + {currentType === "AxisAngle" && ( + <> + {(() => { + const axisAngleValue = value && typeof value === "object" && "type" in value && value.type === "AxisAngle" ? value : null; + const x = axisAngleValue?.x || { type: "ConstantValue" as const, value: 0 }; + const y = axisAngleValue?.y || { type: "ConstantValue" as const, value: 0 }; + const z = axisAngleValue?.z || { type: "ConstantValue" as const, value: 1 }; + const angle = axisAngleValue?.angle || { type: "ConstantValue" as const, value: 0 }; + + return ( + <> + +
Axis X
+ { + if (axisAngleValue) { + onChange({ ...axisAngleValue, x: newX as Value }); + } else { + onChange({ + type: "AxisAngle", + x: newX as Value, + y, + z, + angle, + }); + } + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> +
+ +
Axis Y
+ { + if (axisAngleValue) { + onChange({ ...axisAngleValue, y: newY as Value }); + } else { + onChange({ + type: "AxisAngle", + x, + y: newY as Value, + z, + angle, + }); + } + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> +
+ +
Axis Z
+ { + if (axisAngleValue) { + onChange({ ...axisAngleValue, z: newZ as Value }); + } else { + onChange({ + type: "AxisAngle", + x, + y, + z: newZ as Value, + angle, + }); + } + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> +
+ +
Angle
+ { + if (axisAngleValue) { + onChange({ ...axisAngleValue, angle: newAngle as Value }); + } else { + onChange({ + type: "AxisAngle", + x, + y, + z, + angle: newAngle as Value, + }); + } + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> +
+ + ); + })()} + + )} + + {currentType === "RandomQuat" && ( + <> +
Random quaternion rotation will be applied to each particle
+ + )} + + ); +} diff --git a/editor/src/editor/windows/effect-editor/editors/value.tsx b/editor/src/editor/windows/effect-editor/editors/value.tsx new file mode 100644 index 000000000..e84d2a201 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/editors/value.tsx @@ -0,0 +1,335 @@ +import { ReactNode } from "react"; + +import { EditorInspectorNumberField } from "../../../layout/inspector/fields/number"; +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; + +import { type Value, type IConstantValue, type IIntervalValue, parseConstantValue, parseIntervalValue } from "babylonjs-editor-tools"; + +type PiecewiseBezier = Extract; +import { BezierEditor } from "./bezier"; + +// Vec3Function is a custom editor extension, not part of the core Value type +export type EffectValueType = IConstantValue["type"] | IIntervalValue["type"] | PiecewiseBezier["type"] | "Vec3Function"; + +export interface IVec3Function { + type: "Vec3Function"; + x: Value; + y: Value; + z: Value; +} + +export interface IEffectValueEditorProps { + value: Value | IVec3Function | undefined; + onChange: (newValue: Value | IVec3Function) => void; + label?: string; + availableTypes?: EffectValueType[]; + min?: number; + step?: number; +} + +/** + * Editor for VEffectValue (ConstantValue, IntervalValue, PiecewiseBezier, Vec3Function) + * Works directly with VEffectValue types, not wrappers + */ +export function EffectValueEditor(props: IEffectValueEditorProps): ReactNode { + const { value, onChange, label, availableTypes, min, step } = props; + + const types = availableTypes || ["ConstantValue", "IntervalValue", "PiecewiseBezier"]; + + // Determine current type from value + let currentType: EffectValueType = "ConstantValue"; + if (value) { + if (typeof value === "number") { + currentType = "ConstantValue"; + } else if ("type" in value) { + if (value.type === "Vec3Function") { + currentType = "Vec3Function"; + } else if (value.type === "ConstantValue") { + currentType = "ConstantValue"; + } else if (value.type === "IntervalValue") { + currentType = "IntervalValue"; + } else if (value.type === "PiecewiseBezier") { + currentType = "PiecewiseBezier"; + } + } + } + + const typeItems = types.map((type) => ({ + text: type, + value: type, + })); + + // Wrapper object for EditorInspectorListField + const wrapper = { + get type() { + return currentType; + }, + set type(newType: EffectValueType) { + currentType = newType; + // Convert value to new type + let newValue: Value | IVec3Function; + if (newType === "ConstantValue") { + const currentValue = + value && typeof value !== "number" && "type" in value && value.type !== "Vec3Function" + ? parseConstantValue(value as Value) + : typeof value === "number" + ? value + : 1; + newValue = { type: "ConstantValue", value: currentValue }; + } else if (newType === "IntervalValue") { + const interval = value && typeof value !== "number" && "type" in value && value.type !== "Vec3Function" ? parseIntervalValue(value as Value) : { min: 0, max: 1 }; + newValue = { type: "IntervalValue", min: interval.min, max: interval.max }; + } else if (newType === "Vec3Function") { + const currentValue = + value && typeof value !== "number" && "type" in value && value.type !== "Vec3Function" + ? parseConstantValue(value as Value) + : typeof value === "number" + ? value + : 1; + newValue = { + type: "Vec3Function", + x: { type: "ConstantValue", value: currentValue }, + y: { type: "ConstantValue", value: currentValue }, + z: { type: "ConstantValue", value: currentValue }, + }; + } else { + // PiecewiseBezier - convert from current value + const currentValue = + value && typeof value !== "number" && "type" in value && value.type !== "Vec3Function" + ? parseConstantValue(value as Value) + : typeof value === "number" + ? value + : 1; + newValue = { + type: "PiecewiseBezier", + functions: [ + { + function: { p0: currentValue, p1: currentValue, p2: currentValue, p3: currentValue }, + start: 0, + }, + ], + }; + } + onChange(newValue); + }, + }; + + return ( + <> + { + // Type change is handled by setter + }} + /> + + {currentType === "ConstantValue" && ( + <> + {(() => { + const constantValue = + value && typeof value !== "number" && "type" in value && value.type !== "Vec3Function" + ? parseConstantValue(value as Value) + : typeof value === "number" + ? value + : 1; + const wrapperValue = { + get value() { + return constantValue; + }, + set value(newVal: number) { + onChange({ type: "ConstantValue", value: newVal }); + }, + }; + return ( + { + // Value change is handled by setter + }} + /> + ); + })()} + + )} + + {currentType === "IntervalValue" && ( + <> + {(() => { + const interval = + value && typeof value !== "number" && "type" in value && value.type !== "Vec3Function" ? parseIntervalValue(value as Value) : { min: 0, max: 1 }; + const wrapperInterval = { + get min() { + return interval.min; + }, + set min(newMin: number) { + const currentMax = value && typeof value !== "number" && "type" in value && value.type === "IntervalValue" ? value.max : interval.max; + onChange({ type: "IntervalValue", min: newMin, max: currentMax }); + }, + get max() { + return interval.max; + }, + set max(newMax: number) { + const currentMin = value && typeof value !== "number" && "type" in value && value.type === "IntervalValue" ? value.min : interval.min; + onChange({ type: "IntervalValue", min: currentMin, max: newMax }); + }, + }; + return ( + +
{label ? "Range" : ""}
+
+ { + // Value change is handled by setter + }} + /> + { + // Value change is handled by setter + }} + /> +
+
+ ); + })()} + + )} + + {currentType === "PiecewiseBezier" && ( + <> + {(() => { + // Convert VEffectValue to wrapper format for BezierEditor + const bezierValue = value && typeof value !== "number" && "type" in value && value.type === "PiecewiseBezier" ? value : null; + const wrapperBezier = { + get functionType() { + return "PiecewiseBezier"; + }, + set functionType(_: string) {}, + get data() { + if (!bezierValue || bezierValue.functions.length === 0) { + return { + function: { p0: 1, p1: 1.0 / 3, p2: (1.0 / 3) * 2, p3: 1 }, + }; + } + // Use first function for editing + return { + function: bezierValue.functions[0].function, + }; + }, + set data(newData: any) { + // Update first function or create new + if (!bezierValue) { + onChange({ + type: "PiecewiseBezier", + functions: [ + { + function: newData.function || { p0: 1, p1: 1.0 / 3, p2: (1.0 / 3) * 2, p3: 1 }, + start: 0, + }, + ], + }); + } else { + const newFunctions = [...bezierValue.functions]; + newFunctions[0] = { + ...newFunctions[0], + function: newData.function || newFunctions[0].function, + }; + onChange({ + type: "PiecewiseBezier", + functions: newFunctions, + }); + } + }, + }; + return {}} />; + })()} + + )} + + {currentType === "Vec3Function" && ( + <> + {(() => { + const vec3Value = value && typeof value !== "number" && "type" in value && value.type === "Vec3Function" ? value : null; + const currentX = vec3Value ? vec3Value.x : { type: "ConstantValue" as const, value: 1 }; + const currentY = vec3Value ? vec3Value.y : { type: "ConstantValue" as const, value: 1 }; + const currentZ = vec3Value ? vec3Value.z : { type: "ConstantValue" as const, value: 1 }; + return ( + <> + +
X
+ { + onChange({ + type: "Vec3Function", + x: newX as Value, + y: currentY, + z: currentZ, + }); + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + min={min} + step={step} + /> +
+ +
Y
+ { + onChange({ + type: "Vec3Function", + x: currentX, + y: newY as Value, + z: currentZ, + }); + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + min={min} + step={step} + /> +
+ +
Z
+ { + onChange({ + type: "Vec3Function", + x: currentX, + y: currentY, + z: newZ as Value, + }); + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + min={min} + step={step} + /> +
+ + ); + })()} + + )} + + ); +} diff --git a/editor/src/editor/windows/effect-editor/graph.tsx b/editor/src/editor/windows/effect-editor/graph.tsx new file mode 100644 index 000000000..79f54d396 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/graph.tsx @@ -0,0 +1,1034 @@ +import { Component, ReactNode } from "react"; +import { Tree, TreeNodeInfo } from "@blueprintjs/core"; + +import { AiOutlinePlus, AiOutlineClose } from "react-icons/ai"; +import { IoSparklesSharp } from "react-icons/io5"; +import { HiOutlineFolder } from "react-icons/hi2"; + +import { + ContextMenu, + ContextMenuContent, + ContextMenuItem, + ContextMenuTrigger, + ContextMenuSeparator, + ContextMenuSub, + ContextMenuSubTrigger, + ContextMenuSubContent, +} from "../../../ui/shadcn/ui/context-menu"; +import { IEffectEditor } from "."; +import { saveSingleFileDialog } from "../../../tools/dialog"; +import { readJSON, writeJSON } from "fs-extra"; +import { toast } from "sonner"; +import { + Effect, + type IEffectNode, + EffectSolidParticleSystem, + EffectParticleSystem, + type IData, + type IGroup, + type IEmitter, + type ITransform, + type IParticleSystemConfig, + deserializeData, +} from "babylonjs-editor-tools"; +import { IQuarksJSON } from "./converters/quarks/types"; +import { QuarksConverter } from "./converters"; +import { basename, dirname } from "path"; +import { Quaternion } from "@babylonjs/core/Maths/math.vector"; +import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; + +export interface IEffectEditorGraphProps { + filePath: string | null; + onNodeSelected?: (nodeId: string | number | null) => void; + editor: IEffectEditor; +} + +export interface IEffectEditorGraphState { + nodes: TreeNodeInfo[]; + selectedNodeId: string | number | null; +} + +interface IEffectInfo { + id: string; + name: string; + effect: Effect; + data: IData; // Store full IData including resources for serialization +} + +/** + * Effect file format with metadata and multiple effects + */ +export interface IEffectFile { + version: string; + effects: IEffectData[]; +} + +/** + * Single effect data in the file + */ +interface IEffectData { + id: string; + name: string; + data: IData; +} + +export class EffectEditorGraph extends Component { + private _effects: Map = new Map(); + /** Map of node instances to unique IDs for tree nodes */ + private _nodeIdMap: Map = new Map(); + + public constructor(props: IEffectEditorGraphProps) { + super(props); + + this.state = { + nodes: [], + selectedNodeId: null, + }; + } + + /** + * Get the first effect (for backward compatibility) + */ + public getEffect(): Effect | null { + const firstEffect = this._effects.values().next().value; + return firstEffect ? firstEffect.effect : null; + } + + /** + * Get all effects + */ + public getAllEffects(): Effect[] { + return Array.from(this._effects.values()).map((info) => info.effect); + } + + /** + * Get effect by ID + */ + public getEffectById(id: string): Effect | null { + const info = this._effects.get(id); + return info ? info.effect : null; + } + + /** + * Finds a node in the tree by ID + */ + private _findNodeById(nodes: TreeNodeInfo[], nodeId: string | number): TreeNodeInfo | null { + for (const node of nodes) { + if (node.id === nodeId) { + return node; + } + if (node.childNodes) { + const found = this._findNodeById(node.childNodes, nodeId); + if (found) { + return found; + } + } + } + return null; + } + + /** + * Gets node data by ID from tree + */ + public getNodeData(nodeId: string | number): IEffectNode | null { + const node = this._findNodeById(this.state.nodes, nodeId); + return node?.nodeData || null; + } + + public componentDidMount(): void {} + + public componentDidUpdate(_prevProps: IEffectEditorGraphProps): void {} + + /** + * Loads nodes from Quarks JSON file + */ + public async loadFromQuarksFile(filePath: string): Promise { + try { + if (!this.props.editor.preview?.scene) { + console.error("Scene is not available"); + return; + } + + const dirnamePath = dirname(filePath); + const originalJsonData = await readJSON(filePath); + + const parser = new QuarksConverter(); + const parseResult = parser.convert(originalJsonData as IQuarksJSON); + + const effect = new Effect(parseResult, this.props.editor.preview.scene, dirnamePath + "/"); + + const effectId = `effect-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; + const effectName = basename(filePath, ".json") || "Effect"; + + this._effects.set(effectId, { + id: effectId, + name: effectName, + effect: effect, + data: parseResult, + }); + + this._rebuildTree(); + + effect.start(); + + setTimeout(() => { + if (this.props.editor?.preview) { + (this.props.editor.preview as any).forceUpdate?.(); + } + }, 100); + } catch (error) { + console.error("Failed to load Effect file:", error); + } + } + /** + * Loads nodes from JSON file + */ + public async loadFromFile(filePath: string): Promise { + try { + if (!this.props.editor.preview?.scene) { + console.error("Scene is not available"); + return; + } + + const dirnamePath = dirname(filePath); + const fileData = await readJSON(filePath); + + // Check if it's new format (IEffectFile) or old format (IData) + if (fileData.version && fileData.effects) { + // New format: IEffectFile + const effectFile = fileData as IEffectFile; + this._effects.clear(); + + for (const effectData of effectFile.effects) { + // Deserialize data to ensure proper Color4, Vector3, Quaternion instances + const deserializedData = deserializeData(effectData.data); + const effect = new Effect(deserializedData, this.props.editor.preview!.scene, dirnamePath + "/"); + this._effects.set(effectData.id, { + id: effectData.id, + name: effectData.name, + effect: effect, + data: deserializedData, + }); + effect.start(); + } + } else { + // Old format: IData (backward compatibility) + // Deserialize data to ensure proper Color4, Vector3, Quaternion instances + const deserializedData = deserializeData(fileData as IData); + const effect = new Effect(deserializedData, this.props.editor.preview!.scene, dirnamePath + "/"); + + const effectId = `effect-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; + const fileName = basename(filePath); + const effectName = fileName.replace(/\.(fx|json)$/, "") || "Effect"; + + this._effects.set(effectId, { + id: effectId, + name: effectName, + effect: effect, + data: deserializedData, + }); + + effect.start(); + } + + this._rebuildTree(); + + setTimeout(() => { + if (this.props.editor?.preview) { + (this.props.editor.preview as any).forceUpdate?.(); + } + }, 100); + } catch (error) { + console.error("Failed to load Effect file:", error); + toast.error(`Failed to load Effect file: ${error instanceof Error ? error.message : String(error)}`); + } + } + + /** + * Load effect from Unity IData (converted from prefab) + */ + public async loadFromUnityData(data: any, prefabName: string): Promise { + try { + if (!this.props.editor.preview?.scene) { + console.error("Scene is not available"); + return; + } + + // Create effect from IData + const effectName = prefabName.replace(".prefab", "").split("/").pop() || "Unity Effect"; + const effect = new Effect(data, this.props.editor.preview.scene); + + // Generate unique ID for effect + const effectId = `unity-effect-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; + + // Store effect with data + this._effects.set(effectId, { + id: effectId, + name: effectName, + effect: effect, + data: data, + }); + + // Rebuild tree with all effects + this._rebuildTree(); + + // Start systems + effect.start(); + + // Notify preview to sync playing state + setTimeout(() => { + if (this.props.editor?.preview) { + (this.props.editor.preview as any).forceUpdate?.(); + } + }, 100); + } catch (error) { + console.error("Failed to load Unity prefab:", error); + throw error; + } + } + + /** + * Rebuild tree from all effects + */ + private _rebuildTree(): void { + // Clear node ID map when rebuilding tree to ensure unique IDs + this._nodeIdMap.clear(); + + const nodes: TreeNodeInfo[] = []; + + for (const [effectId, effectInfo] of this._effects.entries()) { + if (effectInfo.effect.root) { + // Use effect root directly as the tree node, but update its name to effect name + effectInfo.effect.root.name = effectInfo.name; + effectInfo.effect.root.uuid = effectId; + + const treeNode = this._convertNodeToTreeNode(effectInfo.effect.root, true); + nodes.push(treeNode); + } + } + + this.setState({ nodes }); + } + + /** + * Generate unique ID for a node + */ + private _generateUniqueNodeId(Node: IEffectNode): string { + // Check if we already have an ID for this node instance + if (this._nodeIdMap.has(Node)) { + return this._nodeIdMap.get(Node)!; + } + + // Generate unique ID + const uniqueId = `node-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + this._nodeIdMap.set(Node, uniqueId); + return uniqueId; + } + + /** + * Converts IEffectNode to TreeNodeInfo recursively + */ + private _convertNodeToTreeNode(Node: IEffectNode, isEffectRoot: boolean = false): TreeNodeInfo { + // Always use unique ID instead of uuid or name + const nodeId = this._generateUniqueNodeId(Node); + const childNodes = Node.children.length > 0 ? Node.children.map((child) => this._convertNodeToTreeNode(child, false)) : undefined; + + // Check if solid particle system + const isSolid = Node.data instanceof EffectSolidParticleSystem; + + // Determine icon based on node type (sparkles for all particles, with color coding) + let icon: JSX.Element; + if (isEffectRoot) { + icon = ; + } else if (Node.type === "particle") { + icon = ; + } else { + icon = ; + } + + // Get system type label for particles + const secondaryLabel = + Node.type === "particle" ? ( + {isSolid ? "Solid" : "Base"} + ) : undefined; + + return { + id: nodeId, + label: this._getNodeLabelComponent({ id: nodeId, nodeData: Node } as any, Node.name), + icon, + secondaryLabel, + isExpanded: isEffectRoot || Node.type === "group", + childNodes, + isSelected: false, + hasCaret: isEffectRoot || Node.type === "group" || (childNodes && childNodes.length > 0), + nodeData: Node, + }; + } + + /** + * Updates node names in the graph (called when name changes in properties) + */ + public updateNodeNames(): void { + const nodes = this._updateAllNodeNames(this.state.nodes); + this.setState({ nodes }); + } + + /** + * Updates all node names in the tree from actual data + */ + private _updateAllNodeNames(nodes: TreeNodeInfo[]): TreeNodeInfo[] { + return nodes.map((n) => { + const nodeName = n.nodeData?.name || "Unknown"; + const childNodes = n.childNodes ? this._updateAllNodeNames(n.childNodes) : undefined; + return { + ...n, + label: this._getNodeLabelComponent(n, nodeName), + childNodes, + }; + }); + } + + public render(): ReactNode { + return ( +
+ {this.state.nodes.length > 0 && ( +
+ this._handleNodeExpanded(n)} + onNodeCollapse={(n) => this._handleNodeCollapsed(n)} + onNodeClick={(n) => this._handleNodeClicked(n)} + /> +
+ )} + +
{ + ev.preventDefault(); + ev.dataTransfer.dropEffect = "copy"; + }} + onDrop={(ev) => this._handleDropEmpty(ev)} + > + + +
+ {this.state.nodes.length === 0 &&
No particles. Right-click to add.
} +
+
+ + + + Add + + + { + ev.dataTransfer.setData("Effect-editor/create-effect", "effect"); + }} + onClick={() => this._handleCreateEffect()} + > + Effect + + + + +
+
+
+ ); + } + + private _handleNodeExpanded(node: TreeNodeInfo): void { + const nodeId = node.id; + const nodes = this._updateNodeExpanded(this.state.nodes, nodeId as string | number, true); + this.setState({ nodes }); + } + + private _handleNodeCollapsed(node: TreeNodeInfo): void { + const nodeId = node.id; + const nodes = this._updateNodeExpanded(this.state.nodes, nodeId as string | number, false); + this.setState({ nodes }); + } + + private _updateNodeExpanded(nodes: TreeNodeInfo[], nodeId: string | number, isExpanded: boolean): TreeNodeInfo[] { + return nodes.map((n) => { + const nodeName = n.nodeData?.name || "Unknown"; + if (n.id === nodeId) { + return { + ...n, + label: this._getNodeLabelComponent(n, nodeName), + isExpanded, + childNodes: n.childNodes ? this._updateNodeExpanded(n.childNodes, nodeId, isExpanded) : undefined, + }; + } + const childNodes = n.childNodes ? this._updateNodeExpanded(n.childNodes, nodeId, isExpanded) : undefined; + return { + ...n, + label: this._getNodeLabelComponent(n, nodeName), + childNodes, + }; + }); + } + + private _handleNodeClicked(node: TreeNodeInfo): void { + const selectedId = node.id as string | number; + const nodes = this._updateNodeSelection(this.state.nodes, selectedId); + this.setState({ nodes, selectedNodeId: selectedId }); + this.props.onNodeSelected?.(selectedId); + } + + private _updateNodeSelection(nodes: TreeNodeInfo[], selectedId: string | number): TreeNodeInfo[] { + return nodes.map((n) => { + const nodeName = n.nodeData?.name || "Unknown"; + const isSelected = n.id === selectedId; + const childNodes = n.childNodes ? this._updateNodeSelection(n.childNodes, selectedId) : undefined; + return { + ...n, + label: this._getNodeLabelComponent(n, nodeName), + isSelected, + childNodes, + }; + }); + } + + private _getNodeLabelComponent(node: TreeNodeInfo, name: string): JSX.Element { + const label = ( +
{ + if (node.nodeData?.type === "group") { + ev.preventDefault(); + ev.stopPropagation(); + ev.dataTransfer.dropEffect = "copy"; + } + }} + onDrop={(ev) => { + if (node.nodeData?.type === "group") { + ev.preventDefault(); + ev.stopPropagation(); + this._handleDropOnNode(node, ev); + } + }} + > + {name} +
+ ); + + return ( + + {label} + + + + Add + + + {node.nodeData?.type === "group" && ( + <> + { + ev.dataTransfer.setData("Effect-editor/create-item", "base-particle"); + }} + onClick={() => this._handleAddParticleSystemToNode(node, "base")} + > + Base Particle + + { + ev.dataTransfer.setData("Effect-editor/create-item", "solid-particle"); + }} + onClick={() => this._handleAddParticleSystemToNode(node, "solid")} + > + Solid Particle + + { + ev.dataTransfer.setData("Effect-editor/create-item", "group"); + }} + onClick={() => this._handleAddGroupToNode(node)} + > + Group + + + )} + + + {this._isEffectRootNode(node) && ( + <> + + this._handleExportEffect(node)}>Export + + )} + + this._handleDeleteNode(node)}> + Delete + + + + ); + } + + /** + * Check if node is an effect root node + */ + private _isEffectRootNode(node: TreeNodeInfo): boolean { + const nodeData = node.nodeData; + if (!nodeData || !nodeData.uuid) { + return false; + } + + // Check if this node is the root of any effect + return this._effects.has(nodeData.uuid); + } + + /** + * Export effect to JSON file + */ + private async _handleExportEffect(node: TreeNodeInfo): Promise { + const nodeData = node.nodeData; + if (!nodeData || !nodeData.uuid) { + return; + } + + const effectInfo = this._effects.get(nodeData.uuid); + if (!effectInfo || !effectInfo.data) { + toast.error("Cannot export effect: data not available"); + return; + } + + const filePath = saveSingleFileDialog({ + title: "Export Effect", + filters: [{ name: "Effect Files", extensions: ["effect"] }], + defaultPath: `${effectInfo.name}.effect`, + }); + + if (!filePath) { + return; + } + + try { + // Serialize current state of the effect + const serializedData = this._serializeEffectToData(effectInfo); + await writeJSON(filePath, serializedData, { + spaces: "\t", + encoding: "utf-8", + }); + + toast.success(`Effect exported successfully to ${filePath}`); + } catch (error) { + console.error("Failed to export effect:", error); + toast.error(`Failed to export effect: ${error instanceof Error ? error.message : String(error)}`); + } + } + + /** + * Serialize IEffectNode tree back to IData format + */ + private _serializeNodeToData(node: IEffectNode): IGroup | IEmitter | null { + if (node.type === "group") { + const transformNode = node.data as TransformNode; + const transform: ITransform = { + position: transformNode.position.clone(), + rotation: transformNode.rotationQuaternion ? transformNode.rotationQuaternion.clone() : Quaternion.Identity(), + scale: transformNode.scaling.clone(), + }; + + const group: IGroup = { + uuid: node.uuid, + name: node.name, + transform, + children: node.children.map((child) => this._serializeNodeToData(child)).filter((child): child is IGroup | IEmitter => child !== null), + }; + + return group; + } else if (node.type === "particle") { + const system = node.data as EffectParticleSystem | EffectSolidParticleSystem; + const emitter = system.emitter as TransformNode; + const transform: ITransform = { + position: emitter.position.clone(), + rotation: emitter.rotationQuaternion ? emitter.rotationQuaternion.clone() : Quaternion.Identity(), + scale: emitter.scaling.clone(), + }; + + const config = this._serializeSystemToConfig(system); + + const emitterData: IEmitter = { + uuid: node.uuid, + name: node.name, + transform, + config, + systemType: system instanceof EffectSolidParticleSystem ? "solid" : "base", + }; + + return emitterData; + } + + return null; + } + + /** + * Serialize particle system to IParticleSystemConfig + */ + private _serializeSystemToConfig(system: EffectParticleSystem | EffectSolidParticleSystem): IParticleSystemConfig { + const config: IParticleSystemConfig = { + systemType: system instanceof EffectSolidParticleSystem ? "solid" : "base", + minSize: system.minSize, + maxSize: system.maxSize, + minLifeTime: system.minLifeTime, + maxLifeTime: system.maxLifeTime, + minEmitPower: system.minEmitPower, + maxEmitPower: system.maxEmitPower, + emitRate: system.emitRate, + targetStopDuration: system.targetStopDuration, + manualEmitCount: system.manualEmitCount, + preWarmCycles: system.preWarmCycles, + preWarmStepOffset: system.preWarmStepOffset, + color1: system.color1, + color2: system.color2, + colorDead: system.colorDead, + minInitialRotation: system.minInitialRotation, + maxInitialRotation: system.maxInitialRotation, + isLocal: system.isLocal, + disposeOnStop: system.disposeOnStop, + gravity: system.gravity, + noiseStrength: system.noiseStrength, + minAngularSpeed: system.minAngularSpeed, + maxAngularSpeed: system.maxAngularSpeed, + minScaleX: system.minScaleX, + maxScaleX: system.maxScaleX, + minScaleY: system.minScaleY, + maxScaleY: system.maxScaleY, + }; + + // Add behaviors + if (system.behaviorConfigs && system.behaviorConfigs.length > 0) { + config.behaviors = [...system.behaviorConfigs]; + } + + // Add gradients if available (would need to extract from gradient systems) + // For now, we'll rely on behaviors for gradient data + + return config; + } + + /** + * Serialize a single effect to IData format + */ + private _serializeEffectToData(effectInfo: IEffectInfo): IData { + if (!effectInfo.effect.root) { + return { + root: null, + materials: effectInfo.data.materials || [], + textures: effectInfo.data.textures || [], + images: effectInfo.data.images || [], + geometries: effectInfo.data.geometries || [], + }; + } + + const rootData = this._serializeNodeToData(effectInfo.effect.root); + return { + root: rootData, + materials: effectInfo.data.materials || [], + textures: effectInfo.data.textures || [], + images: effectInfo.data.images || [], + geometries: effectInfo.data.geometries || [], + }; + } + + /** + * Serialize all effects to file format + */ + public serializeToFileFormat(): IEffectFile { + const effects: IEffectData[] = []; + + for (const [effectId, effectInfo] of this._effects.entries()) { + const effectData = this._serializeEffectToData(effectInfo); + + effects.push({ + id: effectId, + name: effectInfo.name, + data: effectData, + }); + + // Update stored data with serialized version + effectInfo.data = effectData; + } + + return { + version: "1.0.0", + effects, + }; + } + + private _handleCreateEffect(): void { + if (!this.props.editor.preview?.scene) { + console.error("Scene is not available"); + return; + } + + // Create empty effect with empty IData + const emptyData: IData = { + root: null, + materials: [], + textures: [], + images: [], + geometries: [], + }; + const effect = new Effect(emptyData, this.props.editor.preview.scene); + + // Generate unique ID and name for effect + const effectId = `effect-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; + let effectName = "Effect"; + let counter = 1; + while (Array.from(this._effects.values()).some((info) => info.name === effectName)) { + effectName = `Effect ${counter}`; + counter++; + } + + // Store effect with the same empty data + this._effects.set(effectId, { + id: effectId, + name: effectName, + effect: effect, + data: emptyData, + }); + + // Rebuild tree with all effects + this._rebuildTree(); + } + + private _findEffectForNode(node: TreeNodeInfo): Effect | null { + // Find the effect that contains this node by traversing up the tree + const nodeData = node.nodeData; + if (!nodeData) { + return null; + } + + // First check if this is an effect root node + if (nodeData.uuid) { + const effectInfo = this._effects.get(nodeData.uuid); + if (effectInfo) { + return effectInfo.effect; + } + } + + // Find effect by checking if node is in any effect's hierarchy + for (const effectInfo of this._effects.values()) { + const effect = effectInfo.effect; + if (effect.root) { + // Check if node is part of this effect's hierarchy + const findNodeInHierarchy = (current: IEffectNode): boolean => { + // Use instance comparison and uuid for matching + if (current === nodeData || (current.uuid && nodeData.uuid && current.uuid === nodeData.uuid)) { + return true; + } + for (const child of current.children) { + if (findNodeInHierarchy(child)) { + return true; + } + } + return false; + }; + + if (findNodeInHierarchy(effect.root)) { + return effect; + } + } + } + + return null; + } + + private _handleAddParticleSystemToNode(node: TreeNodeInfo, systemType: "solid" | "base"): void { + const effect = this._findEffectForNode(node); + if (!effect) { + console.error("No effect found for node"); + return; + } + + const nodeData = node.nodeData; + if (!nodeData || nodeData.type !== "group") { + console.error("Cannot add particle system: parent is not a group"); + return; + } + + const newNode = effect.createParticleSystem(nodeData, systemType); + if (newNode) { + // Rebuild tree with all effects + this._rebuildTree(); + } + } + + private _handleAddGroupToNode(node: TreeNodeInfo): void { + const effect = this._findEffectForNode(node); + if (!effect) { + console.error("No effect found for node"); + return; + } + + const nodeData = node.nodeData; + if (!nodeData || nodeData.type !== "group") { + console.error("Cannot add group: parent is not a group"); + return; + } + + const newNode = effect.createGroup(nodeData); + if (newNode) { + // Rebuild tree with all effects + this._rebuildTree(); + } + } + + private _handleDropEmpty(ev: React.DragEvent): void { + ev.preventDefault(); + ev.stopPropagation(); + + try { + const data = ev.dataTransfer.getData("Effect-editor/create-effect"); + if (data === "effect") { + this._handleCreateEffect(); + } + } catch (e) { + // Ignore errors + } + } + + private _handleDropOnNode(node: TreeNodeInfo, ev: React.DragEvent): void { + ev.preventDefault(); + ev.stopPropagation(); + + if (!node.nodeData || node.nodeData.type !== "group") { + return; + } + + try { + const data = ev.dataTransfer.getData("Effect-editor/create-item"); + if (data === "solid-particle") { + this._handleAddParticleSystemToNode(node, "solid"); + } else if (data === "base-particle") { + this._handleAddParticleSystemToNode(node, "base"); + } else if (data === "group") { + this._handleAddGroupToNode(node); + } + } catch (e) { + // Ignore errors + } + } + + private _addNodeToParent(nodes: TreeNodeInfo[], parentId: string | number, newNode: TreeNodeInfo): TreeNodeInfo[] { + return nodes.map((n) => { + if (n.id === parentId) { + const childNodes = n.childNodes || []; + return { + ...n, + childNodes: [...childNodes, newNode], + hasCaret: true, + isExpanded: true, + }; + } + if (n.childNodes) { + return { + ...n, + childNodes: this._addNodeToParent(n.childNodes, parentId, newNode), + }; + } + return n; + }); + } + + private _handleDeleteNode(node: TreeNodeInfo): void { + const nodeData = node.nodeData; + if (!nodeData) { + return; + } + + // Check if this is an effect root node (uuid matches an effect ID) + const effectId = nodeData.uuid; + if (effectId && this._effects.has(effectId)) { + // Delete entire effect + const effectInfo = this._effects.get(effectId); + if (effectInfo) { + effectInfo.effect.dispose(); + this._effects.delete(effectId); + this._rebuildTree(); + } + } else { + // Delete node from effect hierarchy + const effect = this._findEffectForNode(node); + if (!effect) { + return; + } + + // Find and remove node from effect hierarchy using instance comparison + const removeNodeFromHierarchy = (current: IEffectNode): boolean => { + // Remove from children - use instance comparison primarily + const index = current.children.findIndex((child) => { + // Primary: instance comparison + if (child === nodeData) { + return true; + } + // Fallback: uuid comparison (if both have uuid) + if (child.uuid && nodeData.uuid && child.uuid === nodeData.uuid) { + return true; + } + return false; + }); + + if (index !== -1) { + const removedNode = current.children[index]; + // Recursively dispose all children first + this._disposeNodeRecursive(removedNode); + current.children.splice(index, 1); + return true; + } + + // Recursively search in children + for (const child of current.children) { + if (removeNodeFromHierarchy(child)) { + return true; + } + } + return false; + }; + + if (effect.root) { + removeNodeFromHierarchy(effect.root); + this._rebuildTree(); + } + } + + // Clear selection if deleted node was selected + if (this.state.selectedNodeId === node.id) { + this.setState({ selectedNodeId: null }); + this.props.onNodeSelected?.(null); + } + } + + /** + * Recursively dispose a node and all its children + */ + private _disposeNodeRecursive(node: IEffectNode): void { + // First dispose all children + for (const child of node.children) { + this._disposeNodeRecursive(child); + } + + // Dispose system if it's a particle system + if (node.data) { + node.data.dispose(); + } + // Dispose group if it's a group + if (node.data) { + node.data.dispose(); + } + + // Clear the node ID from our map + this._nodeIdMap.delete(node); + } +} diff --git a/editor/src/editor/windows/effect-editor/index.tsx b/editor/src/editor/windows/effect-editor/index.tsx new file mode 100644 index 000000000..a9fa8adb5 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/index.tsx @@ -0,0 +1,235 @@ +import { ipcRenderer } from "electron"; +import { writeJSON } from "fs-extra"; + +import { toast } from "sonner"; + +import { Component, ReactNode } from "react"; + +import { Toaster } from "../../../ui/shadcn/ui/sonner"; + +import { EffectEditorLayout } from "./layout"; +import { EffectEditorToolbar } from "./toolbar"; +import { UnityImportModal } from "./modals/unity-import-modal"; + +import { projectConfiguration, onProjectConfigurationChangedObservable, IProjectConfiguration } from "../../../project/configuration"; +import { EffectEditorAnimation } from "./animation"; +import { EffectEditorGraph } from "./graph"; +import { EffectEditorPreview } from "./preview"; +import { EffectEditorResources } from "./resources"; +import { convertUnityPrefabToData } from "./converters"; + +export interface IEffectEditorWindowProps { + filePath?: string; + projectConfiguration?: IProjectConfiguration; +} + +export interface IEffectEditorWindowState { + filePath: string | null; + isUnityImportModalOpen: boolean; +} + +export interface IEffectEditor { + layout: EffectEditorLayout | null; + preview: EffectEditorPreview | null; + graph: EffectEditorGraph | null; + animation: EffectEditorAnimation | null; + resources: EffectEditorResources | null; +} +export default class EffectEditorWindow extends Component { + public editor: IEffectEditor = { + layout: null, + preview: null, + graph: null, + animation: null, + resources: null, + }; + + public constructor(props: IEffectEditorWindowProps) { + super(props); + + this.state = { + filePath: props.filePath || null, + isUnityImportModalOpen: false, + }; + } + + public render(): ReactNode { + return ( + <> +
+ + +
+ (this.editor.layout = r)} filePath={this.state.filePath || ""} editor={this.editor} /> +
+
+ + {/* Unity Import Modal */} + this.setState({ isUnityImportModalOpen: false })} + onImport={(contexts, prefabNames) => this.importUnityData(contexts, prefabNames)} + /> + + + + ); + } + + public async componentDidMount(): Promise { + ipcRenderer.on("save", () => this.save()); + ipcRenderer.on("editor:close-window", () => this.close()); + + // Set project configuration if provided + if (this.props.projectConfiguration) { + projectConfiguration.path = this.props.projectConfiguration.path; + projectConfiguration.compressedTexturesEnabled = this.props.projectConfiguration.compressedTexturesEnabled; + onProjectConfigurationChangedObservable.notifyObservers(projectConfiguration); + } + + // Load file if filePath is provided (wait for graph to be ready) + if (this.props.filePath) { + // Wait a bit for graph component to mount + setTimeout(async () => { + if (this.editor.graph) { + await this.editor.graph.loadFromFile(this.props.filePath!); + } + }, 100); + } + } + + public close(): void { + ipcRenderer.send("window:close"); + } + + public async loadFile(filePath: string): Promise { + this.setState({ filePath }); + // TODO: Load file data into editor + } + + public async save(): Promise { + if (!this.state.filePath || !this.editor.graph) { + return; + } + + try { + const fileData = this.editor.graph.serializeToFileFormat(); + await writeJSON(this.state.filePath, fileData, { spaces: "\t", encoding: "utf-8" }); + toast.success("Effect saved"); + ipcRenderer.send("editor:asset-updated", "Effect", fileData); + } catch (error) { + console.error("Failed to save Effect:", error); + toast.error("Failed to save Effect"); + } + } + + public async saveAs(filePath: string): Promise { + this.setState({ filePath }); + await this.save(); + } + + public async importFile(filePath: string): Promise { + try { + if (this.editor.graph) { + await this.editor.graph.loadFromFile(filePath); + toast.success("Effect imported"); + } else { + toast.error("Failed to import Effect: Graph not available"); + } + } catch (error) { + console.error("Failed to import Effect:", error); + toast.error("Failed to import Effect"); + } + } + + public async importQuarksFile(filePath: string): Promise { + try { + if (this.editor.graph) { + await this.editor.graph.loadFromQuarksFile(filePath); + toast.success("Quarks file imported"); + } else { + toast.error("Failed to import Quarks file: Graph not available"); + } + } catch (error) { + console.error("Failed to import Quarks file:", error); + toast.error("Failed to import Quarks file"); + } + } + + /** + * Import Unity prefab data and create Effect + * @param contexts - Array of Unity asset contexts (parsed components + dependencies) + * @param prefabNames - Array of prefab names corresponding to contexts + */ + public async importUnityData(contexts: any[], prefabNames: string[]): Promise { + try { + // Get Scene from preview for model loading + let scene = this.editor.preview?.scene || undefined; + if (!scene) { + // Try waiting a bit for preview to initialize + await new Promise((resolve) => setTimeout(resolve, 100)); + scene = this.editor.preview?.scene || undefined; + } + if (!scene) { + console.warn("Scene not available for model loading, models will be placeholders"); + } + + // Convert each prefab with its dependencies + let successCount = 0; + for (let i = 0; i < contexts.length; i++) { + try { + const context = contexts[i]; + const prefabName = prefabNames[i]; + + // Validate context structure + if (!context) { + console.error("Context is null/undefined:", context); + toast.error(`Invalid prefab data for ${prefabName}`); + continue; + } + + if (!context.prefabComponents) { + console.error("prefabComponents is missing in context:", context); + toast.error(`Missing prefab components for ${prefabName}`); + continue; + } + + if (!(context.prefabComponents instanceof Map)) { + console.error("prefabComponents is not a Map:", typeof context.prefabComponents, context.prefabComponents); + toast.error(`Invalid prefab components type for ${prefabName}`); + continue; + } + + // Convert to IData (pass already parsed components, dependencies, and Scene for model parsing) + const data = await convertUnityPrefabToData(context.prefabComponents, context.dependencies, scene as any); + + // Import into graph + if (this.editor.graph) { + await this.editor.graph.loadFromUnityData(data, prefabName); + successCount++; + } else { + toast.error(`Failed to import ${prefabName}: Graph not available`); + } + } catch (error) { + console.error(`Failed to import prefab ${prefabNames[i]}:`, error); + toast.error(`Failed to import ${prefabNames[i]}`); + } + } + + if (successCount > 0) { + toast.success(`Successfully imported ${successCount} prefab${successCount > 1 ? "s" : ""}`); + } + } catch (error) { + console.error("Failed to import Unity prefabs:", error); + toast.error("Failed to import Unity prefabs"); + throw error; + } + } + + /** + * Open Unity import modal + */ + public openUnityImportModal(): void { + this.setState({ isUnityImportModalOpen: true }); + } +} diff --git a/editor/src/editor/windows/effect-editor/layout.tsx b/editor/src/editor/windows/effect-editor/layout.tsx new file mode 100644 index 000000000..c762da8b8 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/layout.tsx @@ -0,0 +1,306 @@ +import { Component, ReactNode } from "react"; +import { IJsonModel, Layout, Model, TabNode } from "flexlayout-react"; + +import { waitNextAnimationFrame } from "../../../tools/tools"; + +import { EffectEditorPreview } from "./preview"; +import { EffectEditorGraph } from "./graph"; +import { EffectEditorAnimation } from "./animation"; +import { EffectEditorPropertiesTab } from "./properties/tab"; +import { EffectEditorResources } from "./resources"; +import { IEffectEditor } from "."; + +const layoutModel: IJsonModel = { + global: { + tabSetEnableMaximize: true, + tabEnableRename: false, + tabSetMinHeight: 50, + tabSetMinWidth: 240, + enableEdgeDock: false, + }, + layout: { + type: "row", + width: 100, + height: 100, + children: [ + { + type: "row", + weight: 75, + children: [ + { + type: "tabset", + weight: 75, + children: [ + { + type: "tab", + id: "preview", + name: "Preview", + component: "preview", + enableClose: false, + enableRenderOnDemand: false, + }, + ], + }, + { + type: "tabset", + weight: 25, + children: [ + { + type: "tab", + id: "animation", + name: "Animation", + component: "animation", + enableClose: false, + enableRenderOnDemand: false, + }, + ], + }, + ], + }, + { + type: "row", + weight: 25, + children: [ + { + type: "tabset", + weight: 40, + children: [ + { + type: "tab", + id: "graph", + name: "Particles", + component: "graph", + enableClose: false, + enableRenderOnDemand: false, + }, + { + type: "tab", + id: "resources", + name: "Resources", + component: "resources", + enableClose: false, + enableRenderOnDemand: false, + }, + ], + }, + { + type: "tabset", + weight: 60, + children: [ + { + type: "tab", + id: "properties-object", + name: "Object", + component: "properties-object", + enableClose: false, + enableRenderOnDemand: false, + }, + { + type: "tab", + id: "properties-emission", + name: "Emission", + component: "properties-emission", + enableClose: false, + enableRenderOnDemand: false, + }, + { + type: "tab", + id: "properties-renderer", + name: "Renderer", + component: "properties-renderer", + enableClose: false, + enableRenderOnDemand: false, + }, + { + type: "tab", + id: "properties-initialization", + name: "Initialization", + component: "properties-initialization", + enableClose: false, + enableRenderOnDemand: false, + }, + { + type: "tab", + id: "properties-behaviors", + name: "Behaviors", + component: "properties-behaviors", + enableClose: false, + enableRenderOnDemand: false, + }, + ], + }, + ], + }, + ], + }, +}; + +export interface IEffectEditorLayoutProps { + filePath: string | null; + editor: IEffectEditor; +} + +export interface IEffectEditorLayoutState { + selectedNodeId: string | number | null; + resources: any[]; + propertiesKey: number; +} + +export class EffectEditorLayout extends Component { + private _model: Model = Model.fromJson(layoutModel as any); + + private _components: Record = {}; + + public constructor(props: IEffectEditorLayoutProps) { + super(props); + + this.state = { + selectedNodeId: null, + resources: [], + propertiesKey: 0, + }; + } + + public componentDidMount(): void { + this._updateComponents(); + } + + public componentDidUpdate(): void { + this._updateComponents(); + } + + private _handleNodeSelected = (nodeId: string | number | null): void => { + this.setState( + (prevState) => ({ + selectedNodeId: nodeId, + propertiesKey: prevState.propertiesKey + 1, // Increment key to force component recreation + }), + () => { + // Update components immediately after state change + this._updateComponents(); + // Force update layout to ensure flexlayout-react sees the new component + this.forceUpdate(); + } + ); + }; + + private _updateComponents(): void { + this._components = { + preview: ( + (this.props.editor.preview = r!)} + filePath={this.props.filePath} + editor={this.props.editor} + selectedNodeId={this.state.selectedNodeId} + onSceneReady={() => { + // Update graph when scene is ready + if (this.props.editor.graph) { + this.props.editor.graph.forceUpdate(); + } + }} + /> + ), + graph: ( + (this.props.editor.graph = r!)} + filePath={this.props.filePath} + onNodeSelected={this._handleNodeSelected} + editor={this.props.editor} + // onResourcesLoaded={(resources) => { + // this.setState({ resources }); + // }} + /> + ), + resources: (this.props.editor.resources = r!)} resources={this.state.resources} />, + animation: (this.props.editor.animation = r!)} filePath={this.props.filePath} editor={this.props.editor} />, + "properties-object": ( + { + // Update graph node names when name changes + if (this.props.editor.graph) { + this.props.editor.graph.updateNodeNames(); + } + }} + getNodeData={(nodeId) => this.props.editor.graph?.getNodeData(nodeId) || null} + /> + ), + "properties-renderer": ( + this.props.editor.graph?.getNodeData(nodeId) || null} + /> + ), + "properties-emission": ( + this.props.editor.graph?.getNodeData(nodeId) || null} + /> + ), + "properties-initialization": ( + this.props.editor.graph?.getNodeData(nodeId) || null} + /> + ), + "properties-behaviors": ( + this.props.editor.graph?.getNodeData(nodeId) || null} + /> + ), + }; + } + + public render(): ReactNode { + return ( +
+ this._layoutFactory(n)} /> +
+ ); + } + + private _layoutFactory(node: TabNode): ReactNode { + const componentName = node.getComponent(); + if (!componentName) { + return
Error, see console...
; + } + + // Always update components before returning, especially for properties tabs + // This ensures flexlayout-react gets the latest component with updated props + if (componentName.startsWith("properties-")) { + this._updateComponents(); + } + + const component = this._components[componentName]; + if (!component) { + return
Error, see console...
; + } + + node.setEventListener("resize", () => { + waitNextAnimationFrame().then(() => this.props.editor.preview?.resize()); + }); + + return component; + } +} diff --git a/editor/src/editor/windows/effect-editor/modals/unity-import-modal.tsx b/editor/src/editor/windows/effect-editor/modals/unity-import-modal.tsx new file mode 100644 index 000000000..c1e079127 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/modals/unity-import-modal.tsx @@ -0,0 +1,1115 @@ +/** + * Unity Asset Import Modal + * Allows importing Unity Particle System prefabs from ZIP archives + */ + +import { Component, ReactNode } from "react"; +import { Tree, TreeNodeInfo } from "@blueprintjs/core"; +import { Button } from "../../../../ui/shadcn/ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../../../../ui/shadcn/ui/dialog"; +import { Checkbox } from "../../../../ui/shadcn/ui/checkbox"; +import { Upload, FileArchive, Search } from "lucide-react"; +import { HiOutlineFolder } from "react-icons/hi2"; +import { toast } from "sonner"; +import * as yaml from "js-yaml"; +import { Input } from "../../../../ui/shadcn/ui/input"; +import { ScrollArea } from "../../../../ui/shadcn/ui/scroll-area"; + +/** + * Recursively process Unity inline objects like {fileID: 123} + */ +function processUnityInlineObjects(obj: any): any { + if (typeof obj === "string") { + const inlineMatch = obj.match(/^\s*\{([^}]+)\}\s*$/); + if (inlineMatch) { + const pairs = inlineMatch[1].split(","); + const result: any = {}; + for (const pair of pairs) { + const [key, value] = pair.split(":").map((s) => s.trim()); + if (key && value !== undefined) { + if (value === "true") { + result[key] = true; + } else if (value === "false") { + result[key] = false; + } else if (/^-?\d+$/.test(value)) { + result[key] = parseInt(value, 10); + } else if (/^-?\d*\.\d+$/.test(value)) { + result[key] = parseFloat(value); + } else { + result[key] = value.replace(/^["']|["']$/g, ""); + } + } + } + return result; + } + return obj; + } + + if (Array.isArray(obj)) { + return obj.map((item) => processUnityInlineObjects(item)); + } + + if (obj && typeof obj === "object") { + const result: any = {}; + for (const [key, value] of Object.entries(obj)) { + result[key] = processUnityInlineObjects(value); + } + return result; + } + + return obj; +} + +/** + * Parse Unity YAML string into component map (same logic as in converter) + */ +function parseUnityYAML(yamlContent: string): Map { + // Validate input + if (typeof yamlContent !== "string") { + console.error("parseUnityYAML: yamlContent must be a string, got:", typeof yamlContent, yamlContent); + throw new Error("parseUnityYAML: yamlContent must be a string"); + } + + const components = new Map(); + const documents = yamlContent.split(/^---\s+/gm).filter(Boolean); + + for (const doc of documents) { + const match = doc.match(/^!u!(\d+)\s+&(\d+)/); + if (!match) { + continue; + } + + const [, componentType, componentId] = match; + const yamlWithoutTag = doc.replace(/^!u!(\d+)\s+&(\d+)\s*\n/, ""); + + try { + const parsed = yaml.load(yamlWithoutTag, { + schema: yaml.DEFAULT_SCHEMA, + }) as any; + + if (!parsed || typeof parsed !== "object") { + continue; + } + + const processed = processUnityInlineObjects(parsed); + + const component: any = { + id: componentId, + __type: componentType, + ...processed, + }; + + components.set(componentId, component); + + const mainKey = Object.keys(processed).find((k) => k !== "id" && k !== "__type"); + if (mainKey && processed[mainKey] && typeof processed[mainKey] === "object") { + processed[mainKey].__id = componentId; + } + } catch (error) { + console.warn(`Failed to parse Unity YAML component ${componentId}:`, error); + continue; + } + } + + return components; +} + +export interface IUnityPrefabNode { + name: string; + path: string; + type: "prefab" | "folder"; + children?: IUnityPrefabNode[]; +} + +export interface IUnityAssetContext { + prefabComponents: Map; // Already parsed Unity components + dependencies: { + textures: Map; // GUID -> file data + materials: Map; // GUID -> YAML content + models: Map; // GUID -> file data + sounds: Map; // GUID -> file data + meta: Map; // GUID -> meta data + }; +} + +export interface IUnityImportModalProps { + isOpen: boolean; + onClose: () => void; + onImport: (contexts: IUnityAssetContext[], prefabNames: string[]) => void; +} + +export interface IUnityImportModalState { + isDragging: boolean; + zipFile: File | null; + treeNodes: TreeNodeInfo[]; + selectedPrefabs: Set; + isProcessing: boolean; + searchQuery: string; +} + +/** + * Modal for importing Unity prefabs from ZIP archives + */ +export class UnityImportModal extends Component { + private _dropZoneRef: HTMLDivElement | null = null; + + constructor(props: IUnityImportModalProps) { + super(props); + + this.state = { + isDragging: false, + zipFile: null, + treeNodes: [], + selectedPrefabs: new Set(), + isProcessing: false, + searchQuery: "", + }; + } + + public render(): ReactNode { + const { isOpen } = this.props; + const { isDragging, zipFile, treeNodes, selectedPrefabs, isProcessing } = this.state; + + const { searchQuery } = this.state; + const filteredTreeNodes = this._filterTreeNodes(treeNodes, searchQuery); + + return ( + !open && this._handleClose()}> + + + + + Import Unity Assets + + + {/* Search and Controls - only show when tree is loaded */} + {treeNodes.length > 0 && ( +
+
+
+ + + {selectedPrefabs.size} of {this._countPrefabs(treeNodes)} prefab{this._countPrefabs(treeNodes) !== 1 ? "s" : ""} selected + +
+
+ + +
+
+ + {/* Search Input */} +
+ + this.setState({ searchQuery: e.target.value })} + className="pl-9 h-9" + /> +
+
+ )} +
+ +
+ {/* Drop Zone */} + {!zipFile && ( +
(this._dropZoneRef = ref)} + className={` + border-2 border-dashed rounded-lg p-12 + flex flex-col items-center justify-center gap-4 + transition-all duration-200 cursor-pointer + ${isDragging ? "border-primary bg-primary/5 scale-[1.02]" : "border-border hover:border-primary/50 hover:bg-muted/30"} + `} + onDragOver={(e) => this._handleDragOver(e)} + onDragLeave={(e) => this._handleDragLeave(e)} + onDrop={(e) => this._handleDrop(e)} + onClick={() => this._handleClickUpload()} + > +
+ +
+
+

{isDragging ? "Drop ZIP archive here" : "Drag & drop Unity ZIP archive"}

+

or click to browse

+
+

Supported: .zip (Unity Prefab + Meta files)

+
+ )} + + {/* File Info */} + {zipFile && treeNodes.length === 0 && ( +
+
+ +
+
+

{zipFile.name}

+

{this._formatFileSize(zipFile.size)}

+
+ +
+ )} + + {/* Prefab Tree */} + {treeNodes.length > 0 && ( + +
+ +
+
+ )} + + {/* Processing State */} + {isProcessing && ( +
+
+
+
+
+
+

Processing ZIP archive...

+

Please wait

+
+
+
+ )} +
+ + + + + +
+
+ ); + } + + /** + * Build tree structure from ZIP file paths + */ + private _buildTreeFromPaths(prefabPaths: string[]): IUnityPrefabNode[] { + // Build folder tree structure + const folderMap = new Map(); + + // Helper to get or create folder node + const getOrCreateFolder = (folderPath: string, folderName: string): IUnityPrefabNode => { + if (!folderMap.has(folderPath)) { + folderMap.set(folderPath, { + name: folderName, + path: folderPath, + type: "folder", + children: [], + }); + } + return folderMap.get(folderPath)!; + }; + + // Process each prefab path + for (const path of prefabPaths) { + const parts = path.split("/").filter(Boolean); + const fileName = parts.pop() || path; + const folderParts = parts; + + // Build folder hierarchy + let currentPath = ""; + let parentNode: IUnityPrefabNode | null = null; + + for (let i = 0; i < folderParts.length; i++) { + const folderName = folderParts[i]; + currentPath = currentPath ? `${currentPath}/${folderName}` : folderName; + + const folderNode = getOrCreateFolder(currentPath, folderName); + if (parentNode && parentNode.children) { + // Check if already added + if (!parentNode.children.some((c) => c.path === currentPath)) { + parentNode.children.push(folderNode); + } + } + parentNode = folderNode; + } + + // Add prefab to parent folder (or root) + const prefabNode: IUnityPrefabNode = { + name: fileName.replace(".prefab", ""), + path: path, + type: "prefab", + }; + + if (parentNode) { + if (!parentNode.children) { + parentNode.children = []; + } + parentNode.children.push(prefabNode); + } else { + // Root level prefab - add to root + if (!folderMap.has("")) { + folderMap.set("", { + name: "", + path: "", + type: "folder", + children: [], + }); + } + folderMap.get("")!.children!.push(prefabNode); + } + } + + // Get root folders (those without parent in map) + const rootNodes: IUnityPrefabNode[] = []; + for (const [path, node] of folderMap) { + if (path === "" || !folderMap.has(path.split("/").slice(0, -1).join("/"))) { + rootNodes.push(node); + } + } + + // Sort: folders first, then prefabs, alphabetically + const sortNode = (node: IUnityPrefabNode): void => { + if (node.children) { + node.children.sort((a, b) => { + if (a.type === "folder" && b.type === "prefab") { + return -1; + } + if (a.type === "prefab" && b.type === "folder") { + return 1; + } + return a.name.localeCompare(b.name); + }); + node.children.forEach(sortNode); + } + }; + + rootNodes.forEach(sortNode); + rootNodes.sort((a, b) => a.name.localeCompare(b.name)); + + return rootNodes; + } + + /** + * Convert IUnityPrefabNode to TreeNodeInfo + */ + private _convertToTreeNode(node: IUnityPrefabNode): TreeNodeInfo { + const isSelected = this.state.selectedPrefabs.has(node.path); + const childNodes = node.children ? node.children.map((child) => this._convertToTreeNode(child)) : undefined; + + const label = ( +
+ {node.type === "prefab" && ( + this._handleTogglePrefab(node.path, checked as boolean)} onClick={(e) => e.stopPropagation()} /> + )} + {node.name || "Root"} +
+ ); + + return { + id: node.path, + label, + icon: node.type === "folder" ? : undefined, + isExpanded: node.type === "folder", + hasCaret: node.type === "folder" && childNodes && childNodes.length > 0, + childNodes, + isSelected: false, // Tree selection is handled by checkbox + nodeData: node, + }; + } + + /** + * Handle node click + */ + private _handleNodeClick = (nodeData: TreeNodeInfo): void => { + // Toggle checkbox for prefab nodes + if (nodeData.nodeData?.type === "prefab") { + const isSelected = this.state.selectedPrefabs.has(nodeData.nodeData.path); + this._handleTogglePrefab(nodeData.nodeData.path, !isSelected); + } + }; + + /** + * Handle node expand + */ + private _handleNodeExpand = (nodeData: TreeNodeInfo): void => { + // Update tree to reflect expansion + const updateNodes = (nodes: TreeNodeInfo[]): TreeNodeInfo[] => { + return nodes.map((n) => { + if (n.id === nodeData.id) { + return { ...n, isExpanded: true }; + } + if (n.childNodes) { + return { ...n, childNodes: updateNodes(n.childNodes) }; + } + return n; + }); + }; + this.setState({ treeNodes: updateNodes(this.state.treeNodes) }); + }; + + /** + * Handle node collapse + */ + private _handleNodeCollapse = (nodeData: TreeNodeInfo): void => { + // Update tree to reflect collapse + const updateNodes = (nodes: TreeNodeInfo[]): TreeNodeInfo[] => { + return nodes.map((n) => { + if (n.id === nodeData.id) { + return { ...n, isExpanded: false }; + } + if (n.childNodes) { + return { ...n, childNodes: updateNodes(n.childNodes) }; + } + return n; + }); + }; + this.setState({ treeNodes: updateNodes(this.state.treeNodes) }); + }; + + /** + * Handle drag over + */ + private _handleDragOver(e: React.DragEvent): void { + e.preventDefault(); + e.stopPropagation(); + this.setState({ isDragging: true }); + } + + /** + * Handle drag leave + */ + private _handleDragLeave(e: React.DragEvent): void { + e.preventDefault(); + e.stopPropagation(); + if (e.currentTarget === this._dropZoneRef) { + this.setState({ isDragging: false }); + } + } + + /** + * Handle drop + */ + private async _handleDrop(e: React.DragEvent): Promise { + e.preventDefault(); + e.stopPropagation(); + this.setState({ isDragging: false }); + + const files = Array.from(e.dataTransfer.files); + const zipFile = files.find((f) => f.name.endsWith(".zip")); + + if (!zipFile) { + toast.error("Please drop a ZIP archive"); + return; + } + + await this._processZipFile(zipFile); + } + + /** + * Handle click upload + */ + private _handleClickUpload(): void { + const input = document.createElement("input"); + input.type = "file"; + input.accept = ".zip"; + input.onchange = async (e) => { + const file = (e.target as HTMLInputElement).files?.[0]; + if (file) { + await this._processZipFile(file); + } + }; + input.click(); + } + + /** + * Process ZIP file and extract prefab list with folder structure + */ + private async _processZipFile(file: File): Promise { + this.setState({ zipFile: file, isProcessing: true }); + + try { + // Convert File to Buffer for adm-zip (Electron-compatible) + const arrayBuffer = await file.arrayBuffer(); + const buffer = Buffer.from(arrayBuffer); + + // Use adm-zip for Electron (better than jszip for Node.js/Electron) + const AdmZip = (await import("adm-zip")).default; + const zip = new AdmZip(buffer); + + const prefabPaths: string[] = []; + + // Get all entries from ZIP + const zipEntries = zip.getEntries(); + + // Find all .prefab files (ignore .meta files and directories) + for (const entry of zipEntries) { + if (entry.entryName.endsWith(".prefab") && !entry.isDirectory && !entry.entryName.endsWith(".meta")) { + prefabPaths.push(entry.entryName); + } + } + + if (prefabPaths.length === 0) { + toast.error("No .prefab files found in ZIP archive"); + this.setState({ isProcessing: false, zipFile: null }); + return; + } + + // Build tree structure from paths + const treeStructure = this._buildTreeFromPaths(prefabPaths); + + // Convert to TreeNodeInfo + const treeNodes = treeStructure.map((node) => this._convertToTreeNode(node)); + + this.setState({ + treeNodes, + isProcessing: false, + }); + + toast.success(`Found ${prefabPaths.length} prefab${prefabPaths.length > 1 ? "s" : ""} in archive`); + } catch (error) { + console.error("Failed to process ZIP:", error); + toast.error("Failed to process ZIP archive"); + this.setState({ isProcessing: false, zipFile: null }); + } + } + + /** + * Handle toggle prefab selection + */ + private _handleTogglePrefab(path: string, checked: boolean): void { + const selectedPrefabs = new Set(this.state.selectedPrefabs); + if (checked) { + selectedPrefabs.add(path); + } else { + selectedPrefabs.delete(path); + } + + // Update tree nodes to reflect checkbox state + const updateNodes = (nodes: TreeNodeInfo[]): TreeNodeInfo[] => { + return nodes.map((n) => { + if (n.nodeData?.path === path) { + // Update label with new checkbox state + const node = n.nodeData; + const label = ( +
+ {node.type === "prefab" && ( + this._handleTogglePrefab(path, c as boolean)} onClick={(e) => e.stopPropagation()} /> + )} + {node.name || "Root"} +
+ ); + return { ...n, label }; + } + if (n.childNodes) { + return { ...n, childNodes: updateNodes(n.childNodes) }; + } + return n; + }); + }; + + this.setState({ + selectedPrefabs, + treeNodes: updateNodes(this.state.treeNodes), + }); + } + + /** + * Handle select all prefabs + */ + private _handleSelectAll(): void { + const allPaths = this._collectAllPaths(this.state.treeNodes); + this.setState({ selectedPrefabs: new Set(allPaths) }); + + // Update tree to reflect all selected + const updateNodes = (nodes: TreeNodeInfo[]): TreeNodeInfo[] => { + return nodes.map((n) => { + if (n.nodeData?.type === "prefab") { + const node = n.nodeData; + const label = ( +
+ this._handleTogglePrefab(node.path, c as boolean)} onClick={(e) => e.stopPropagation()} /> + {node.name} +
+ ); + return { ...n, label }; + } + if (n.childNodes) { + return { ...n, childNodes: updateNodes(n.childNodes) }; + } + return n; + }); + }; + this.setState({ treeNodes: updateNodes(this.state.treeNodes) }); + } + + /** + * Handle select none + */ + private _handleSelectNone(): void { + this.setState({ selectedPrefabs: new Set() }); + + // Update tree to reflect none selected + const updateNodes = (nodes: TreeNodeInfo[]): TreeNodeInfo[] => { + return nodes.map((n) => { + if (n.nodeData?.type === "prefab") { + const node = n.nodeData; + const label = ( +
+ this._handleTogglePrefab(node.path, c as boolean)} onClick={(e) => e.stopPropagation()} /> + {node.name} +
+ ); + return { ...n, label }; + } + if (n.childNodes) { + return { ...n, childNodes: updateNodes(n.childNodes) }; + } + return n; + }); + }; + this.setState({ treeNodes: updateNodes(this.state.treeNodes) }); + } + + /** + * Collect all prefab paths recursively from tree nodes + */ + private _collectAllPaths(nodes: TreeNodeInfo[]): string[] { + const paths: string[] = []; + for (const node of nodes) { + if (node.nodeData?.type === "prefab") { + paths.push(node.nodeData.path); + } + if (node.childNodes) { + paths.push(...this._collectAllPaths(node.childNodes)); + } + } + return paths; + } + + /** + * Count total prefabs in tree + */ + private _countPrefabs(nodes: TreeNodeInfo[]): number { + let count = 0; + for (const node of nodes) { + if (node.nodeData?.type === "prefab") { + count++; + } + if (node.childNodes) { + count += this._countPrefabs(node.childNodes); + } + } + return count; + } + + /** + * Filter tree nodes by search query + */ + private _filterTreeNodes(nodes: TreeNodeInfo[], query: string): TreeNodeInfo[] { + if (!query.trim()) { + return nodes; + } + + const lowerQuery = query.toLowerCase(); + + const filterNode = (node: TreeNodeInfo): TreeNodeInfo | null => { + const nodeName = node.nodeData?.name?.toLowerCase() || ""; + const matchesQuery = nodeName.includes(lowerQuery); + + // Filter children first + let filteredChildren: TreeNodeInfo[] | undefined; + if (node.childNodes) { + filteredChildren = node.childNodes.map(filterNode).filter((n) => n !== null) as TreeNodeInfo[]; + } + + // If this node matches or has matching children, include it + if (matchesQuery || (filteredChildren && filteredChildren.length > 0)) { + return { + ...node, + childNodes: filteredChildren && filteredChildren.length > 0 ? filteredChildren : undefined, + isExpanded: matchesQuery || (filteredChildren && filteredChildren.length > 0) ? true : node.isExpanded, + }; + } + + return null; + }; + + return nodes.map(filterNode).filter((n) => n !== null) as TreeNodeInfo[]; + } + + /** + * Handle remove file + */ + private _handleRemoveFile(): void { + this.setState({ + zipFile: null, + treeNodes: [], + selectedPrefabs: new Set(), + searchQuery: "", + }); + } + + /** + * Collect all fileID references from parsed YAML object + */ + private _collectFileIDs(obj: any, fileIDs: Set): void { + if (typeof obj !== "object" || obj === null) { + return; + } + + if (Array.isArray(obj)) { + for (const item of obj) { + this._collectFileIDs(item, fileIDs); + } + return; + } + + // Check for Unity fileID references: {fileID: "123"} or {fileID: 123} + if (obj.fileID !== undefined) { + const fileID = String(obj.fileID); + if (fileID !== "0" && fileID !== "4294967295") { + // 0 = null, 4294967295 = missing + fileIDs.add(fileID); + } + } + + // Recursively check all properties + for (const value of Object.values(obj)) { + this._collectFileIDs(value, fileIDs); + } + } + + /** + * Parse Unity .meta file to extract GUID and fileID mappings + */ + private _parseMetaFile(metaContent: string): { guid: string; fileIDToGUID: Map } | null { + try { + const parsed = yaml.load(metaContent) as any; + if (!parsed || !parsed.guid) { + return null; + } + + const fileIDToGUID = new Map(); + const guid = parsed.guid; + + // Unity stores fileID -> GUID mappings in the meta file + // Look for external references in the meta file + if (parsed.ExternalObjects) { + for (const [key, value] of Object.entries(parsed.ExternalObjects)) { + if (value && typeof value === "object" && (value as any).guid) { + fileIDToGUID.set(key, (value as any).guid); + } + } + } + + // Also check for fileIDToRecycleName which maps fileID to GUID + if (parsed.fileIDToRecycleName) { + for (const [fileID, guidOrName] of Object.entries(parsed.fileIDToRecycleName)) { + // Sometimes it's a GUID directly, sometimes it needs lookup + if (typeof guidOrName === "string") { + fileIDToGUID.set(fileID, guidOrName); + } + } + } + + return { + guid, + fileIDToGUID, + }; + } catch (error) { + console.warn("Failed to parse meta file:", error); + return null; + } + } + + /** + * Collect all dependencies for a prefab + */ + private async _collectDependencies(zip: any, prefabPath: string, allEntries: any[]): Promise { + const dependencies: IUnityAssetContext["dependencies"] = { + textures: new Map(), + materials: new Map(), + models: new Map(), + sounds: new Map(), + meta: new Map(), + }; + + // Read prefab YAML + const prefabEntry = zip.getEntry(prefabPath); + if (!prefabEntry) { + return dependencies; + } + + const prefabYaml = prefabEntry.getData().toString("utf8"); + + // Parse Unity YAML to find fileID references + const components = parseUnityYAML(prefabYaml); + + // Build fileID -> GUID mapping from all .meta files FIRST + const fileIDToGUID = new Map(); + const guidToPath = new Map(); + const guidToMeta = new Map(); + + // First pass: collect all meta files and build GUID -> path mapping + for (const entry of allEntries) { + if (entry.entryName.endsWith(".meta") && !entry.isDirectory) { + try { + const metaContent = entry.getData().toString("utf8"); + const meta = this._parseMetaFile(metaContent); + if (meta) { + const assetPath = entry.entryName.replace(/\.meta$/, ""); + guidToPath.set(meta.guid, assetPath); + guidToMeta.set(meta.guid, meta); + + // Map fileID -> GUID from this meta file + for (const [fileID, guid] of meta.fileIDToGUID) { + fileIDToGUID.set(fileID, guid); + } + } + } catch (error) { + console.warn(`Failed to parse meta file ${entry.entryName}:`, error); + } + } + } + + // Collect component IDs (internal references within prefab) + const componentIDs = new Set(components.keys()); + + // Collect all fileID references from components + const allFileIDs = new Set(); + for (const [_id, component] of components) { + this._collectFileIDs(component, allFileIDs); + } + + // Find external fileID references (those that are NOT component IDs but have GUID mappings) + // These are references to external assets (textures, materials, models, etc.) + const externalFileIDs = new Set(); + for (const fileID of allFileIDs) { + // If fileID is not a component ID (internal) and has a GUID mapping, it's an external asset reference + if (!componentIDs.has(fileID) && fileIDToGUID.has(fileID)) { + externalFileIDs.add(fileID); + } + } + + // Also check for direct GUID references in components (m_Texture, m_Material, etc.) + const referencedGUIDs = new Set(); + for (const [_id, component] of components) { + this._collectGUIDReferences(component, referencedGUIDs); + } + + // Collect all assets that are referenced + const collectedGUIDs = new Set(); + for (const fileID of externalFileIDs) { + const guid = fileIDToGUID.get(fileID); + if (guid) { + collectedGUIDs.add(guid); + } + } + for (const guid of referencedGUIDs) { + collectedGUIDs.add(guid); + } + + // Collect dependencies by GUID (ONLY those that are actually referenced) + for (const guid of collectedGUIDs) { + const assetPath = guidToPath.get(guid); + if (!assetPath) { + continue; + } + + const assetEntry = zip.getEntry(assetPath); + if (!assetEntry || assetEntry.isDirectory) { + continue; + } + + const ext = assetPath.split(".").pop()?.toLowerCase(); + const meta = guidToMeta.get(guid); + + if (meta) { + dependencies.meta.set(guid, { path: assetPath, guid }); + + // Categorize by extension + if (ext === "png" || ext === "jpg" || ext === "jpeg" || ext === "tga" || ext === "tiff" || ext === "dds") { + dependencies.textures.set(guid, assetEntry.getData()); + } else if (ext === "mat") { + const matContent = assetEntry.getData().toString("utf8"); + dependencies.materials.set(guid, matContent); + } else if (ext === "fbx" || ext === "obj" || ext === "dae" || ext === "mesh") { + dependencies.models.set(guid, assetEntry.getData()); + } else if (ext === "wav" || ext === "mp3" || ext === "ogg" || ext === "aac") { + dependencies.sounds.set(guid, assetEntry.getData()); + } + } + } + + return dependencies; + } + + /** + * Collect GUID references from Unity component (m_Texture, m_Material, etc.) + */ + private _collectGUIDReferences(obj: any, guids: Set): void { + if (typeof obj !== "object" || obj === null) { + return; + } + + if (Array.isArray(obj)) { + for (const item of obj) { + this._collectGUIDReferences(item, guids); + } + return; + } + + // Check for GUID fields (Unity uses guid field in some references) + if (obj.guid && typeof obj.guid === "string") { + guids.add(obj.guid); + } + + // Check for common Unity asset reference patterns + if (obj.m_Texture && obj.m_Texture.guid) { + guids.add(obj.m_Texture.guid); + } + if (obj.m_Material && obj.m_Material.guid) { + guids.add(obj.m_Material.guid); + } + if (obj.m_Mesh && obj.m_Mesh.guid) { + guids.add(obj.m_Mesh.guid); + } + + // Recursively check all properties + for (const value of Object.values(obj)) { + this._collectGUIDReferences(value, guids); + } + } + + /** + * Handle import - collect all dependencies and pass to converter + */ + private async _handleImport(): Promise { + const { zipFile, selectedPrefabs } = this.state; + if (!zipFile || selectedPrefabs.size === 0) { + toast.error("No prefabs selected"); + return; + } + + this.setState({ isProcessing: true }); + + try { + // Convert File to Buffer + const arrayBuffer = await zipFile.arrayBuffer(); + const buffer = Buffer.from(arrayBuffer); + + // Load ZIP + const AdmZip = (await import("adm-zip")).default; + const zip = new AdmZip(buffer); + const allEntries = zip.getEntries(); + + // Process each selected prefab + const contexts: IUnityAssetContext[] = []; + const prefabNames: string[] = []; + + for (const prefabPath of Array.from(selectedPrefabs)) { + try { + // Read prefab YAML + const prefabEntry = zip.getEntry(prefabPath); + if (!prefabEntry || prefabEntry.isDirectory) { + continue; + } + + const prefabYaml = prefabEntry.getData().toString("utf8"); + + // Validate YAML content + if (typeof prefabYaml !== "string" || !prefabYaml.trim()) { + console.error(`Invalid prefab YAML for ${prefabPath}`); + toast.error(`Invalid prefab file: ${prefabPath.split("/").pop()}`); + continue; + } + + // Parse Unity YAML here (already done in _collectDependencies, but we need it here too) + const prefabComponents = parseUnityYAML(prefabYaml); + + // Validate parsed components + if (!(prefabComponents instanceof Map)) { + console.error(`Failed to parse prefab components for ${prefabPath}, got:`, typeof prefabComponents); + toast.error(`Failed to parse prefab: ${prefabPath.split("/").pop()}`); + continue; + } + + // Collect all dependencies + const dependencies = await this._collectDependencies(zip, prefabPath, allEntries); + + contexts.push({ + prefabComponents, + dependencies, + }); + + prefabNames.push(prefabPath.split("/").pop()?.replace(".prefab", "") || prefabPath); + } catch (error) { + console.error(`Failed to process prefab ${prefabPath}:`, error); + toast.error(`Failed to process ${prefabPath.split("/").pop()}`); + } + } + + if (contexts.length > 0) { + this.props.onImport(contexts, prefabNames); + this._handleClose(); + } else { + toast.error("No valid prefabs to import"); + } + } catch (error) { + console.error("Failed to import Unity prefabs:", error); + toast.error("Failed to import Unity prefabs"); + } finally { + this.setState({ isProcessing: false }); + } + } + + /** + * Handle close + */ + private _handleClose(): void { + this.setState({ + isDragging: false, + zipFile: null, + treeNodes: [], + selectedPrefabs: new Set(), + isProcessing: false, + searchQuery: "", + }); + this.props.onClose(); + } + + /** + * Format file size + */ + private _formatFileSize(bytes: number): string { + if (bytes < 1024) { + return `${bytes} B`; + } + if (bytes < 1024 * 1024) { + return `${(bytes / 1024).toFixed(1)} KB`; + } + return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; + } +} diff --git a/editor/src/editor/windows/effect-editor/preview.tsx b/editor/src/editor/windows/effect-editor/preview.tsx new file mode 100644 index 000000000..29055e602 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/preview.tsx @@ -0,0 +1,347 @@ +import { Component, ReactNode } from "react"; + +import { Scene } from "@babylonjs/core/scene"; +import { Engine } from "@babylonjs/core/Engines/engine"; +import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera"; +import { DirectionalLight } from "@babylonjs/core/Lights/directionalLight"; +import { MeshBuilder } from "@babylonjs/core/Meshes/meshBuilder"; +import { Color3, Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { GridMaterial } from "@babylonjs/materials"; + +import { Button } from "../../../ui/shadcn/ui/button"; +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../../../ui/shadcn/ui/tooltip"; + +import { IoPlay, IoStop, IoRefresh } from "react-icons/io5"; +import type { IEffectEditor } from "."; +import { Effect, type IEffectNode } from "babylonjs-editor-tools"; + +// don't like because it's not a good practice, but it's the only way to load the shaders +import "@babylonjs/core/Particles/particleSystemComponent"; +import "@babylonjs/core/Shaders/particles.vertex"; +import "@babylonjs/core/Shaders/particles.fragment"; +import "@babylonjs/core/Shaders/rgbdDecode.fragment"; + +export interface IEffectEditorPreviewProps { + filePath: string | null; + onSceneReady?: (scene: Scene) => void; + editor?: IEffectEditor; + selectedNodeId?: string | number | null; +} + +export interface IEffectEditorPreviewState { + playing: boolean; +} + +export class EffectEditorPreview extends Component { + public engine: Engine | null = null; + public scene: Scene | null = null; + public camera: ArcRotateCamera | null = null; + + private _canvasRef: HTMLCanvasElement | null = null; + private _renderLoopId: number = -1; + + public constructor(props: IEffectEditorPreviewProps) { + super(props); + + this.state = { + playing: false, + }; + } + + public render(): ReactNode { + return ( +
+ this._onGotCanvasRef(r!)} className="w-full h-full outline-none" /> + + {/* Play/Stop/Restart buttons - only show if a node is selected */} + {this.props.selectedNodeId && ( +
+ + + + + + {this.state.playing ? "Stop" : "Play"} + + + {this.state.playing && ( + + + + + Restart + + )} + +
+ )} +
+ ); + } + + public componentDidMount(): void { + // Canvas ref will be set in render, _onGotCanvasRef will be called automatically + // Sync playing state with effect state + this._syncPlayingState(); + } + + private _syncPlayingState(): void { + if (!this.props.selectedNodeId) { + // No node selected, hide buttons + if (this.state.playing) { + this.setState({ playing: false }); + } + return; + } + + const nodeData = this.props.editor?.graph?.getNodeData(this.props.selectedNodeId); + if (!nodeData) { + if (this.state.playing) { + this.setState({ playing: false }); + } + return; + } + + // Find the effect that contains this node + const effect = this._findEffectForNode(nodeData); + if (!effect) { + if (this.state.playing) { + this.setState({ playing: false }); + } + return; + } + + // Check if this is an effect root node + const isEffectRoot = this._isEffectRootNode(nodeData); + if (isEffectRoot) { + // For effect root, check if entire effect is started + const isStarted = effect.isStarted(); + if (this.state.playing !== isStarted) { + this.setState({ playing: isStarted }); + } + } else { + // For group or system, check if node is started + const isStarted = effect.isNodeStarted(nodeData); + if (this.state.playing !== isStarted) { + this.setState({ playing: isStarted }); + } + } + } + + /** + * Find the effect that contains the given node + */ + private _findEffectForNode(node: IEffectNode): Effect | null { + const effects = this.props.editor?.graph?.getAllEffects() || []; + for (const effect of effects) { + // Check if node is part of this effect's hierarchy + if (this._isNodeInEffect(node, effect)) { + return effect; + } + } + return null; + } + + /** + * Check if node is part of effect's hierarchy + */ + private _isNodeInEffect(node: IEffectNode, effect: Effect): boolean { + if (!effect.root) { + return false; + } + + const findNode = (current: IEffectNode): boolean => { + if (current === node || current.uuid === node.uuid || current.name === node.name) { + return true; + } + for (const child of current.children) { + if (findNode(child)) { + return true; + } + } + return false; + }; + + return findNode(effect.root); + } + + /** + * Check if node is an effect root node + */ + private _isEffectRootNode(node: IEffectNode): boolean { + if (!node.uuid) { + return false; + } + + // Check if this node's UUID matches an effect ID (effect root has effect ID as uuid) + const effects = this.props.editor?.graph?.getAllEffects() || []; + for (const effect of effects) { + if (effect.root && effect.root.uuid === node.uuid) { + return true; + } + } + return false; + } + + public componentWillUnmount(): void { + if (this._renderLoopId !== -1) { + cancelAnimationFrame(this._renderLoopId); + } + + this.scene?.dispose(); + this.engine?.dispose(); + } + + /** + * Resizes the engine. + */ + public resize(): void { + this.engine?.resize(); + } + + private async _onGotCanvasRef(canvas: HTMLCanvasElement | null): Promise { + if (!canvas || this.engine) { + return; + } + + this._canvasRef = canvas; + + this.engine = new Engine(this._canvasRef, true, { + antialias: true, + adaptToDeviceRatio: true, + }); + + this.scene = new Scene(this.engine); + + // Scene settings + this.scene.clearColor = new Color4(0.1, 0.1, 0.1, 1.0); + this.scene.ambientColor = new Color3(1, 1, 1); + + // Camera + this.camera = new ArcRotateCamera("Camera", 0, 0.8, 4, Vector3.Zero(), this.scene); + this.camera.doNotSerialize = true; + this.camera.lowerRadiusLimit = 3; + this.camera.upperRadiusLimit = 10; + this.camera.wheelPrecision = 20; + this.camera.minZ = 0.001; + this.camera.attachControl(canvas, true); + this.camera.useFramingBehavior = true; + this.camera.wheelDeltaPercentage = 0.01; + this.camera.pinchDeltaPercentage = 0.01; + + // Directional light (sun) + const sunLight = new DirectionalLight("sun", new Vector3(-1, -1, -1), this.scene); + sunLight.intensity = 1.0; + sunLight.diffuse = new Color3(1, 1, 1); + sunLight.specular = new Color3(1, 1, 1); + + // Ground with grid material + const groundMaterial = new GridMaterial("groundMaterial", this.scene); + groundMaterial.majorUnitFrequency = 2; + groundMaterial.minorUnitVisibility = 0.1; + groundMaterial.gridRatio = 0.5; + groundMaterial.backFaceCulling = false; + groundMaterial.mainColor = new Color3(1, 1, 1); + groundMaterial.lineColor = new Color3(1.0, 1.0, 1.0); + groundMaterial.opacity = 0.5; + + const ground = MeshBuilder.CreateGround("ground", { width: 100, height: 100 }, this.scene); + ground.material = groundMaterial; + + // Render loop + this.engine.runRenderLoop(() => { + if (this.scene) { + this.scene.render(); + } + }); + + // Handle resize + window.addEventListener("resize", () => { + this.engine?.resize(); + }); + + // Notify parent that scene is ready + this.props.onSceneReady?.(this.scene); + + this.forceUpdate(); + } + + private _handlePlayStop(): void { + if (!this.props.selectedNodeId) { + return; + } + + const nodeData = this.props.editor?.graph?.getNodeData(this.props.selectedNodeId); + if (!nodeData) { + return; + } + + const effect = this._findEffectForNode(nodeData); + if (!effect) { + return; + } + + // Check if this is an effect root node + const isEffectRoot = this._isEffectRootNode(nodeData); + if (isEffectRoot) { + // For effect root, manage entire effect + if (effect.isStarted()) { + effect.stop(); + } else { + effect.start(); + } + } else if (effect.isNodeStarted(nodeData)) { + // For group or system, manage only this node + effect.stopNode(nodeData); + } else { + effect.startNode(nodeData); + } + + this._syncPlayingState(); + } + + private _handleRestart(): void { + if (!this.props.selectedNodeId) { + return; + } + + const nodeData = this.props.editor?.graph?.getNodeData(this.props.selectedNodeId); + if (!nodeData) { + return; + } + + const effect = this._findEffectForNode(nodeData); + if (!effect) { + return; + } + + // Check if this is an effect root node + const isEffectRoot = this._isEffectRootNode(nodeData); + if (isEffectRoot) { + // For effect root, restart entire effect + effect.reset(); + effect.start(); + } else { + // For group or system, restart only this node + effect.resetNode(nodeData); + effect.startNode(nodeData); + } + + this.setState({ playing: true }); + } + + public componentDidUpdate(prevProps: IEffectEditorPreviewProps): void { + // Sync playing state when selected node changes or when props change + if (prevProps.selectedNodeId !== this.props.selectedNodeId) { + this._syncPlayingState(); + } else { + // Update playing state based on actual node state + this._syncPlayingState(); + } + } +} diff --git a/editor/src/editor/windows/effect-editor/properties/behaviors.tsx b/editor/src/editor/windows/effect-editor/properties/behaviors.tsx new file mode 100644 index 000000000..bfe10c176 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/properties/behaviors.tsx @@ -0,0 +1,555 @@ +import { ReactNode } from "react"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; + +import { EditorInspectorNumberField } from "../../../layout/inspector/fields/number"; +import { EditorInspectorVectorField } from "../../../layout/inspector/fields/vector"; +import { EditorInspectorColorField } from "../../../layout/inspector/fields/color"; +import { EditorInspectorSwitchField } from "../../../layout/inspector/fields/switch"; +import { EditorInspectorStringField } from "../../../layout/inspector/fields/string"; +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; +import { EditorInspectorSectionField } from "../../../layout/inspector/fields/section"; + +import { Button } from "../../../../ui/shadcn/ui/button"; +import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../../../ui/shadcn/ui/dropdown-menu"; +import { HiOutlineTrash } from "react-icons/hi2"; +import { IoAddSharp } from "react-icons/io5"; + +import { type IEffectNode, EffectParticleSystem, EffectSolidParticleSystem } from "babylonjs-editor-tools"; +import { FunctionEditor, ColorFunctionEditor } from "../editors"; + +// Types +export type FunctionType = "ConstantValue" | "IntervalValue" | "PiecewiseBezier" | "Vector3Function"; +export type ColorFunctionType = "ConstantColor" | "ColorRange" | "Gradient" | "RandomColor" | "RandomColorBetweenGradient"; + +export interface IBehaviorProperty { + name: string; + type: "vector3" | "number" | "color" | "range" | "boolean" | "string" | "function" | "enum" | "colorFunction"; + label: string; + default?: any; + enumItems?: Array<{ text: string; value: any }>; + functionTypes?: FunctionType[]; + colorFunctionTypes?: ColorFunctionType[]; +} + +export interface IBehaviorDefinition { + type: string; + label: string; + properties: IBehaviorProperty[]; +} + +// Behavior Registry +export const BehaviorRegistry: { [key: string]: IBehaviorDefinition } = { + ApplyForce: { + type: "ApplyForce", + label: "Apply Force", + properties: [ + { name: "direction", type: "vector3", label: "Direction", default: { x: 0, y: 1, z: 0 } }, + { + name: "magnitude", + type: "function", + label: "Magnitude", + default: null, + functionTypes: ["ConstantValue", "IntervalValue"], + }, + ], + }, + Noise: { + type: "Noise", + label: "Noise", + properties: [ + { + name: "frequency", + type: "function", + label: "Frequency", + default: 1.0, + functionTypes: ["ConstantValue", "IntervalValue"], + }, + { + name: "power", + type: "function", + label: "Power", + default: 1.0, + functionTypes: ["ConstantValue", "IntervalValue"], + }, + { + name: "positionAmount", + type: "function", + label: "Position Amount", + default: 1.0, + functionTypes: ["ConstantValue", "IntervalValue"], + }, + { + name: "rotationAmount", + type: "function", + label: "Rotation Amount", + default: 0.0, + functionTypes: ["ConstantValue", "IntervalValue"], + }, + ], + }, + TurbulenceField: { + type: "TurbulenceField", + label: "Turbulence Field", + properties: [ + { name: "scale", type: "vector3", label: "Scale", default: { x: 1, y: 1, z: 1 } }, + { name: "octaves", type: "number", label: "Octaves", default: 1 }, + { name: "velocityMultiplier", type: "vector3", label: "Velocity Multiplier", default: { x: 1, y: 1, z: 1 } }, + { name: "timeScale", type: "vector3", label: "Time Scale", default: { x: 1, y: 1, z: 1 } }, + ], + }, + GravityForce: { + type: "GravityForce", + label: "Gravity Force", + properties: [ + { name: "center", type: "vector3", label: "Center", default: { x: 0, y: 0, z: 0 } }, + { name: "magnitude", type: "number", label: "Magnitude", default: 1.0 }, + ], + }, + ColorOverLife: { + type: "ColorOverLife", + label: "Color Over Life", + properties: [ + { + name: "color", + type: "colorFunction", + label: "Color", + default: null, + colorFunctionTypes: ["ConstantColor", "ColorRange", "Gradient", "RandomColorBetweenGradient"], + }, + ], + }, + RotationOverLife: { + type: "RotationOverLife", + label: "Rotation Over Life", + properties: [ + { + name: "angularVelocity", + type: "function", + label: "Angular Velocity", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + ], + }, + Rotation3DOverLife: { + type: "Rotation3DOverLife", + label: "Rotation 3D Over Life", + properties: [ + { + name: "angularVelocity", + type: "function", + label: "Angular Velocity", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + ], + }, + SizeOverLife: { + type: "SizeOverLife", + label: "Size Over Life", + properties: [ + { + name: "size", + type: "function", + label: "Size", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier", "Vector3Function"], + }, + ], + }, + ColorBySpeed: { + type: "ColorBySpeed", + label: "Color By Speed", + properties: [ + { + name: "color", + type: "colorFunction", + label: "Color", + default: null, + colorFunctionTypes: ["ConstantColor", "ColorRange", "Gradient", "RandomColorBetweenGradient"], + }, + { name: "speedRange", type: "range", label: "Speed Range", default: { min: 0, max: 10 } }, + ], + }, + RotationBySpeed: { + type: "RotationBySpeed", + label: "Rotation By Speed", + properties: [ + { + name: "angularVelocity", + type: "function", + label: "Angular Velocity", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + { name: "speedRange", type: "range", label: "Speed Range", default: { min: 0, max: 10 } }, + ], + }, + SizeBySpeed: { + type: "SizeBySpeed", + label: "Size By Speed", + properties: [ + { + name: "size", + type: "function", + label: "Size", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier", "Vector3Function"], + }, + { name: "speedRange", type: "range", label: "Speed Range", default: { min: 0, max: 10 } }, + ], + }, + SpeedOverLife: { + type: "SpeedOverLife", + label: "Speed Over Life", + properties: [ + { + name: "speed", + type: "function", + label: "Speed", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + ], + }, + FrameOverLife: { + type: "FrameOverLife", + label: "Frame Over Life", + properties: [ + { + name: "frame", + type: "function", + label: "Frame", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + ], + }, + ForceOverLife: { + type: "ForceOverLife", + label: "Force Over Life", + properties: [ + { + name: "x", + type: "function", + label: "X", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + { + name: "y", + type: "function", + label: "Y", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + { + name: "z", + type: "function", + label: "Z", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + ], + }, + OrbitOverLife: { + type: "OrbitOverLife", + label: "Orbit Over Life", + properties: [ + { + name: "orbitSpeed", + type: "function", + label: "Orbit Speed", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + { name: "axis", type: "vector3", label: "Axis", default: { x: 0, y: 1, z: 0 } }, + ], + }, + WidthOverLength: { + type: "WidthOverLength", + label: "Width Over Length", + properties: [ + { + name: "width", + type: "function", + label: "Width", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + ], + }, + ChangeEmitDirection: { + type: "ChangeEmitDirection", + label: "Change Emit Direction", + properties: [ + { + name: "angle", + type: "function", + label: "Angle", + default: 0.0, + functionTypes: ["ConstantValue", "IntervalValue"], + }, + ], + }, + EmitSubParticleSystem: { + type: "EmitSubParticleSystem", + label: "Emit Sub Particle System", + properties: [ + { name: "subParticleSystem", type: "string", label: "Sub Particle System", default: "" }, + { name: "useVelocityAsBasis", type: "boolean", label: "Use Velocity As Basis", default: false }, + { + name: "mode", + type: "enum", + label: "Mode", + default: 0, + enumItems: [ + { text: "Death", value: 0 }, + { text: "Birth", value: 1 }, + { text: "Frame", value: 2 }, + ], + }, + { name: "emitProbability", type: "number", label: "Emit Probability", default: 1.0 }, + ], + }, + LimitSpeedOverLife: { + type: "LimitSpeedOverLife", + label: "Limit Speed Over Life", + properties: [ + { + name: "speed", + type: "function", + label: "Speed", + default: null, + functionTypes: ["ConstantValue", "IntervalValue", "PiecewiseBezier"], + }, + { name: "dampen", type: "number", label: "Dampen", default: 0.0 }, + ], + }, +}; + +// Utility functions +export function getBehaviorDefinition(type: string): IBehaviorDefinition | undefined { + return BehaviorRegistry[type]; +} + +export function createDefaultBehaviorData(type: string): any { + const definition = BehaviorRegistry[type]; + if (!definition) { + return { type }; + } + + const data: any = { type }; + for (const prop of definition.properties) { + if (prop.type === "function") { + data[prop.name] = { + functionType: prop.functionTypes?.[0] || "ConstantValue", + data: {}, + }; + if (data[prop.name].functionType === "ConstantValue") { + data[prop.name].data.value = prop.default !== undefined ? prop.default : 1.0; + } else if (data[prop.name].functionType === "IntervalValue") { + data[prop.name].data.min = 0; + data[prop.name].data.max = 1; + } + } else if (prop.type === "colorFunction") { + data[prop.name] = { + colorFunctionType: prop.colorFunctionTypes?.[0] || "ConstantColor", + data: {}, + }; + } else if (prop.default !== undefined) { + if (prop.type === "vector3") { + data[prop.name] = { x: prop.default.x, y: prop.default.y, z: prop.default.z }; + } else if (prop.type === "range") { + data[prop.name] = { min: prop.default.min, max: prop.default.max }; + } else { + data[prop.name] = prop.default; + } + } + } + return data; +} + +// Helper function to render a single property +function renderProperty(prop: IBehaviorProperty, behavior: any, onChange: () => void): ReactNode { + switch (prop.type) { + case "vector3": + if (!behavior[prop.name]) { + const defaultVal = prop.default || { x: 0, y: 0, z: 0 }; + behavior[prop.name] = new Vector3(defaultVal.x, defaultVal.y, defaultVal.z); + } else if (!(behavior[prop.name] instanceof Vector3)) { + const obj = behavior[prop.name]; + behavior[prop.name] = new Vector3(obj.x || 0, obj.y || 0, obj.z || 0); + } + return ; + + case "number": + if (behavior[prop.name] === undefined) { + behavior[prop.name] = prop.default !== undefined ? prop.default : 0; + } + return ; + + case "color": + if (!behavior[prop.name]) { + behavior[prop.name] = prop.default ? new Color4(prop.default.r, prop.default.g, prop.default.b, prop.default.a) : new Color4(1, 1, 1, 1); + } + return ; + + case "range": + if (!behavior[prop.name]) { + behavior[prop.name] = prop.default ? { ...prop.default } : { min: 0, max: 1 }; + } + return ( + +
{prop.label}
+
+ + +
+
+ ); + + case "boolean": + if (behavior[prop.name] === undefined) { + behavior[prop.name] = prop.default !== undefined ? prop.default : false; + } + return ; + + case "string": + if (behavior[prop.name] === undefined) { + behavior[prop.name] = prop.default !== undefined ? prop.default : ""; + } + return ; + + case "enum": + if (behavior[prop.name] === undefined) { + behavior[prop.name] = prop.default !== undefined ? prop.default : (prop.enumItems?.[0]?.value ?? 0); + } + if (!prop.enumItems || prop.enumItems.length === 0) { + return null; + } + return ; + + case "colorFunction": + // All color functions are now stored uniformly in behavior[prop.name] + if (!behavior[prop.name]) { + behavior[prop.name] = { + colorFunctionType: prop.colorFunctionTypes?.[0] || "ConstantColor", + data: {}, + }; + } + return ; + + case "function": + if (!behavior[prop.name]) { + behavior[prop.name] = { + functionType: prop.functionTypes?.[0] || "ConstantValue", + data: {}, + }; + } + return ; + + default: + return null; + } +} + +// Component to render behavior properties +interface IBehaviorPropertiesProps { + behavior: any; + onChange: () => void; +} + +function BehaviorProperties(props: IBehaviorPropertiesProps): ReactNode { + const { behavior, onChange } = props; + const definition = getBehaviorDefinition(behavior.type); + + if (!definition) { + return null; + } + + return <>{definition.properties.map((prop) => renderProperty(prop, behavior, onChange))}; +} + +// Main component +export interface IEffectEditorBehaviorsPropertiesProps { + nodeData: IEffectNode; + onChange: () => void; +} + +export function EffectEditorBehaviorsProperties(props: IEffectEditorBehaviorsPropertiesProps): ReactNode { + const { nodeData, onChange } = props; + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + const behaviorConfigs: any[] = system instanceof EffectParticleSystem || system instanceof EffectSolidParticleSystem ? system.behaviorConfigs || [] : []; + + const handleAddBehavior = (behaviorType: string): void => { + const newBehavior = createDefaultBehaviorData(behaviorType); + newBehavior.id = `behavior-${Date.now()}-${Math.random()}`; + behaviorConfigs.push(newBehavior); + onChange(); + }; + + const handleRemoveBehavior = (index: number): void => { + behaviorConfigs.splice(index, 1); + onChange(); + }; + + const handleBehaviorChange = (): void => { + onChange(); + }; + + return ( + <> + {behaviorConfigs.length === 0 &&
No behaviors. Click "Add Behavior" to add one.
} + {behaviorConfigs.map((behavior, index) => { + const definition = getBehaviorDefinition(behavior.type); + const title = definition?.label || behavior.type || `Behavior ${index + 1}`; + + return ( + + {title} + +
+ } + > + + + ); + })} + + + + + + + {Object.values(BehaviorRegistry).map((definition) => ( + handleAddBehavior(definition.type)}> + {definition.label} + + ))} + + + + ); +} diff --git a/editor/src/editor/windows/effect-editor/properties/emission.tsx b/editor/src/editor/windows/effect-editor/properties/emission.tsx new file mode 100644 index 000000000..97c861ee1 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/properties/emission.tsx @@ -0,0 +1,504 @@ +import { ReactNode } from "react"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; + +import { EditorInspectorNumberField } from "../../../layout/inspector/fields/number"; +import { EditorInspectorVectorField } from "../../../layout/inspector/fields/vector"; +import { EditorInspectorSwitchField } from "../../../layout/inspector/fields/switch"; +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; +import { EditorInspectorSectionField } from "../../../layout/inspector/fields/section"; + +import { + type IEffectNode, + type IEmissionBurst, + EffectSolidParticleSystem, + EffectParticleSystem, + SolidSphereParticleEmitter, + SolidConeParticleEmitter, + SolidBoxParticleEmitter, + SolidHemisphericParticleEmitter, + SolidCylinderParticleEmitter, + Value, +} from "babylonjs-editor-tools"; +import { EffectValueEditor } from "../editors/value"; + +export interface IEffectEditorEmissionPropertiesProps { + nodeData: IEffectNode; + onChange: () => void; +} + +/** + * Renders emitter shape properties for SolidParticleSystem + */ +function renderSolidParticleSystemEmitter(system: EffectSolidParticleSystem, onChange: () => void): ReactNode { + const emitter = system.particleEmitterType; + const emitterType = emitter ? emitter.constructor.name : "Point"; + + const emitterTypeMap: Record = { + SolidPointParticleEmitter: "point", + SolidSphereParticleEmitter: "sphere", + SolidConeParticleEmitter: "cone", + SolidBoxParticleEmitter: "box", + SolidHemisphericParticleEmitter: "hemisphere", + SolidCylinderParticleEmitter: "cylinder", + }; + + const currentType = emitterTypeMap[emitterType] || "point"; + const emitterTypes = [ + { text: "Point", value: "point" }, + { text: "Box", value: "box" }, + { text: "Sphere", value: "sphere" }, + { text: "Cone", value: "cone" }, + { text: "Hemisphere", value: "hemisphere" }, + { text: "Cylinder", value: "cylinder" }, + ]; + + // Helper to get current values from various emitter types + const getRadius = (): number => { + if (emitter instanceof SolidSphereParticleEmitter || emitter instanceof SolidConeParticleEmitter) { + return emitter.radius; + } + if (emitter instanceof SolidHemisphericParticleEmitter || emitter instanceof SolidCylinderParticleEmitter) { + return emitter.radius; + } + return 1; + }; + + const getRadiusRange = (): number => { + if (emitter instanceof SolidHemisphericParticleEmitter || emitter instanceof SolidCylinderParticleEmitter) { + return emitter.radiusRange; + } + return 1; + }; + + const getDirectionRandomizer = (): number => { + if (emitter instanceof SolidHemisphericParticleEmitter || emitter instanceof SolidCylinderParticleEmitter) { + return emitter.directionRandomizer; + } + return 0; + }; + + return ( + <> + ({ text: t.text, value: t.value }))} + onChange={(value) => { + const currentRadius = getRadius(); + const currentArc = emitter instanceof SolidSphereParticleEmitter || emitter instanceof SolidConeParticleEmitter ? emitter.arc : Math.PI * 2; + const currentThickness = emitter instanceof SolidSphereParticleEmitter || emitter instanceof SolidConeParticleEmitter ? emitter.thickness : 1; + const currentAngle = emitter instanceof SolidConeParticleEmitter ? emitter.angle : Math.PI / 6; + const currentHeight = emitter instanceof SolidCylinderParticleEmitter ? emitter.height : 1; + const currentRadiusRange = getRadiusRange(); + const currentDirRandomizer = getDirectionRandomizer(); + + switch (value) { + case "point": + system.createPointEmitter(); + break; + case "box": + system.createBoxEmitter(); + break; + case "sphere": + system.createSphereEmitter(currentRadius, currentArc, currentThickness); + break; + case "cone": + system.createConeEmitter(currentRadius, currentArc, currentThickness, currentAngle); + break; + case "hemisphere": + system.createHemisphericEmitter(currentRadius, currentRadiusRange, currentDirRandomizer); + break; + case "cylinder": + system.createCylinderEmitter(currentRadius, currentHeight, currentRadiusRange, currentDirRandomizer); + break; + } + onChange(); + }} + /> + + {emitter instanceof SolidSphereParticleEmitter && ( + <> + + + + + )} + + {emitter instanceof SolidConeParticleEmitter && ( + <> + + + + + + )} + + {emitter instanceof SolidBoxParticleEmitter && ( + <> + +
Direction
+ + +
+ +
Emit Box
+ + +
+ + )} + + {emitter instanceof SolidHemisphericParticleEmitter && ( + <> + + + + + )} + + {emitter instanceof SolidCylinderParticleEmitter && ( + <> + + + + + + )} + + ); +} + +/** + * Renders emitter shape properties for ParticleSystem + */ +function renderParticleSystemEmitter(system: EffectParticleSystem, onChange: () => void): ReactNode { + const emitter = system.particleEmitterType; + if (!emitter) { + return
No emitter found.
; + } + + const emitterType = emitter.getClassName(); + const emitterTypeMap: Record = { + PointParticleEmitter: "point", + BoxParticleEmitter: "box", + SphereParticleEmitter: "sphere", + SphereDirectedParticleEmitter: "sphere", + ConeParticleEmitter: "cone", + ConeDirectedParticleEmitter: "cone", + HemisphericParticleEmitter: "hemisphere", + CylinderParticleEmitter: "cylinder", + CylinderDirectedParticleEmitter: "cylinder", + }; + + const currentType = emitterTypeMap[emitterType] || "point"; + const emitterTypes = [ + { text: "Point", value: "point" }, + { text: "Box", value: "box" }, + { text: "Sphere", value: "sphere" }, + { text: "Cone", value: "cone" }, + { text: "Hemisphere", value: "hemisphere" }, + { text: "Cylinder", value: "cylinder" }, + ]; + + return ( + <> + ({ text: t.text, value: t.value }))} + onChange={(value) => { + const currentRadius = "radius" in emitter ? (emitter as any).radius : 1; + const currentAngle = "angle" in emitter ? (emitter as any).angle : Math.PI / 6; + const currentHeight = "height" in emitter ? (emitter as any).height : 1; + const currentDirection1 = "direction1" in emitter ? (emitter as any).direction1?.clone() : Vector3.Zero(); + const currentDirection2 = "direction2" in emitter ? (emitter as any).direction2?.clone() : Vector3.Zero(); + const currentMinEmitBox = "minEmitBox" in emitter ? (emitter as any).minEmitBox?.clone() : new Vector3(-0.5, -0.5, -0.5); + const currentMaxEmitBox = "maxEmitBox" in emitter ? (emitter as any).maxEmitBox?.clone() : new Vector3(0.5, 0.5, 0.5); + + switch (value) { + case "point": + system.createPointEmitter(currentDirection1, currentDirection2); + break; + case "box": + system.createBoxEmitter(currentDirection1, currentDirection2, currentMinEmitBox, currentMaxEmitBox); + break; + case "sphere": + system.createSphereEmitter(currentRadius); + break; + case "cone": + system.createConeEmitter(currentRadius, currentAngle); + break; + case "hemisphere": + system.createHemisphericEmitter(currentRadius); + break; + case "cylinder": + system.createCylinderEmitter(currentRadius, currentHeight); + break; + } + onChange(); + }} + /> + + {emitterType === "BoxParticleEmitter" && ( + <> + +
Direction
+ + +
+ +
Emit Box
+ + +
+ + )} + + {(emitterType === "ConeParticleEmitter" || emitterType === "ConeDirectedParticleEmitter") && ( + <> + + + + + + + {emitterType === "ConeDirectedParticleEmitter" && ( + +
Direction
+ + +
+ )} + + )} + + {(emitterType === "CylinderParticleEmitter" || emitterType === "CylinderDirectedParticleEmitter") && ( + <> + + + + + + {emitterType === "CylinderDirectedParticleEmitter" && ( + +
Direction
+ + +
+ )} + + )} + + {(emitterType === "SphereParticleEmitter" || emitterType === "SphereDirectedParticleEmitter") && ( + <> + + + + + {emitterType === "SphereDirectedParticleEmitter" && ( + +
Direction
+ + +
+ )} + + )} + + {emitterType === "PointParticleEmitter" && ( + +
Direction
+ + +
+ )} + + {emitterType === "HemisphericParticleEmitter" && ( + <> + + + + + )} + + ); +} + +/** + * Renders emitter shape properties + */ +function renderEmitterShape(nodeData: IEffectNode, onChange: () => void): ReactNode { + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + + if (system instanceof EffectSolidParticleSystem) { + return renderSolidParticleSystemEmitter(system, onChange); + } + + if (system instanceof EffectParticleSystem) { + return renderParticleSystemEmitter(system, onChange); + } + + return null; +} + +/** + * Renders emission bursts + */ +function renderBursts(system: EffectParticleSystem | EffectSolidParticleSystem, onChange: () => void): ReactNode { + const bursts: (IEmissionBurst & { cycle?: number; interval?: number; probability?: number })[] = Array.isArray((system as any).emissionBursts) + ? (system as any).emissionBursts + : []; + + const addBurst = () => { + bursts.push({ + time: 0, + count: 1, + cycle: 1, + interval: 0, + probability: 1, + }); + (system as any).emissionBursts = bursts; + onChange(); + }; + + const removeBurst = (index: number) => { + bursts.splice(index, 1); + (system as any).emissionBursts = bursts; + onChange(); + }; + + return ( + +
+ {bursts.map((burst, idx) => ( +
+
+
Burst #{idx + 1}
+ +
+
+ { + burst.time = val as Value; + onChange(); + }} + /> + { + burst.count = val as Value; + onChange(); + }} + /> + + + +
+
+ ))} + +
+
+ ); +} + +/** + * Renders emission parameters (looping, duration, emit over time/distance, bursts) + */ +function renderEmissionParameters(nodeData: IEffectNode, onChange: () => void): ReactNode { + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + + // Proxy for looping (targetStopDuration === 0 means looping) + const loopingProxy = { + get isLooping() { + return (system as any).targetStopDuration === 0; + }, + set isLooping(value: boolean) { + if (value) { + (system as any).targetStopDuration = 0; + } else if ((system as any).targetStopDuration === 0) { + (system as any).targetStopDuration = 5; // Default duration + } + }, + }; + + // Proxy for prewarm (preWarmCycles > 0 means prewarm enabled) + const prewarmProxy = { + get prewarm() { + return (system as any).preWarmCycles > 0; + }, + set prewarm(value: boolean) { + if (value && (system as any).preWarmCycles === 0) { + (system as any).preWarmCycles = Math.ceil((system as any).targetStopDuration || 5) * 60; + (system as any).preWarmStepOffset = 1 / 60; + } else if (!value) { + (system as any).preWarmCycles = 0; + } + }, + }; + + return ( + <> + + + + + {/* Emit Rate (native Babylon.js property) */} + + + {/* Emit Over Distance - only for SolidParticleSystem */} + {system instanceof EffectSolidParticleSystem && ( + + { + (system as EffectSolidParticleSystem).emissionOverDistance = val as Value; + onChange(); + }} + /> + + )} + + {renderBursts(system as any, onChange)} + + ); +} + +/** + * Combined emission properties component + * Includes both emitter shape and emission parameters + */ +export function EffectEditorEmissionProperties(props: IEffectEditorEmissionPropertiesProps): ReactNode { + const { nodeData, onChange } = props; + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + return ( + <> + {renderEmitterShape(nodeData, onChange)} + + {renderEmissionParameters(nodeData, onChange)} + + ); +} diff --git a/editor/src/editor/windows/effect-editor/properties/initialization.tsx b/editor/src/editor/windows/effect-editor/properties/initialization.tsx new file mode 100644 index 000000000..2948f8d6b --- /dev/null +++ b/editor/src/editor/windows/effect-editor/properties/initialization.tsx @@ -0,0 +1,221 @@ +import { ReactNode } from "react"; + +import { EditorInspectorBlockField } from "../../../layout/inspector/fields/block"; + +import { type IEffectNode, parseConstantValue, parseIntervalValue, parseConstantColor, Value, Color, Rotation } from "babylonjs-editor-tools"; +import { EffectValueEditor, type IVec3Function } from "../editors/value"; +import { EffectColorEditor } from "../editors/color"; + +export interface IEffectEditorParticleInitializationPropertiesProps { + nodeData: IEffectNode; + onChange?: () => void; +} + +export function EffectEditorParticleInitializationProperties(props: IEffectEditorParticleInitializationPropertiesProps): ReactNode { + const { nodeData } = props; + const onChange = props.onChange || (() => {}); + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + + // Helper to get/set startLife - both systems use native minLifeTime/maxLifeTime + const getStartLife = (): Value | undefined => { + // Both systems have native minLifeTime/maxLifeTime properties + return { type: "IntervalValue", min: (system as any).minLifeTime, max: (system as any).maxLifeTime }; + }; + + const setStartLife = (value: Value): void => { + const interval = parseIntervalValue(value); + (system as any).minLifeTime = interval.min; + (system as any).maxLifeTime = interval.max; + onChange(); + }; + + // Helper to get/set startSize - both systems use native minSize/maxSize + const getStartSize = (): Value | IVec3Function | undefined => { + // Both systems have native minSize/maxSize properties + return { type: "IntervalValue", min: (system as any).minSize, max: (system as any).maxSize }; + }; + + const setStartSize = (value: Value | IVec3Function): void => { + if (typeof value === "object" && "type" in value && value.type === "Vec3Function") { + // For Vec3Function, use average of x, y, z + const x = parseConstantValue(value.x); + const y = parseConstantValue(value.y); + const z = parseConstantValue(value.z); + const avg = (x + y + z) / 3; + (system as any).minSize = avg; + (system as any).maxSize = avg; + } else { + const interval = parseIntervalValue(value as Value); + (system as any).minSize = interval.min; + (system as any).maxSize = interval.max; + } + onChange(); + }; + + // Helper to get/set startSpeed - both systems use native minEmitPower/maxEmitPower + const getStartSpeed = (): Value | undefined => { + // Both systems have native minEmitPower/maxEmitPower properties + return { type: "IntervalValue", min: (system as any).minEmitPower, max: (system as any).maxEmitPower }; + }; + + const setStartSpeed = (value: Value): void => { + const interval = parseIntervalValue(value); + (system as any).minEmitPower = interval.min; + (system as any).maxEmitPower = interval.max; + onChange(); + }; + + // Helper to get/set startColor - both systems use native color1 + const getStartColor = (): Color | undefined => { + // Both systems have native color1 property + if ((system as any).color1) { + return { type: "ConstantColor", value: [(system as any).color1.r, (system as any).color1.g, (system as any).color1.b, (system as any).color1.a] }; + } + return undefined; + }; + + const setStartColor = (value: Color): void => { + const color = parseConstantColor(value); + (system as any).color1 = color; + onChange(); + }; + + // Helper to get/set startRotation - both systems use native minInitialRotation/maxInitialRotation + const getStartRotation = (): Rotation | undefined => { + // Both systems have native minInitialRotation/maxInitialRotation properties + return { + type: "Euler", + angleZ: { type: "IntervalValue", min: (system as any).minInitialRotation, max: (system as any).maxInitialRotation }, + order: "xyz", + }; + }; + + const setStartRotation = (value: Rotation): void => { + // Extract angleZ from rotation + if (typeof value === "object" && "type" in value && value.type === "Euler" && value.angleZ) { + const interval = parseIntervalValue(value.angleZ); + (system as any).minInitialRotation = interval.min; + (system as any).maxInitialRotation = interval.max; + } else if ( + typeof value === "number" || + (typeof value === "object" && "type" in value && (value.type === "ConstantValue" || value.type === "IntervalValue" || value.type === "PiecewiseBezier")) + ) { + const interval = parseIntervalValue(value as Value); + (system as any).minInitialRotation = interval.min; + (system as any).maxInitialRotation = interval.max; + } + onChange(); + }; + + // Helper to get/set angular speed - both systems use native minAngularSpeed/maxAngularSpeed + const getAngularSpeed = (): Value | undefined => { + return { type: "IntervalValue", min: (system as any).minAngularSpeed, max: (system as any).maxAngularSpeed }; + }; + + const setAngularSpeed = (value: Value): void => { + const interval = parseIntervalValue(value); + (system as any).minAngularSpeed = interval.min; + (system as any).maxAngularSpeed = interval.max; + onChange(); + }; + + // Helper to get/set scale X - both systems use native minScaleX/maxScaleX + const getScaleX = (): Value | undefined => { + return { type: "IntervalValue", min: (system as any).minScaleX, max: (system as any).maxScaleX }; + }; + + const setScaleX = (value: Value): void => { + const interval = parseIntervalValue(value); + (system as any).minScaleX = interval.min; + (system as any).maxScaleX = interval.max; + onChange(); + }; + + // Helper to get/set scale Y - both systems use native minScaleY/maxScaleY + const getScaleY = (): Value | undefined => { + return { type: "IntervalValue", min: (system as any).minScaleY, max: (system as any).maxScaleY }; + }; + + const setScaleY = (value: Value): void => { + const interval = parseIntervalValue(value); + (system as any).minScaleY = interval.min; + (system as any).maxScaleY = interval.max; + onChange(); + }; + + return ( + <> + +
Start Life
+ +
+ + +
Start Size
+ +
+ + +
Scale X
+ +
+ + +
Scale Y
+ +
+ + +
Start Speed
+ +
+ + +
Start Color
+ +
+ + +
Start Rotation
+ {(() => { + // Both systems use native minInitialRotation/maxInitialRotation + const rotation = getStartRotation(); + const angleZ = + rotation && typeof rotation === "object" && "type" in rotation && rotation.type === "Euler" && rotation.angleZ + ? rotation.angleZ + : { type: "IntervalValue" as const, min: 0, max: 0 }; + return ( + { + setStartRotation({ + type: "Euler", + angleZ: newAngleZ as Value, + order: "xyz", + }); + }} + availableTypes={["ConstantValue", "IntervalValue", "PiecewiseBezier"]} + step={0.1} + /> + ); + })()} +
+ + +
Angular Speed
+ +
+ + ); +} diff --git a/editor/src/editor/windows/effect-editor/properties/object.tsx b/editor/src/editor/windows/effect-editor/properties/object.tsx new file mode 100644 index 000000000..eb16d0363 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/properties/object.tsx @@ -0,0 +1,81 @@ +import { ReactNode } from "react"; + +import { EditorInspectorStringField } from "../../../layout/inspector/fields/string"; +import { EditorInspectorVectorField } from "../../../layout/inspector/fields/vector"; +import { EditorInspectorSwitchField } from "../../../layout/inspector/fields/switch"; + +import { type IEffectNode, isSystem } from "babylonjs-editor-tools"; +import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; +import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; + +export interface IEffectEditorObjectPropertiesProps { + nodeData: IEffectNode; + onChange?: () => void; +} + +export function EffectEditorObjectProperties(props: IEffectEditorObjectPropertiesProps): ReactNode { + const { nodeData, onChange } = props; + + if (!nodeData.data) { + return ( + <> + +
Data not available
+ + ); + } + + const object = isSystem(nodeData.data) ? nodeData.data.emitter : nodeData.data; + + const GetRotationInspector = (object: TransformNode | AbstractMesh, onFinishChange?: () => void): ReactNode => { + if (object.rotationQuaternion) { + const valueRef = object.rotationQuaternion.toEulerAngles(); + + const proxy = new Proxy(valueRef, { + get(target, prop) { + return target[prop]; + }, + set(obj, prop, value) { + obj[prop] = value; + object.rotationQuaternion?.copyFrom(obj.toQuaternion()); + + return true; + }, + }); + + const o = { proxy }; + + return ( + Rotation
} + object={o} + property="proxy" + asDegrees + step={0.1} + onFinishChange={() => onFinishChange?.()} + /> + ); + } + + return ( + Rotation} + object={object} + property="rotation" + asDegrees + step={0.1} + onFinishChange={() => onFinishChange?.()} + /> + ); + }; + + return ( + <> + + + + {GetRotationInspector(object as TransformNode, onChange)} + + + ); +} diff --git a/editor/src/editor/windows/effect-editor/properties/renderer.tsx b/editor/src/editor/windows/effect-editor/properties/renderer.tsx new file mode 100644 index 000000000..f416f3128 --- /dev/null +++ b/editor/src/editor/windows/effect-editor/properties/renderer.tsx @@ -0,0 +1,352 @@ +import { Component, ReactNode } from "react"; + +import { EditorInspectorSectionField } from "../../../layout/inspector/fields/section"; +import { EditorInspectorNumberField } from "../../../layout/inspector/fields/number"; +import { EditorInspectorSwitchField } from "../../../layout/inspector/fields/switch"; +import { EditorInspectorListField } from "../../../layout/inspector/fields/list"; +import { EditorInspectorTextureField } from "../../../layout/inspector/fields/texture"; +import { EditorInspectorGeometryField } from "../../../layout/inspector/fields/geometry"; + +import { Material } from "@babylonjs/core/Materials/material"; +import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem"; +import { Mesh } from "@babylonjs/core/Meshes/mesh"; + +import { EditorPBRMaterialInspector } from "../../../layout/inspector/material/pbr"; +import { EditorStandardMaterialInspector } from "../../../layout/inspector/material/standard"; +import { EditorNodeMaterialInspector } from "../../../layout/inspector/material/node"; +import { EditorMultiMaterialInspector } from "../../../layout/inspector/material/multi"; +import { EditorSkyMaterialInspector } from "../../../layout/inspector/material/sky"; +import { EditorGridMaterialInspector } from "../../../layout/inspector/material/grid"; +import { EditorNormalMaterialInspector } from "../../../layout/inspector/material/normal"; +import { EditorWaterMaterialInspector } from "../../../layout/inspector/material/water"; +import { EditorLavaMaterialInspector } from "../../../layout/inspector/material/lava"; +import { EditorTriPlanarMaterialInspector } from "../../../layout/inspector/material/tri-planar"; +import { EditorCellMaterialInspector } from "../../../layout/inspector/material/cell"; +import { EditorFireMaterialInspector } from "../../../layout/inspector/material/fire"; +import { EditorGradientMaterialInspector } from "../../../layout/inspector/material/gradient"; + +import { type IEffectNode, EffectSolidParticleSystem, EffectParticleSystem } from "babylonjs-editor-tools"; +import { IEffectEditor } from ".."; + +export interface IEffectEditorParticleRendererPropertiesProps { + nodeData: IEffectNode; + editor: IEffectEditor; + onChange: () => void; +} + +export interface IEffectEditorParticleRendererPropertiesState { + meshDragOver: boolean; +} + +export class EffectEditorParticleRendererProperties extends Component { + public constructor(props: IEffectEditorParticleRendererPropertiesProps) { + super(props); + this.state = { + meshDragOver: false, + }; + } + + public render(): ReactNode { + const { nodeData } = this.props; + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + const isEffectSolidParticleSystem = system instanceof EffectSolidParticleSystem; + const isEffectParticleSystem = system instanceof EffectParticleSystem; + const systemType = isEffectSolidParticleSystem ? "solid" : "base"; + + return ( + <> + {/* System Mode */} +
System Mode: {systemType === "solid" ? "Mesh (Solid)" : "Billboard (Base)"}
+ + {/* Billboard Mode - только для base */} + {isEffectParticleSystem && ( + <> + this.props.onChange()} + /> + this.props.onChange()} /> + + )} + + {/* World Space (isLocal inverted) */} + {(() => { + const proxy = { + get worldSpace() { + return !(system as any).isLocal; + }, + set worldSpace(value: boolean) { + (system as any).isLocal = !value; + }, + }; + return this.props.onChange()} />; + })()} + + {/* Material Inspector - только для solid с материалом */} + {isEffectSolidParticleSystem && this._getMaterialInspector()} + + {/* Blend Mode - только для base */} + {isEffectParticleSystem && ( + this.props.onChange()} + /> + )} + + {/* Texture */} + {this._getTextureField()} + + {/* Render Order */} + {this._getRenderOrderField()} + + {/* UV Tile */} + {this._getUVTileSection()} + + {/* Start Tile Index */} + {this._getStartTileIndexField()} + + {/* Soft Particles - only for ParticleSystem */} + {isEffectParticleSystem && this.props.onChange()} />} + + {/* Geometry - только для solid */} + {isEffectSolidParticleSystem && this._getGeometryField()} + + ); + } + + private _getMaterialInspector(): ReactNode { + const { nodeData } = this.props; + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + + // Получаем material только для VEffectSolidParticleSystem + if (!(system instanceof EffectSolidParticleSystem) || !system.mesh || !system.mesh.material) { + return null; + } + + const material = system.mesh.material; + return this._getMaterialInspectorComponent(material, system.mesh); + } + + private _getMaterialInspectorComponent(material: Material, mesh?: any): ReactNode { + switch (material.getClassName()) { + case "PBRMaterial": + return ; + + case "StandardMaterial": + return ; + + case "NodeMaterial": + return ; + + case "MultiMaterial": + return ; + + case "SkyMaterial": + return ; + + case "GridMaterial": + return ; + + case "NormalMaterial": + return ; + + case "WaterMaterial": + return ; + + case "LavaMaterial": + return ; + + case "TriPlanarMaterial": + return ; + + case "CellMaterial": + return ; + + case "FireMaterial": + return ; + + case "GradientMaterial": + return ; + + default: + return null; + } + } + + private _getTextureField(): ReactNode { + const { nodeData, editor } = this.props; + + if (nodeData.type !== "particle" || !nodeData.data || !editor.preview?.scene) { + return null; + } + + const system = nodeData.data; + + // For VEffectParticleSystem, use particleTexture + // For VEffectSolidParticleSystem, textures are handled by the material inspector + if (system instanceof EffectParticleSystem) { + return ( + this.props.onChange()} + /> + ); + } + + return null; + } + + private _getRenderOrderField(): ReactNode { + const { nodeData } = this.props; + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + + // Для VEffectParticleSystem, renderOrder хранится в renderingGroupId + if (system instanceof EffectParticleSystem) { + return this.props.onChange()} />; + } + + // Для VEffectSolidParticleSystem, renderOrder хранится в system.renderOrder и применяется к mesh.renderingGroupId + if (system instanceof EffectSolidParticleSystem) { + // Создаем proxy объект для доступа к renderOrder через mesh.renderingGroupId + const proxy = { + get renderingGroupId() { + return system.mesh?.renderingGroupId ?? system.renderOrder ?? 0; + }, + set renderingGroupId(value: number) { + if (system.mesh) { + system.mesh.renderingGroupId = value; + } + system.renderOrder = value; + }, + }; + + return this.props.onChange()} />; + } + + return null; + } + + private _getUVTileSection(): ReactNode { + const { nodeData } = this.props; + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + + // UV Tile only available for ParticleSystem (sprite sheets) + if (system instanceof EffectParticleSystem) { + return ( + + this.props.onChange()} /> + this.props.onChange()} /> + + ); + } + + // SolidParticleSystem uses mesh UVs, no tile settings + return null; + } + + private _getStartTileIndexField(): ReactNode { + const { nodeData } = this.props; + + if (nodeData.type !== "particle" || !nodeData.data) { + return null; + } + + const system = nodeData.data; + + // Start Tile Index only available for ParticleSystem (sprite sheets) + if (system instanceof EffectParticleSystem) { + return this.props.onChange()} />; + } + + // SolidParticleSystem uses mesh UVs, no tile index + return null; + } + + private _getGeometryField(): ReactNode { + const { nodeData, editor } = this.props; + + if (nodeData.type !== "particle" || !nodeData.data || !(nodeData.data instanceof EffectSolidParticleSystem) || !editor.preview?.scene) { + return null; + } + + const system = nodeData.data as EffectSolidParticleSystem; + + // Store reference to source mesh in a custom property + // Since SPS disposes the source mesh after addShape, we need to store it separately + if (!(system as any)._sourceMesh) { + (system as any)._sourceMesh = null; + } + + const proxy = { + get particleMesh() { + // Return stored source mesh or null + return (system as any)._sourceMesh || null; + }, + set particleMesh(value: Mesh | null) { + if (!value) { + // Clear geometry + (system as any)._sourceMesh = null; + return; + } + + // Clone mesh to avoid disposing the original asset + const clonedMesh = value.clone(`${system.name}_particleMesh_temp`, null, false, false); + if (!clonedMesh) { + console.error("[Geometry Field] Failed to clone mesh"); + return; + } + + // Store reference to source mesh for UI display + (system as any)._sourceMesh = value; + + // Replace the particle mesh (this will rebuild the entire SPS) + system.replaceParticleMesh(clonedMesh); + + // Notify change + this.props.onChange(); + }, + }; + + return this.props.onChange()} />; + } +} diff --git a/editor/src/editor/windows/effect-editor/properties/tab.tsx b/editor/src/editor/windows/effect-editor/properties/tab.tsx new file mode 100644 index 000000000..f69eee40b --- /dev/null +++ b/editor/src/editor/windows/effect-editor/properties/tab.tsx @@ -0,0 +1,102 @@ +import { Component, ReactNode } from "react"; +import type { IEffectNode } from "babylonjs-editor-tools"; +import { IEffectEditor } from ".."; +import { EffectEditorObjectProperties } from "./object"; +import { EffectEditorParticleRendererProperties } from "./renderer"; +import { EffectEditorEmissionProperties } from "./emission"; +import { EffectEditorParticleInitializationProperties } from "./initialization"; +import { EffectEditorBehaviorsProperties } from "./behaviors"; + +export interface IEffectEditorPropertiesTabProps { + filePath: string | null; + selectedNodeId: string | number | null; + editor: IEffectEditor; + tabType: "object" | "emission" | "renderer" | "initialization" | "behaviors"; + onNameChanged?: () => void; + getNodeData: (nodeId: string | number) => IEffectNode | null; +} + +export class EffectEditorPropertiesTab extends Component { + public render(): ReactNode { + const { selectedNodeId, tabType, getNodeData, editor, onNameChanged } = this.props; + + if (!selectedNodeId) { + return ( +
+

{tabType === "object" ? "No node selected" : "No particle selected"}

+
+ ); + } + + const nodeData = getNodeData(selectedNodeId); + + if (!nodeData) { + return ( +
+

Node not found

+
+ ); + } + + // For groups, only show object properties + if (nodeData.type === "group" && tabType !== "object") { + return ( +
+

Select a particle system

+
+ ); + } + + // For particles, check if system exists + if (nodeData.type === "particle" && !nodeData.data && tabType !== "object") { + return ( +
+

Select a particle system

+
+ ); + } + + const commonProps = { + nodeData, + onChange: () => { + this.forceUpdate(); + onNameChanged?.(); + }, + }; + + switch (tabType) { + case "object": + return ( +
+ +
+ ); + case "emission": + return ( +
+ +
+ ); + case "renderer": + return ( +
+ +
+ ); + case "initialization": + return ( +
+ +
+ ); + case "behaviors": + return ( +
+ +
+ ); + default: + return null; + } + } +} diff --git a/editor/src/editor/windows/effect-editor/resources.tsx b/editor/src/editor/windows/effect-editor/resources.tsx new file mode 100644 index 000000000..5be69723e --- /dev/null +++ b/editor/src/editor/windows/effect-editor/resources.tsx @@ -0,0 +1,78 @@ +import { Component, ReactNode } from "react"; +import { Tree, TreeNodeInfo } from "@blueprintjs/core"; + +import { IoImageOutline, IoCubeOutline } from "react-icons/io5"; + +import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger } from "../../../ui/shadcn/ui/context-menu"; + +export interface IEffectEditorResourcesProps { + resources: any[]; +} + +export interface IEffectEditorResourcesState { + nodes: TreeNodeInfo[]; +} + +export class EffectEditorResources extends Component { + public constructor(props: IEffectEditorResourcesProps) { + super(props); + + this.state = { + nodes: this._convertToTreeNodeInfo(props.resources), + }; + } + + public componentDidUpdate(prevProps: IEffectEditorResourcesProps): void { + if (prevProps.resources !== this.props.resources) { + this.setState({ + nodes: this._convertToTreeNodeInfo(this.props.resources), + }); + } + } + + private _convertToTreeNodeInfo(resources: any[]): TreeNodeInfo[] { + return resources.map((resource) => { + const icon = resource.type === "texture" ? : ; + + const label = ( + + +
{resource.name}
+
+ + UUID: {resource.resourceData?.uuid || resource.id} + {resource.resourceData?.path && Path: {resource.resourceData.path}} + +
+ ); + + return { + id: resource.id, + label, + icon, + isExpanded: false, + childNodes: undefined, + isSelected: false, + hasCaret: false, + }; + }); + } + + public render(): ReactNode { + if (this.state.nodes.length === 0) { + return ( +
+

No resources

+
+ ); + } + + return ( +
+
+ +
+
+ ); + } +} diff --git a/editor/src/editor/windows/effect-editor/toolbar.tsx b/editor/src/editor/windows/effect-editor/toolbar.tsx new file mode 100644 index 000000000..e9742a6da --- /dev/null +++ b/editor/src/editor/windows/effect-editor/toolbar.tsx @@ -0,0 +1,160 @@ +import { Component, ReactNode } from "react"; + +import { + Menubar, + MenubarContent, + MenubarItem, + MenubarMenu, + MenubarSeparator, + MenubarShortcut, + MenubarSub, + MenubarSubContent, + MenubarSubTrigger, + MenubarTrigger, +} from "../../../ui/shadcn/ui/menubar"; + +import { openSingleFileDialog, saveSingleFileDialog } from "../../../tools/dialog"; +import { ToolbarComponent } from "../../../ui/toolbar"; + +import IEffectEditor from "./index"; + +export interface IEffectEditorToolbarProps { + editor: IEffectEditor; +} + +export interface IEffectEditorToolbarState { + // No state needed - modal is managed by editor +} + +export class EffectEditorToolbar extends Component { + constructor(props: IEffectEditorToolbarProps) { + super(props); + this.state = {}; + } + public render(): ReactNode { + return ( + + + + + {/* File */} + + File + + this._handleOpen()}> + Open... CTRL+O + + + + + this._handleSave()}> + Save CTRL+S + + + this._handleSaveAs()}> + Save As... CTRL+SHIFT+S + + + + + {/* Import Submenu */} + + Import... + + this._handleImportBabylonEffect()}>Babylon Effect + this._handleImportQuarks()}>Quarks Effect + + this._handleImportUnity()}>Unity Assets + + + + + + +
+
+ Effect Editor + {this.props.editor.state.filePath && ( +
(...{this.props.editor.state.filePath.substring(this.props.editor.state.filePath.length - 30)})
+ )} +
+
+
+ ); + } + + private _handleOpen(): void { + const file = openSingleFileDialog({ + title: "Open Effect File", + filters: [{ name: "Effect Files", extensions: ["Effect", "json"] }], + }); + + if (!file) { + return; + } + + this.props.editor.loadFile(file); + } + + private _handleSave(): void { + if (!this.props.editor.state.filePath) { + this._handleSaveAs(); + return; + } + + this.props.editor.save(); + } + + private _handleSaveAs(): void { + const file = saveSingleFileDialog({ + title: "Save Effect File", + filters: [{ name: "Effect Files", extensions: ["Effect", "json"] }], + defaultPath: this.props.editor.state.filePath || "untitled.Effect", + }); + + if (!file) { + return; + } + + this.props.editor.saveAs(file); + } + + /** + * Handle import Babylon Effect JSON + */ + private _handleImportBabylonEffect(): void { + const file = openSingleFileDialog({ + title: "Import Babylon Effect JSON", + filters: [{ name: "Effect Files", extensions: ["effect"] }], + }); + + if (!file) { + return; + } + + this.props.editor.importFile(file); + } + + /** + * Handle import Quarks JSON + */ + private _handleImportQuarks(): void { + const file = openSingleFileDialog({ + title: "Import Quarks JSON", + filters: [{ name: "Quarks Files", extensions: ["json"] }], + }); + + if (!file) { + return; + } + + this.props.editor.importQuarksFile(file); + } + + /** + * Handle import Unity assets (open modal) + */ + private _handleImportUnity(): void { + this.props.editor.openUnityImportModal(); + } +} diff --git a/editor/src/ui/gradient-picker.tsx b/editor/src/ui/gradient-picker.tsx new file mode 100644 index 000000000..25f02aeed --- /dev/null +++ b/editor/src/ui/gradient-picker.tsx @@ -0,0 +1,407 @@ +import { ReactNode, MouseEvent, useState, useRef, useEffect } from "react"; +import { Color3, Color4 } from "babylonjs"; +import { ColorPicker } from "./color-picker"; +import { Button } from "../ui/shadcn/ui/button"; +import { AiOutlineClose } from "react-icons/ai"; + +/** + * Universal gradient key type (not tied to Effect) + */ +export interface IGradientKey { + time?: number; + value: number | [number, number, number, number] | { r: number; g: number; b: number; a?: number }; + pos?: number; +} + +export interface IGradientPickerProps { + colorKeys: IGradientKey[]; + alphaKeys?: IGradientKey[]; + onChange: (colorKeys: IGradientKey[], alphaKeys?: IGradientKey[]) => void; + onFinish?: (colorKeys: IGradientKey[], alphaKeys?: IGradientKey[]) => void; + className?: string; +} + +/** + * Visual gradient picker component + * Allows users to visually edit gradient by clicking on gradient bar, dragging stops, and picking colors + */ +export function GradientPicker(props: IGradientPickerProps): ReactNode { + const { colorKeys, alphaKeys = [], onChange, onFinish, className } = props; + const [selectedKeyIndex, setSelectedKeyIndex] = useState(null); + const [selectedAlphaIndex, setSelectedAlphaIndex] = useState(null); + const gradientRef = useRef(null); + const alphaRef = useRef(null); + const [isDragging, setIsDragging] = useState(false); + const [dragKeyIndex, setDragKeyIndex] = useState(null); + const [isAlphaDragging, setIsAlphaDragging] = useState(false); + const [dragAlphaIndex, setDragAlphaIndex] = useState(null); + + // Sort keys by position + const sortedColorKeys = [...colorKeys].sort((a, b) => (a.pos || 0) - (b.pos || 0)); + const sortedAlphaKeys = [...alphaKeys].sort((a, b) => (a.pos || 0) - (b.pos || 0)); + + // Generate gradient CSS string + const generateGradient = (keys: IGradientKey[]): string => { + const sorted = [...keys].sort((a, b) => (a.pos || 0) - (b.pos || 0)); + const stops = sorted.map((key) => { + const pos = (key.pos || 0) * 100; + let color = "rgba(0, 0, 0, 1)"; + if (Array.isArray(key.value)) { + const [r, g, b, a = 1] = key.value; + color = `rgba(${r * 255}, ${g * 255}, ${b * 255}, ${a})`; + } else if (typeof key.value === "object" && "r" in key.value) { + const r = key.value.r * 255; + const g = key.value.g * 255; + const b = key.value.b * 255; + const a = ("a" in key.value && key.value.a !== undefined ? key.value.a : 1) * 255; + color = `rgba(${r}, ${g}, ${b}, ${a / 255})`; + } + return `${color} ${pos}%`; + }); + return `linear-gradient(to right, ${stops.join(", ")})`; + }; + + // Get color value from key + const getColorFromKey = (key: IGradientKey): Color4 => { + if (Array.isArray(key.value)) { + const [r, g, b, a = 1] = key.value; + return new Color4(r, g, b, a); + } else if (typeof key.value === "object" && "r" in key.value) { + return new Color4(key.value.r, key.value.g, key.value.b, "a" in key.value ? key.value.a || 1 : 1); + } + return new Color4(0, 0, 0, 1); + }; + + // Interpolate color at position + const interpolateColorAtPosition = (keys: IGradientKey[], pos: number): Color4 => { + if (keys.length === 0) { + return new Color4(1, 1, 1, 1); + } + if (keys.length === 1) { + return getColorFromKey(keys[0]); + } + + for (let i = 0; i < keys.length - 1; i++) { + const key1 = keys[i]; + const key2 = keys[i + 1]; + const pos1 = key1.pos || 0; + const pos2 = key2.pos || 0; + + if (pos >= pos1 && pos <= pos2) { + const t = (pos - pos1) / (pos2 - pos1); + const color1 = getColorFromKey(key1); + const color2 = getColorFromKey(key2); + return new Color4( + color1.r + (color2.r - color1.r) * t, + color1.g + (color2.g - color1.g) * t, + color1.b + (color2.b - color1.b) * t, + color1.a + (color2.a - color1.a) * t + ); + } + } + + // Outside range, return nearest + if (pos <= (keys[0].pos || 0)) { + return getColorFromKey(keys[0]); + } + return getColorFromKey(keys[keys.length - 1]); + }; + + // Handle click on gradient bar to add/select key + const handleGradientClick = (e: MouseEvent, isAlpha: boolean = false) => { + const rect = isAlpha ? alphaRef.current?.getBoundingClientRect() : gradientRef.current?.getBoundingClientRect(); + if (!rect) { + return; + } + + const x = e.clientX - rect.left; + const pos = Math.max(0, Math.min(1, x / rect.width)); + + if (isAlpha) { + // Check if clicked near existing alpha key + const nearKeyIndex = sortedAlphaKeys.findIndex((key) => Math.abs((key.pos || 0) - pos) < 0.05); + if (nearKeyIndex >= 0) { + setSelectedAlphaIndex(nearKeyIndex); + return; + } + + // Add new alpha key + const newAlphaKeys = [...alphaKeys, { pos, value: 1 }]; + const sorted = newAlphaKeys.sort((a, b) => (a.pos || 0) - (b.pos || 0)); + const newIndex = sorted.findIndex((key) => key.pos === pos); + setSelectedAlphaIndex(newIndex); + onChange(colorKeys, sorted); + } else { + // Check if clicked near existing color key + const nearKeyIndex = sortedColorKeys.findIndex((key) => Math.abs((key.pos || 0) - pos) < 0.05); + if (nearKeyIndex >= 0) { + setSelectedKeyIndex(nearKeyIndex); + return; + } + + // Interpolate color at position + const color = interpolateColorAtPosition(sortedColorKeys, pos); + const newKey: IGradientKey = { pos, value: [color.r, color.g, color.b, color.a] as [number, number, number, number] }; + const newColorKeys: IGradientKey[] = [...colorKeys, newKey]; + const sorted = newColorKeys.sort((a, b) => (a.pos || 0) - (b.pos || 0)); + const newIndex = sorted.findIndex((key) => key.pos === pos); + setSelectedKeyIndex(newIndex); + onChange(sorted, alphaKeys); + } + }; + + // Handle mouse down on key stop + const handleKeyMouseDown = (e: MouseEvent, index: number, isAlpha: boolean) => { + e.stopPropagation(); + if (isAlpha) { + setIsAlphaDragging(true); + setDragAlphaIndex(index); + setSelectedAlphaIndex(index); + } else { + setIsDragging(true); + setDragKeyIndex(index); + setSelectedKeyIndex(index); + } + }; + + // Handle mouse move for dragging + useEffect(() => { + const handleMouseMove = (e: MouseEvent) => { + if (isDragging && dragKeyIndex !== null && gradientRef.current) { + const rect = gradientRef.current.getBoundingClientRect(); + const x = e.clientX - rect.left; + const pos = Math.max(0, Math.min(1, x / rect.width)); + + const newColorKeys = [...colorKeys]; + const key = sortedColorKeys[dragKeyIndex]; + const originalIndex = colorKeys.findIndex((k) => k === key); + if (originalIndex >= 0) { + newColorKeys[originalIndex] = { ...key, pos }; + onChange(newColorKeys, alphaKeys); + } + } + + if (isAlphaDragging && dragAlphaIndex !== null && alphaRef.current) { + const rect = alphaRef.current.getBoundingClientRect(); + const x = e.clientX - rect.left; + const pos = Math.max(0, Math.min(1, x / rect.width)); + + const newAlphaKeys = [...alphaKeys]; + const key = sortedAlphaKeys[dragAlphaIndex]; + const originalIndex = alphaKeys.findIndex((k) => k === key); + if (originalIndex >= 0) { + newAlphaKeys[originalIndex] = { ...key, pos }; + onChange(colorKeys, newAlphaKeys); + } + } + }; + + const handleMouseUp = () => { + if (isDragging || isAlphaDragging) { + setIsDragging(false); + setIsAlphaDragging(false); + setDragKeyIndex(null); + setDragAlphaIndex(null); + if (onFinish) { + onFinish(colorKeys, alphaKeys); + } + } + }; + + if (isDragging || isAlphaDragging) { + window.addEventListener("mousemove", handleMouseMove as any); + window.addEventListener("mouseup", handleMouseUp); + return () => { + window.removeEventListener("mousemove", handleMouseMove as any); + window.removeEventListener("mouseup", handleMouseUp); + }; + } + }, [isDragging, isAlphaDragging, dragKeyIndex, dragAlphaIndex, colorKeys, alphaKeys, onChange, onFinish, sortedColorKeys, sortedAlphaKeys]); + + // Handle color change for selected key + const handleColorChange = (color: Color3 | Color4) => { + if (selectedKeyIndex === null) { + return; + } + + const key = sortedColorKeys[selectedKeyIndex]; + const originalIndex = colorKeys.findIndex((k) => k === key); + if (originalIndex >= 0) { + const newColorKeys = [...colorKeys]; + newColorKeys[originalIndex] = { + ...key, + value: [color.r, color.g, color.b, color instanceof Color4 ? color.a : 1], + }; + onChange(newColorKeys, alphaKeys); + } + }; + + // Handle alpha change for selected alpha key + const handleAlphaChange = (value: number) => { + if (selectedAlphaIndex === null) { + return; + } + + const key = sortedAlphaKeys[selectedAlphaIndex]; + const originalIndex = alphaKeys.findIndex((k) => k === key); + if (originalIndex >= 0) { + const newAlphaKeys = [...alphaKeys]; + newAlphaKeys[originalIndex] = { ...key, value }; + onChange(colorKeys, newAlphaKeys); + } + }; + + // Handle delete key + const handleDeleteKey = (index: number, isAlpha: boolean) => { + if (isAlpha) { + if (alphaKeys.length <= 2) { + return; // Keep at least 2 keys + } + const newAlphaKeys = alphaKeys.filter((_, i) => i !== index); + setSelectedAlphaIndex(null); + onChange(colorKeys, newAlphaKeys); + } else { + if (colorKeys.length <= 2) { + return; // Keep at least 2 keys + } + const newColorKeys = colorKeys.filter((_, i) => i !== index); + setSelectedKeyIndex(null); + onChange(newColorKeys, alphaKeys); + } + }; + + return ( +
+ {/* Color Gradient Bar */} +
+
Color Gradient
+
handleGradientClick(e, false)} + > + {sortedColorKeys.map((key, index) => { + const pos = (key.pos || 0) * 100; + const color = getColorFromKey(key); + const isSelected = selectedKeyIndex === index; + return ( +
handleKeyMouseDown(e, index, false)} + > +
+
+ ); + })} +
+ + {/* Color Picker for Selected Key */} + {selectedKeyIndex !== null && ( +
+
+ handleColorChange(new Color4(color.r, color.g, color.b, color.a))} + onFinish={(color) => { + handleColorChange(new Color4(color.r, color.g, color.b, color.a)); + if (onFinish) { + onFinish(colorKeys, alphaKeys); + } + }} + /> +
+ +
+ )} +
+ + {/* Alpha Gradient Bar */} +
+
Alpha Gradient
+
handleGradientClick(e, true)} + > + {sortedAlphaKeys.map((key, index) => { + const pos = (key.pos || 0) * 100; + const alphaValue = typeof key.value === "number" ? key.value : Array.isArray(key.value) ? key.value[3] || 1 : 1; + const isSelected = selectedAlphaIndex === index; + return ( +
handleKeyMouseDown(e, index, true)} + > +
+
+ ); + })} +
+ + {/* Alpha Slider for Selected Key */} + {selectedAlphaIndex !== null && ( +
+
+ handleAlphaChange(parseFloat(e.target.value))} + className="w-full" + /> +
+ +
+ )} +
+
+ ); +} diff --git a/editor/src/ui/shadcn/ui/scroll-area.tsx b/editor/src/ui/shadcn/ui/scroll-area.tsx new file mode 100644 index 000000000..541bed078 --- /dev/null +++ b/editor/src/ui/shadcn/ui/scroll-area.tsx @@ -0,0 +1,37 @@ +import * as React from "react"; +import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"; + +import { cn } from "../../utils"; + +const ScrollArea = React.forwardRef, React.ComponentPropsWithoutRef>( + ({ className, children, ...props }, ref) => ( + + {children} + + + + ) +); +ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName; + +const ScrollBar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, orientation = "vertical", ...props }, ref) => ( + + + +)); +ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName; + +export { ScrollArea, ScrollBar }; diff --git a/tools/src/effect/behaviors/colorBySpeed.ts b/tools/src/effect/behaviors/colorBySpeed.ts new file mode 100644 index 000000000..9bbb495c0 --- /dev/null +++ b/tools/src/effect/behaviors/colorBySpeed.ts @@ -0,0 +1,68 @@ +import type { IColorBySpeedBehavior } from "../types"; +import type { Particle } from "@babylonjs/core/Particles/particle"; +import { interpolateColorKeys } from "./utils"; + +/** + * Apply ColorBySpeed behavior to ParticleSystem (per-particle) + * Uses unified IColorFunction structure: behavior.color = { colorFunctionType, data } + */ +export function applyColorBySpeedPS(behavior: IColorBySpeedBehavior, particle: Particle): void { + // New structure: behavior.color.data.colorKeys + if (!behavior.color || !behavior.color.data?.colorKeys || !particle.color || !particle.direction) { + return; + } + + const minSpeed = behavior.minSpeed !== undefined ? (typeof behavior.minSpeed === "number" ? behavior.minSpeed : 0) : 0; + const maxSpeed = behavior.maxSpeed !== undefined ? (typeof behavior.maxSpeed === "number" ? behavior.maxSpeed : 1) : 1; + const colorKeys = behavior.color.data.colorKeys; + + if (!colorKeys || colorKeys.length === 0) { + return; + } + + const vel = particle.direction; + const currentSpeed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z); + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + const interpolatedColor = interpolateColorKeys(colorKeys, speedRatio); + + particle.color.r = interpolatedColor.r; + particle.color.g = interpolatedColor.g; + particle.color.b = interpolatedColor.b; + particle.color.a = interpolatedColor.a; +} + +/** + * Apply ColorBySpeed behavior to SolidParticleSystem (per-particle) + * Uses unified IColorFunction structure: behavior.color = { colorFunctionType, data } + */ +export function applyColorBySpeedSPS(behavior: IColorBySpeedBehavior, particle: any): void { + // New structure: behavior.color.data.colorKeys + if (!behavior.color || !behavior.color.data?.colorKeys || !particle.color) { + return; + } + + const minSpeed = behavior.minSpeed !== undefined ? (typeof behavior.minSpeed === "number" ? behavior.minSpeed : 0) : 0; + const maxSpeed = behavior.maxSpeed !== undefined ? (typeof behavior.maxSpeed === "number" ? behavior.maxSpeed : 1) : 1; + const colorKeys = behavior.color.data.colorKeys; + + if (!colorKeys || colorKeys.length === 0) { + return; + } + + const vel = particle.velocity; + const currentSpeed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z); + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + const interpolatedColor = interpolateColorKeys(colorKeys, speedRatio); + const startColor = particle.props?.startColor; + + if (startColor) { + particle.color.r = interpolatedColor.r * startColor.r; + particle.color.g = interpolatedColor.g * startColor.g; + particle.color.b = interpolatedColor.b * startColor.b; + particle.color.a = startColor.a; + } else { + particle.color.r = interpolatedColor.r; + particle.color.g = interpolatedColor.g; + particle.color.b = interpolatedColor.b; + } +} diff --git a/tools/src/effect/behaviors/colorOverLife.ts b/tools/src/effect/behaviors/colorOverLife.ts new file mode 100644 index 000000000..c3e64b4bc --- /dev/null +++ b/tools/src/effect/behaviors/colorOverLife.ts @@ -0,0 +1,297 @@ +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import type { IColorOverLifeBehavior } from "../types"; +import { extractColorFromValue, extractAlphaFromValue } from "./utils"; +import type { EffectSolidParticleSystem, EffectParticleSystem } from "../systems"; +/** + * Apply ColorOverLife behavior to ParticleSystem + * Uses unified IColorFunction structure: behavior.color = { colorFunctionType, data } + */ +export function applyColorOverLifePS(particleSystem: EffectParticleSystem, behavior: IColorOverLifeBehavior | any): void { + // New unified structure: behavior.color is IColorFunction + const colorFunction = behavior.color; + if (!colorFunction) { + return; + } + + const colorFunctionType = colorFunction.colorFunctionType; + const data = colorFunction.data; + + // Handle ConstantColor + if (colorFunctionType === "ConstantColor" && data?.color) { + const color = data.color; + particleSystem.color1 = new Color4(color.r, color.g, color.b, color.a); + particleSystem.color2 = new Color4(color.r, color.g, color.b, color.a); + return; + } + + // Handle RandomColorBetweenGradient - apply first gradient (TODO: implement proper random selection per particle) + if (colorFunctionType === "RandomColorBetweenGradient" && data?.gradient1) { + const colorKeys = data.gradient1.colorKeys || []; + const alphaKeys = data.gradient1.alphaKeys || []; + + // Apply first gradient + for (const key of colorKeys) { + if (key.value !== undefined && key.pos !== undefined) { + let color: { r: number; g: number; b: number }; + let alpha: number; + + if (Array.isArray(key.value)) { + color = { r: key.value[0], g: key.value[1], b: key.value[2] }; + alpha = key.value[3] !== undefined ? key.value[3] : 1; + } else { + color = extractColorFromValue(key.value); + alpha = extractAlphaFromValue(key.value); + } + + particleSystem.addColorGradient(key.pos, new Color4(color.r, color.g, color.b, alpha)); + } + } + + for (const key of alphaKeys) { + if (key.value !== undefined && key.pos !== undefined) { + const alpha = typeof key.value === "number" ? key.value : extractAlphaFromValue(key.value); + const existingGradients = particleSystem.getColorGradients(); + const existingGradient = existingGradients?.find((g) => Math.abs(g.gradient - key.pos) < 0.001); + if (existingGradient) { + existingGradient.color1.a = alpha; + if (existingGradient.color2) { + existingGradient.color2.a = alpha; + } + } else { + particleSystem.addColorGradient(key.pos, new Color4(1, 1, 1, alpha)); + } + } + } + return; + } + + // Handle Gradient + if (colorFunctionType === "Gradient" && data) { + const colorKeys = data.colorKeys || []; + const alphaKeys = data.alphaKeys || []; + + // Apply color keys + for (const key of colorKeys) { + if (key.value !== undefined && key.pos !== undefined) { + let color: { r: number; g: number; b: number }; + let alpha: number; + + if (Array.isArray(key.value)) { + // UI format: [r, g, b, a] + color = { r: key.value[0], g: key.value[1], b: key.value[2] }; + alpha = key.value[3] !== undefined ? key.value[3] : 1; + } else { + // Quarks format: extract from value + color = extractColorFromValue(key.value); + alpha = extractAlphaFromValue(key.value); + } + + particleSystem.addColorGradient(key.pos, new Color4(color.r, color.g, color.b, alpha)); + } + } + + // Apply alpha keys (merge with existing color gradients) + for (const key of alphaKeys) { + if (key.value !== undefined && key.pos !== undefined) { + const alpha = typeof key.value === "number" ? key.value : extractAlphaFromValue(key.value); + const existingGradients = particleSystem.getColorGradients(); + const existingGradient = existingGradients?.find((g) => Math.abs(g.gradient - key.pos) < 0.001); + if (existingGradient) { + existingGradient.color1.a = alpha; + if (existingGradient.color2) { + existingGradient.color2.a = alpha; + } + } else { + particleSystem.addColorGradient(key.pos, new Color4(1, 1, 1, alpha)); + } + } + } + } +} + +/** + * Apply ColorOverLife behavior to SolidParticleSystem + * Uses unified IColorFunction structure: behavior.color = { colorFunctionType, data } + */ +export function applyColorOverLifeSPS(system: EffectSolidParticleSystem, behavior: IColorOverLifeBehavior | any): void { + // New unified structure: behavior.color is IColorFunction + const colorFunction = behavior.color; + if (!colorFunction) { + return; + } + + const colorFunctionType = colorFunction.colorFunctionType; + const data = colorFunction.data; + let colorKeys: any[] = []; + let alphaKeys: any[] = []; + + // Handle ConstantColor + if (colorFunctionType === "ConstantColor" && data?.color) { + const color = data.color; + system.color1 = new Color4(color.r, color.g, color.b, color.a); + system.color2 = new Color4(color.r, color.g, color.b, color.a); + return; + } + + // Handle RandomColorBetweenGradient - apply first gradient (TODO: implement proper random selection per particle) + if (colorFunctionType === "RandomColorBetweenGradient" && data?.gradient1) { + colorKeys = data.gradient1.colorKeys || []; + alphaKeys = data.gradient1.alphaKeys || []; + } else if (colorFunctionType === "Gradient" && data) { + colorKeys = data.colorKeys || []; + alphaKeys = data.alphaKeys || []; + } else { + return; + } + + // Collect all unique positions from both color and alpha keys + const allPositions = new Set(); + for (const key of colorKeys) { + if (key.pos !== undefined) { + allPositions.add(key.pos); + } + } + for (const key of alphaKeys) { + const pos = key.pos ?? key.time ?? 0; + allPositions.add(pos); + } + + if (allPositions.size === 0) { + return; + } + + // Sort positions and create gradients at each position + const sortedPositions = Array.from(allPositions).sort((a, b) => a - b); + for (const pos of sortedPositions) { + // Get color at this position + let color = { r: 1, g: 1, b: 1 }; + if (colorKeys.length > 0) { + const exactColorKey = colorKeys.find((k) => k.pos !== undefined && Math.abs(k.pos - pos) < 0.001); + if (exactColorKey && exactColorKey.value !== undefined) { + if (Array.isArray(exactColorKey.value)) { + color = { r: exactColorKey.value[0], g: exactColorKey.value[1], b: exactColorKey.value[2] }; + } else { + color = extractColorFromValue(exactColorKey.value); + } + } else { + // Interpolate color from surrounding keys + color = interpolateColorFromKeys(colorKeys, pos); + } + } + + // Get alpha at this position + let alpha = 1; + if (alphaKeys.length > 0) { + const exactAlphaKey = alphaKeys.find((k) => { + const kPos = k.pos ?? k.time ?? 0; + return Math.abs(kPos - pos) < 0.001; + }); + if (exactAlphaKey && exactAlphaKey.value !== undefined) { + if (typeof exactAlphaKey.value === "number") { + alpha = exactAlphaKey.value; + } else { + alpha = extractAlphaFromValue(exactAlphaKey.value); + } + } else { + // Interpolate alpha from surrounding keys + alpha = interpolateAlphaFromKeys(alphaKeys, pos); + } + } else if (colorKeys.length > 0) { + // If no alpha keys, try to get alpha from color key + const exactColorKey = colorKeys.find((k) => k.pos !== undefined && Math.abs(k.pos - pos) < 0.001); + if (exactColorKey && exactColorKey.value !== undefined) { + if (Array.isArray(exactColorKey.value)) { + alpha = exactColorKey.value[3] !== undefined ? exactColorKey.value[3] : 1; + } else { + alpha = extractAlphaFromValue(exactColorKey.value); + } + } + } + + system.addColorGradient(pos, new Color4(color.r, color.g, color.b, alpha)); + } +} + +/** + * Interpolate color from gradient keys at a given position + */ +function interpolateColorFromKeys(keys: any[], pos: number): { r: number; g: number; b: number } { + if (keys.length === 0) { + return { r: 1, g: 1, b: 1 }; + } + if (keys.length === 1) { + const value = keys[0].value; + return Array.isArray(value) ? { r: value[0], g: value[1], b: value[2] } : extractColorFromValue(value); + } + + // Find surrounding keys + let before = keys[0]; + let after = keys[keys.length - 1]; + for (let i = 0; i < keys.length - 1; i++) { + const k1 = keys[i]; + const k2 = keys[i + 1]; + if (k1.pos !== undefined && k2.pos !== undefined && k1.pos <= pos && k2.pos >= pos) { + before = k1; + after = k2; + break; + } + } + + if (before === after) { + const value = before.value; + return Array.isArray(value) ? { r: value[0], g: value[1], b: value[2] } : extractColorFromValue(value); + } + + // Interpolate + const t = (pos - (before.pos ?? 0)) / ((after.pos ?? 1) - (before.pos ?? 0)); + const c1 = Array.isArray(before.value) ? { r: before.value[0], g: before.value[1], b: before.value[2] } : extractColorFromValue(before.value); + const c2 = Array.isArray(after.value) ? { r: after.value[0], g: after.value[1], b: after.value[2] } : extractColorFromValue(after.value); + + return { + r: c1.r + (c2.r - c1.r) * t, + g: c1.g + (c2.g - c1.g) * t, + b: c1.b + (c2.b - c1.b) * t, + }; +} + +/** + * Interpolate alpha from gradient keys at a given position + */ +function interpolateAlphaFromKeys(keys: any[], pos: number): number { + if (keys.length === 0) { + return 1; + } + if (keys.length === 1) { + const value = keys[0].value; + return typeof value === "number" ? value : extractAlphaFromValue(value); + } + + // Find surrounding keys + let before = keys[0]; + let after = keys[keys.length - 1]; + for (let i = 0; i < keys.length - 1; i++) { + const k1 = keys[i]; + const k2 = keys[i + 1]; + const k1Pos = k1.pos ?? k1.time ?? 0; + const k2Pos = k2.pos ?? k2.time ?? 1; + if (k1Pos <= pos && k2Pos >= pos) { + before = k1; + after = k2; + break; + } + } + + if (before === after) { + const value = before.value; + return typeof value === "number" ? value : extractAlphaFromValue(value); + } + + // Interpolate + const beforePos = before.pos ?? before.time ?? 0; + const afterPos = after.pos ?? after.time ?? 1; + const t = (pos - beforePos) / (afterPos - beforePos); + const a1 = typeof before.value === "number" ? before.value : extractAlphaFromValue(before.value); + const a2 = typeof after.value === "number" ? after.value : extractAlphaFromValue(after.value); + + return a1 + (a2 - a1) * t; +} diff --git a/tools/src/effect/behaviors/forceOverLife.ts b/tools/src/effect/behaviors/forceOverLife.ts new file mode 100644 index 000000000..cb64539be --- /dev/null +++ b/tools/src/effect/behaviors/forceOverLife.ts @@ -0,0 +1,34 @@ +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import type { IForceOverLifeBehavior, IGravityForceBehavior } from "../types"; +import { parseConstantValue } from "../utils"; +import type { EffectParticleSystem } from "../systems"; +/** + * Apply ForceOverLife behavior to ParticleSystem + */ +export function applyForceOverLifePS(particleSystem: EffectParticleSystem, behavior: IForceOverLifeBehavior): void { + if (behavior.force) { + const forceX = behavior.force.x !== undefined ? parseConstantValue(behavior.force.x) : 0; + const forceY = behavior.force.y !== undefined ? parseConstantValue(behavior.force.y) : 0; + const forceZ = behavior.force.z !== undefined ? parseConstantValue(behavior.force.z) : 0; + if (Math.abs(forceY) > 0.01 || Math.abs(forceX) > 0.01 || Math.abs(forceZ) > 0.01) { + particleSystem.gravity = new Vector3(forceX, forceY, forceZ); + } + } else if (behavior.x !== undefined || behavior.y !== undefined || behavior.z !== undefined) { + const forceX = behavior.x !== undefined ? parseConstantValue(behavior.x) : 0; + const forceY = behavior.y !== undefined ? parseConstantValue(behavior.y) : 0; + const forceZ = behavior.z !== undefined ? parseConstantValue(behavior.z) : 0; + if (Math.abs(forceY) > 0.01 || Math.abs(forceX) > 0.01 || Math.abs(forceZ) > 0.01) { + particleSystem.gravity = new Vector3(forceX, forceY, forceZ); + } + } +} + +/** + * Apply GravityForce behavior to ParticleSystem + */ +export function applyGravityForcePS(particleSystem: EffectParticleSystem, behavior: IGravityForceBehavior): void { + if (behavior.gravity !== undefined) { + const gravity = parseConstantValue(behavior.gravity); + particleSystem.gravity = new Vector3(0, -gravity, 0); + } +} diff --git a/tools/src/effect/behaviors/frameOverLife.ts b/tools/src/effect/behaviors/frameOverLife.ts new file mode 100644 index 000000000..9fb7dea38 --- /dev/null +++ b/tools/src/effect/behaviors/frameOverLife.ts @@ -0,0 +1,34 @@ +import type { IFrameOverLifeBehavior } from "../types"; +import { parseConstantValue } from "../utils"; +import type { EffectParticleSystem } from "../systems"; +/** + * Apply FrameOverLife behavior to ParticleSystem + */ +export function applyFrameOverLifePS(particleSystem: EffectParticleSystem, behavior: IFrameOverLifeBehavior): void { + if (!behavior.frame) { + return; + } + + particleSystem.isAnimationSheetEnabled = true; + if (typeof behavior.frame === "object" && behavior.frame !== null && "keys" in behavior.frame && behavior.frame.keys && Array.isArray(behavior.frame.keys)) { + const frames = behavior.frame.keys.map((k) => { + const val = k.value; + const pos = k.pos ?? k.time ?? 0; + if (typeof val === "number") { + return val; + } + if (Array.isArray(val)) { + return val[0] || 0; + } + return pos; + }); + if (frames.length > 0) { + particleSystem.startSpriteCellID = Math.floor(frames[0]); + particleSystem.endSpriteCellID = Math.floor(frames[frames.length - 1] || frames[0]); + } + } else if (typeof behavior.frame === "number" || (typeof behavior.frame === "object" && behavior.frame !== null && "type" in behavior.frame)) { + const frameValue = parseConstantValue(behavior.frame); + particleSystem.startSpriteCellID = Math.floor(frameValue); + particleSystem.endSpriteCellID = Math.floor(frameValue); + } +} diff --git a/tools/src/effect/behaviors/index.ts b/tools/src/effect/behaviors/index.ts new file mode 100644 index 000000000..849a07acf --- /dev/null +++ b/tools/src/effect/behaviors/index.ts @@ -0,0 +1,18 @@ +/** + * Behavior modules for VFX particle systems + * + * Each behavior module exports functions for both ParticleSystem (PS) and SolidParticleSystem (SPS) + */ + +export * from "./colorOverLife"; +export * from "./sizeOverLife"; +export * from "./rotationOverLife"; +export * from "./forceOverLife"; +export * from "./speedOverLife"; +export * from "./colorBySpeed"; +export * from "./sizeBySpeed"; +export * from "./rotationBySpeed"; +export * from "./orbitOverLife"; +export * from "./frameOverLife"; +export * from "./limitSpeedOverLife"; +export * from "./utils"; diff --git a/tools/src/effect/behaviors/limitSpeedOverLife.ts b/tools/src/effect/behaviors/limitSpeedOverLife.ts new file mode 100644 index 000000000..5fdc741cd --- /dev/null +++ b/tools/src/effect/behaviors/limitSpeedOverLife.ts @@ -0,0 +1,66 @@ +import type { ILimitSpeedOverLifeBehavior } from "../types"; +import { extractNumberFromValue } from "./utils"; +import { parseConstantValue } from "../utils"; +import type { EffectSolidParticleSystem, EffectParticleSystem } from "../systems"; +/** + * Apply LimitSpeedOverLife behavior to ParticleSystem + */ +export function applyLimitSpeedOverLifePS(particleSystem: EffectParticleSystem, behavior: ILimitSpeedOverLifeBehavior): void { + if (behavior.dampen !== undefined) { + const dampen = parseConstantValue(behavior.dampen); + particleSystem.limitVelocityDamping = dampen; + } + + if (behavior.maxSpeed !== undefined) { + const speedLimit = parseConstantValue(behavior.maxSpeed); + particleSystem.addLimitVelocityGradient(0, speedLimit); + particleSystem.addLimitVelocityGradient(1, speedLimit); + } else if (behavior.speed !== undefined) { + if (typeof behavior.speed === "object" && behavior.speed !== null && "keys" in behavior.speed && behavior.speed.keys && Array.isArray(behavior.speed.keys)) { + for (const key of behavior.speed.keys) { + const pos = key.pos ?? key.time ?? 0; + const val = key.value; + if (val !== undefined && pos !== undefined) { + const numVal = extractNumberFromValue(val); + particleSystem.addLimitVelocityGradient(pos, numVal); + } + } + } else if (typeof behavior.speed === "number" || (typeof behavior.speed === "object" && behavior.speed !== null && "type" in behavior.speed)) { + const speedLimit = parseConstantValue(behavior.speed); + particleSystem.addLimitVelocityGradient(0, speedLimit); + particleSystem.addLimitVelocityGradient(1, speedLimit); + } + } +} + +/** + * Apply LimitSpeedOverLife behavior to SolidParticleSystem + * Adds limit velocity gradients to the system (similar to ParticleSystem native gradients) + */ +export function applyLimitSpeedOverLifeSPS(system: EffectSolidParticleSystem, behavior: ILimitSpeedOverLifeBehavior): void { + if (behavior.dampen !== undefined) { + const dampen = parseConstantValue(behavior.dampen); + system.limitVelocityDamping = dampen; + } + + if (behavior.maxSpeed !== undefined) { + const speedLimit = parseConstantValue(behavior.maxSpeed); + system.addLimitVelocityGradient(0, speedLimit); + system.addLimitVelocityGradient(1, speedLimit); + } else if (behavior.speed !== undefined) { + if (typeof behavior.speed === "object" && behavior.speed !== null && "keys" in behavior.speed && behavior.speed.keys && Array.isArray(behavior.speed.keys)) { + for (const key of behavior.speed.keys) { + const pos = key.pos ?? key.time ?? 0; + const val = key.value; + if (val !== undefined && pos !== undefined) { + const numVal = extractNumberFromValue(val); + system.addLimitVelocityGradient(pos, numVal); + } + } + } else if (typeof behavior.speed === "number" || (typeof behavior.speed === "object" && behavior.speed !== null && "type" in behavior.speed)) { + const speedLimit = parseConstantValue(behavior.speed); + system.addLimitVelocityGradient(0, speedLimit); + system.addLimitVelocityGradient(1, speedLimit); + } + } +} diff --git a/tools/src/effect/behaviors/orbitOverLife.ts b/tools/src/effect/behaviors/orbitOverLife.ts new file mode 100644 index 000000000..6e3109220 --- /dev/null +++ b/tools/src/effect/behaviors/orbitOverLife.ts @@ -0,0 +1,107 @@ +import { Particle } from "@babylonjs/core/Particles/particle"; +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import type { IOrbitOverLifeBehavior, Value } from "../types"; +import { extractNumberFromValue, interpolateGradientKeys } from "./utils"; +import { parseConstantValue, parseIntervalValue } from "../utils"; + +/** + * Apply OrbitOverLife behavior to Particle + * Gets lifeRatio from particle (age / lifeTime) + */ +export function applyOrbitOverLifePS(particle: Particle, behavior: IOrbitOverLifeBehavior): void { + if (!behavior.radius || particle.lifeTime <= 0) { + return; + } + + // Get lifeRatio from particle + const lifeRatio = particle.age / particle.lifeTime; + + // Parse radius (can be Value with keys or constant/interval) + let radius = 1; + const radiusValue = behavior.radius; + + // Check if radius is an object with keys (gradient) + if ( + radiusValue !== undefined && + radiusValue !== null && + typeof radiusValue === "object" && + "keys" in radiusValue && + Array.isArray(radiusValue.keys) && + radiusValue.keys.length > 0 + ) { + radius = interpolateGradientKeys(radiusValue.keys, lifeRatio, extractNumberFromValue); + } else if (radiusValue !== undefined && radiusValue !== null) { + // Parse as Value (number, ConstantValue, or IntervalValue) + const parsedRadius = parseIntervalValue(radiusValue as Value); + radius = parsedRadius.min + (parsedRadius.max - parsedRadius.min) * lifeRatio; + } + + const speed = behavior.speed !== undefined ? parseConstantValue(behavior.speed) : 1; + const angle = lifeRatio * speed * Math.PI * 2; + + // Calculate orbit offset relative to center + const centerX = behavior.center?.x ?? 0; + const centerY = behavior.center?.y ?? 0; + const centerZ = behavior.center?.z ?? 0; + + const orbitX = Math.cos(angle) * radius; + const orbitY = Math.sin(angle) * radius; + const orbitZ = 0; // 2D orbit + + // Apply orbit offset to particle position + if (particle.position) { + particle.position.x = centerX + orbitX; + particle.position.y = centerY + orbitY; + particle.position.z = centerZ + orbitZ; + } +} + +/** + * Apply OrbitOverLife behavior to SolidParticle + * Gets lifeRatio from particle (age / lifeTime) + */ +export function applyOrbitOverLifeSPS(particle: SolidParticle, behavior: IOrbitOverLifeBehavior): void { + if (!behavior.radius || particle.lifeTime <= 0) { + return; + } + + // Get lifeRatio from particle + const lifeRatio = particle.age / particle.lifeTime; + + // Parse radius (can be Value with keys or constant/interval) + let radius = 1; + const radiusValue = behavior.radius; + + // Check if radius is an object with keys (gradient) + if ( + radiusValue !== undefined && + radiusValue !== null && + typeof radiusValue === "object" && + "keys" in radiusValue && + Array.isArray(radiusValue.keys) && + radiusValue.keys.length > 0 + ) { + radius = interpolateGradientKeys(radiusValue.keys, lifeRatio, extractNumberFromValue); + } else if (radiusValue !== undefined && radiusValue !== null) { + // Parse as Value (number, ConstantValue, or IntervalValue) + const parsedRadius = parseIntervalValue(radiusValue as Value); + radius = parsedRadius.min + (parsedRadius.max - parsedRadius.min) * lifeRatio; + } + + const speed = behavior.speed !== undefined ? parseConstantValue(behavior.speed) : 1; + const angle = lifeRatio * speed * Math.PI * 2; + + // Calculate orbit offset relative to center + const centerX = behavior.center?.x ?? 0; + const centerY = behavior.center?.y ?? 0; + const centerZ = behavior.center?.z ?? 0; + + const orbitX = Math.cos(angle) * radius; + const orbitY = Math.sin(angle) * radius; + const orbitZ = 0; // 2D orbit + + // Apply orbit offset to particle position + particle.position.x = centerX + orbitX; + particle.position.y = centerY + orbitY; + particle.position.z = centerZ + orbitZ; +} diff --git a/tools/src/effect/behaviors/rotationBySpeed.ts b/tools/src/effect/behaviors/rotationBySpeed.ts new file mode 100644 index 000000000..389a6c6d6 --- /dev/null +++ b/tools/src/effect/behaviors/rotationBySpeed.ts @@ -0,0 +1,81 @@ +import { Particle } from "@babylonjs/core/Particles/particle"; +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { extractNumberFromValue, interpolateGradientKeys } from "./utils"; +import { parseConstantValue, parseIntervalValue } from "../utils"; +import { ParticleWithSystem, SolidParticleWithSystem, type IRotationBySpeedBehavior } from "../types"; + +/** + * Apply RotationBySpeed behavior to Particle + * Gets currentSpeed from particle.direction magnitude and updateSpeed from system + */ +export function applyRotationBySpeedPS(particle: Particle, behavior: IRotationBySpeedBehavior): void { + if (!behavior.angularVelocity || !particle.direction) { + return; + } + + // Get current speed from particle velocity/direction + const currentSpeed = Vector3.Distance(Vector3.Zero(), particle.direction); + + // Get updateSpeed from system (stored in particle or use default) + const particleWithSystem = particle as ParticleWithSystem; + const updateSpeed = particleWithSystem.particleSystem?.updateSpeed ?? 0.016; + + // angularVelocity can be Value (constant/interval) or object with keys + let angularSpeed = 0; + if ( + typeof behavior.angularVelocity === "object" && + behavior.angularVelocity !== null && + "keys" in behavior.angularVelocity && + Array.isArray(behavior.angularVelocity.keys) && + behavior.angularVelocity.keys.length > 0 + ) { + const minSpeed = behavior.minSpeed !== undefined ? parseConstantValue(behavior.minSpeed) : 0; + const maxSpeed = behavior.maxSpeed !== undefined ? parseConstantValue(behavior.maxSpeed) : 1; + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + angularSpeed = interpolateGradientKeys(behavior.angularVelocity.keys, speedRatio, extractNumberFromValue); + } else { + const angularVel = parseIntervalValue(behavior.angularVelocity); + angularSpeed = angularVel.min + (angularVel.max - angularVel.min) * 0.5; // Use middle value + } + + particle.angle += angularSpeed * updateSpeed; +} + +/** + * Apply RotationBySpeed behavior to SolidParticle + * Gets currentSpeed from particle.velocity magnitude and updateSpeed from system + */ +export function applyRotationBySpeedSPS(particle: SolidParticle, behavior: IRotationBySpeedBehavior): void { + if (!behavior.angularVelocity) { + return; + } + + // Get current speed from particle velocity + const currentSpeed = Math.sqrt(particle.velocity.x * particle.velocity.x + particle.velocity.y * particle.velocity.y + particle.velocity.z * particle.velocity.z); + + // Get updateSpeed from system (stored in particle.props or use default) + const particleWithSystem = particle as SolidParticleWithSystem; + const updateSpeed = particleWithSystem.system?.updateSpeed ?? 0.016; + + // angularVelocity can be Value (constant/interval) or object with keys + let angularSpeed = 0; + if ( + typeof behavior.angularVelocity === "object" && + behavior.angularVelocity !== null && + "keys" in behavior.angularVelocity && + Array.isArray(behavior.angularVelocity.keys) && + behavior.angularVelocity.keys.length > 0 + ) { + const minSpeed = behavior.minSpeed !== undefined ? parseConstantValue(behavior.minSpeed) : 0; + const maxSpeed = behavior.maxSpeed !== undefined ? parseConstantValue(behavior.maxSpeed) : 1; + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + angularSpeed = interpolateGradientKeys(behavior.angularVelocity.keys, speedRatio, extractNumberFromValue); + } else { + const angularVel = parseIntervalValue(behavior.angularVelocity); + angularSpeed = angularVel.min + (angularVel.max - angularVel.min) * 0.5; // Use middle value + } + + // SolidParticle uses rotation.z for 2D rotation + particle.rotation.z += angularSpeed * updateSpeed; +} diff --git a/tools/src/effect/behaviors/rotationOverLife.ts b/tools/src/effect/behaviors/rotationOverLife.ts new file mode 100644 index 000000000..83141e121 --- /dev/null +++ b/tools/src/effect/behaviors/rotationOverLife.ts @@ -0,0 +1,107 @@ +import type { IRotationOverLifeBehavior } from "../types"; +import { parseIntervalValue } from "../utils"; +import { extractNumberFromValue } from "./utils"; +import type { EffectSolidParticleSystem, EffectParticleSystem } from "../systems"; +/** + * Apply RotationOverLife behavior to ParticleSystem + * Uses addAngularSpeedGradient for gradient support (Babylon.js native) + */ +export function applyRotationOverLifePS(particleSystem: EffectParticleSystem, behavior: IRotationOverLifeBehavior): void { + if (!behavior.angularVelocity) { + return; + } + + // Check if angularVelocity has gradient keys + if ( + typeof behavior.angularVelocity === "object" && + behavior.angularVelocity !== null && + "keys" in behavior.angularVelocity && + Array.isArray(behavior.angularVelocity.keys) && + behavior.angularVelocity.keys.length > 0 + ) { + // Use gradient for keys + for (const key of behavior.angularVelocity.keys) { + const pos = key.pos ?? key.time ?? 0; + const val = key.value; + if (val !== undefined && pos !== undefined) { + const numVal = extractNumberFromValue(val); + particleSystem.addAngularSpeedGradient(pos, numVal); + } + } + } else if ( + typeof behavior.angularVelocity === "object" && + behavior.angularVelocity !== null && + "functions" in behavior.angularVelocity && + Array.isArray(behavior.angularVelocity.functions) && + behavior.angularVelocity.functions.length > 0 + ) { + // Use gradient for functions + for (const func of behavior.angularVelocity.functions) { + if (func.function && func.start !== undefined) { + const startSpeed = func.function.p0 || 0; + const endSpeed = func.function.p3 !== undefined ? func.function.p3 : startSpeed; + particleSystem.addAngularSpeedGradient(func.start, startSpeed); + if (func.function.p3 !== undefined) { + particleSystem.addAngularSpeedGradient(Math.min(func.start + 0.5, 1), endSpeed); + } + } + } + } else { + // Fallback to interval (min/max) - use gradient with min at 0 and max at 1 + const angularVel = parseIntervalValue(behavior.angularVelocity); + particleSystem.addAngularSpeedGradient(0, angularVel.min); + particleSystem.addAngularSpeedGradient(1, angularVel.max); + } +} + +/** + * Apply RotationOverLife behavior to SolidParticleSystem + * Adds angular speed gradients to the system (similar to ParticleSystem native gradients) + */ +export function applyRotationOverLifeSPS(system: EffectSolidParticleSystem, behavior: IRotationOverLifeBehavior): void { + if (!behavior.angularVelocity) { + return; + } + + // Check if angularVelocity has gradient keys + if ( + typeof behavior.angularVelocity === "object" && + behavior.angularVelocity !== null && + "keys" in behavior.angularVelocity && + Array.isArray(behavior.angularVelocity.keys) && + behavior.angularVelocity.keys.length > 0 + ) { + // Use gradient for keys + for (const key of behavior.angularVelocity.keys) { + const pos = key.pos ?? key.time ?? 0; + const val = key.value; + if (val !== undefined && pos !== undefined) { + const numVal = extractNumberFromValue(val); + system.addAngularSpeedGradient(pos, numVal); + } + } + } else if ( + typeof behavior.angularVelocity === "object" && + behavior.angularVelocity !== null && + "functions" in behavior.angularVelocity && + Array.isArray(behavior.angularVelocity.functions) && + behavior.angularVelocity.functions.length > 0 + ) { + // Use gradient for functions + for (const func of behavior.angularVelocity.functions) { + if (func.function && func.start !== undefined) { + const startSpeed = func.function.p0 || 0; + const endSpeed = func.function.p3 !== undefined ? func.function.p3 : startSpeed; + system.addAngularSpeedGradient(func.start, startSpeed); + if (func.function.p3 !== undefined) { + system.addAngularSpeedGradient(Math.min(func.start + 0.5, 1), endSpeed); + } + } + } + } else { + // Fallback to interval (min/max) - use gradient with min at 0 and max at 1 + const angularVel = parseIntervalValue(behavior.angularVelocity); + system.addAngularSpeedGradient(0, angularVel.min); + system.addAngularSpeedGradient(1, angularVel.max); + } +} diff --git a/tools/src/effect/behaviors/sizeBySpeed.ts b/tools/src/effect/behaviors/sizeBySpeed.ts new file mode 100644 index 000000000..a3fcf47db --- /dev/null +++ b/tools/src/effect/behaviors/sizeBySpeed.ts @@ -0,0 +1,51 @@ +import { Particle } from "@babylonjs/core/Particles/particle"; +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import type { ISizeBySpeedBehavior } from "../types"; +import { extractNumberFromValue, interpolateGradientKeys } from "./utils"; +import { parseConstantValue } from "../utils"; + +/** + * Apply SizeBySpeed behavior to Particle + * Gets currentSpeed from particle.direction magnitude + */ +export function applySizeBySpeedPS(particle: Particle, behavior: ISizeBySpeedBehavior): void { + if (!behavior.size || !behavior.size.keys || !particle.direction) { + return; + } + + // Get current speed from particle velocity/direction + const currentSpeed = Vector3.Distance(Vector3.Zero(), particle.direction); + + const sizeKeys = behavior.size.keys; + const minSpeed = behavior.minSpeed !== undefined ? parseConstantValue(behavior.minSpeed) : 0; + const maxSpeed = behavior.maxSpeed !== undefined ? parseConstantValue(behavior.maxSpeed) : 1; + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + + const sizeMultiplier = interpolateGradientKeys(sizeKeys, speedRatio, extractNumberFromValue); + const startSize = particle.size || 1; + particle.size = startSize * sizeMultiplier; +} + +/** + * Apply SizeBySpeed behavior to SolidParticle + * Gets currentSpeed from particle.velocity magnitude + */ +export function applySizeBySpeedSPS(particle: SolidParticle, behavior: ISizeBySpeedBehavior): void { + if (!behavior.size || !behavior.size.keys) { + return; + } + + // Get current speed from particle velocity + const currentSpeed = Math.sqrt(particle.velocity.x * particle.velocity.x + particle.velocity.y * particle.velocity.y + particle.velocity.z * particle.velocity.z); + + const sizeKeys = behavior.size.keys; + const minSpeed = behavior.minSpeed !== undefined ? parseConstantValue(behavior.minSpeed) : 0; + const maxSpeed = behavior.maxSpeed !== undefined ? parseConstantValue(behavior.maxSpeed) : 1; + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + + const sizeMultiplier = interpolateGradientKeys(sizeKeys, speedRatio, extractNumberFromValue); + const startSize = particle.props?.startSize ?? 1; + const newSize = startSize * sizeMultiplier; + particle.scaling.setAll(newSize); +} diff --git a/tools/src/effect/behaviors/sizeOverLife.ts b/tools/src/effect/behaviors/sizeOverLife.ts new file mode 100644 index 000000000..c6e9b6891 --- /dev/null +++ b/tools/src/effect/behaviors/sizeOverLife.ts @@ -0,0 +1,66 @@ +import type { ISizeOverLifeBehavior } from "../types"; +import { extractNumberFromValue } from "./utils"; +import type { EffectSolidParticleSystem, EffectParticleSystem } from "../systems"; +/** + * Apply SizeOverLife behavior to ParticleSystem + * In Quarks, SizeOverLife values are multipliers relative to initial particle size + * In Babylon.js, sizeGradients are absolute values, so we multiply by average initial size + */ +export function applySizeOverLifePS(particleSystem: EffectParticleSystem, behavior: ISizeOverLifeBehavior): void { + // Get average initial size from minSize/maxSize to use as base for multipliers + const avgInitialSize = (particleSystem.minSize + particleSystem.maxSize) / 2; + + if (behavior.size && behavior.size.functions) { + const functions = behavior.size.functions; + for (const func of functions) { + if (func.function && func.start !== undefined) { + // Values from Quarks are multipliers, convert to absolute values + const startSizeMultiplier = func.function.p0 || 1; + const endSizeMultiplier = func.function.p3 !== undefined ? func.function.p3 : startSizeMultiplier; + particleSystem.addSizeGradient(func.start, startSizeMultiplier * avgInitialSize); + if (func.function.p3 !== undefined) { + particleSystem.addSizeGradient(func.start + 0.5, endSizeMultiplier * avgInitialSize); + } + } + } + } else if (behavior.size && behavior.size.keys) { + for (const key of behavior.size.keys) { + if (key.value !== undefined && key.pos !== undefined) { + // Values from Quarks are multipliers, convert to absolute values + const sizeMultiplier = extractNumberFromValue(key.value); + particleSystem.addSizeGradient(key.pos, sizeMultiplier * avgInitialSize); + } + } + } +} + +/** + * Apply SizeOverLife behavior to SolidParticleSystem + * Adds size gradients to the system (similar to ParticleSystem native gradients) + */ +export function applySizeOverLifeSPS(system: EffectSolidParticleSystem, behavior: ISizeOverLifeBehavior): void { + if (!behavior.size) { + return; + } + + if (behavior.size.functions) { + const functions = behavior.size.functions; + for (const func of functions) { + if (func.function && func.start !== undefined) { + const startSize = func.function.p0 || 1; + const endSize = func.function.p3 !== undefined ? func.function.p3 : startSize; + system.addSizeGradient(func.start, startSize); + if (func.function.p3 !== undefined) { + system.addSizeGradient(Math.min(func.start + 0.5, 1), endSize); + } + } + } + } else if (behavior.size.keys) { + for (const key of behavior.size.keys) { + if (key.value !== undefined && key.pos !== undefined) { + const size = extractNumberFromValue(key.value); + system.addSizeGradient(key.pos, size); + } + } + } +} diff --git a/tools/src/effect/behaviors/speedOverLife.ts b/tools/src/effect/behaviors/speedOverLife.ts new file mode 100644 index 000000000..8450937e2 --- /dev/null +++ b/tools/src/effect/behaviors/speedOverLife.ts @@ -0,0 +1,84 @@ +import type { ISpeedOverLifeBehavior } from "../types"; +import { extractNumberFromValue } from "./utils"; +import { parseIntervalValue } from "../utils"; +import type { EffectSolidParticleSystem, EffectParticleSystem } from "../systems"; +/** + * Apply SpeedOverLife behavior to ParticleSystem + */ +export function applySpeedOverLifePS(particleSystem: EffectParticleSystem, behavior: ISpeedOverLifeBehavior): void { + if (behavior.speed) { + if (typeof behavior.speed === "object" && behavior.speed !== null && "keys" in behavior.speed && behavior.speed.keys && Array.isArray(behavior.speed.keys)) { + for (const key of behavior.speed.keys) { + const pos = key.pos ?? key.time ?? 0; + const val = key.value; + if (val !== undefined && pos !== undefined) { + const numVal = extractNumberFromValue(val); + particleSystem.addVelocityGradient(pos, numVal); + } + } + } else if ( + typeof behavior.speed === "object" && + behavior.speed !== null && + "functions" in behavior.speed && + behavior.speed.functions && + Array.isArray(behavior.speed.functions) + ) { + for (const func of behavior.speed.functions) { + if (func.function && func.start !== undefined) { + const startSpeed = func.function.p0 || 1; + const endSpeed = func.function.p3 !== undefined ? func.function.p3 : startSpeed; + particleSystem.addVelocityGradient(func.start, startSpeed); + if (func.function.p3 !== undefined) { + particleSystem.addVelocityGradient(Math.min(func.start + 0.5, 1), endSpeed); + } + } + } + } else if (typeof behavior.speed === "number" || (typeof behavior.speed === "object" && behavior.speed !== null && "type" in behavior.speed)) { + const speedValue = parseIntervalValue(behavior.speed); + particleSystem.addVelocityGradient(0, speedValue.min); + particleSystem.addVelocityGradient(1, speedValue.max); + } + } +} + +/** + * Apply SpeedOverLife behavior to SolidParticleSystem + * Adds velocity gradients to the system (similar to ParticleSystem native gradients) + */ +export function applySpeedOverLifeSPS(system: EffectSolidParticleSystem, behavior: ISpeedOverLifeBehavior): void { + if (!behavior.speed) { + return; + } + + if (typeof behavior.speed === "object" && behavior.speed !== null && "keys" in behavior.speed && behavior.speed.keys && Array.isArray(behavior.speed.keys)) { + for (const key of behavior.speed.keys) { + const pos = key.pos ?? key.time ?? 0; + const val = key.value; + if (val !== undefined && pos !== undefined) { + const numVal = extractNumberFromValue(val); + system.addVelocityGradient(pos, numVal); + } + } + } else if ( + typeof behavior.speed === "object" && + behavior.speed !== null && + "functions" in behavior.speed && + behavior.speed.functions && + Array.isArray(behavior.speed.functions) + ) { + for (const func of behavior.speed.functions) { + if (func.function && func.start !== undefined) { + const startSpeed = func.function.p0 || 1; + const endSpeed = func.function.p3 !== undefined ? func.function.p3 : startSpeed; + system.addVelocityGradient(func.start, startSpeed); + if (func.function.p3 !== undefined) { + system.addVelocityGradient(Math.min(func.start + 0.5, 1), endSpeed); + } + } + } + } else if (typeof behavior.speed === "number" || (typeof behavior.speed === "object" && behavior.speed !== null && "type" in behavior.speed)) { + const speedValue = parseIntervalValue(behavior.speed); + system.addVelocityGradient(0, speedValue.min); + system.addVelocityGradient(1, speedValue.max); + } +} diff --git a/tools/src/effect/behaviors/utils.ts b/tools/src/effect/behaviors/utils.ts new file mode 100644 index 000000000..f7afcac4c --- /dev/null +++ b/tools/src/effect/behaviors/utils.ts @@ -0,0 +1,165 @@ +import type { IGradientKey } from "../types"; + +/** + * Extract RGB color from gradient key value + */ +export function extractColorFromValue(value: number | number[] | { r: number; g: number; b: number; a?: number } | undefined): { r: number; g: number; b: number } { + if (value === undefined) { + return { r: 1, g: 1, b: 1 }; + } + + if (typeof value === "number") { + return { r: value, g: value, b: value }; + } + + if (Array.isArray(value)) { + return { + r: value[0] || 0, + g: value[1] || 0, + b: value[2] || 0, + }; + } + + if (typeof value === "object" && "r" in value) { + return { + r: value.r || 0, + g: value.g || 0, + b: value.b || 0, + }; + } + + return { r: 1, g: 1, b: 1 }; +} + +/** + * Extract alpha from gradient key value + */ +export function extractAlphaFromValue(value: number | number[] | { r: number; g: number; b: number; a?: number } | undefined): number { + if (value === undefined) { + return 1; + } + + if (typeof value === "number") { + return value; + } + + if (Array.isArray(value)) { + return value[3] !== undefined ? value[3] : 1; + } + + if (typeof value === "object" && "a" in value) { + return value.a !== undefined ? value.a : 1; + } + + return 1; +} + +/** + * Extract number from gradient key value + */ +export function extractNumberFromValue(value: number | number[] | { r: number; g: number; b: number; a?: number } | undefined): number { + if (value === undefined) { + return 1; + } + + if (typeof value === "number") { + return value; + } + + if (Array.isArray(value)) { + return value[0] || 0; + } + + return 1; +} + +/** + * Interpolate between two gradient keys + */ +export function interpolateGradientKeys( + keys: IGradientKey[], + ratio: number, + extractValue: (value: number | number[] | { r: number; g: number; b: number; a?: number } | undefined) => number +): number { + if (!keys || keys.length === 0) { + return 1; + } + + if (keys.length === 1) { + return extractValue(keys[0].value); + } + + // Find the two keys to interpolate between + for (let i = 0; i < keys.length - 1; i++) { + const pos1 = keys[i].pos ?? keys[i].time ?? 0; + const pos2 = keys[i + 1].pos ?? keys[i + 1].time ?? 1; + + if (ratio >= pos1 && ratio <= pos2) { + const t = pos2 - pos1 !== 0 ? (ratio - pos1) / (pos2 - pos1) : 0; + const val1 = extractValue(keys[i].value); + const val2 = extractValue(keys[i + 1].value); + return val1 + (val2 - val1) * t; + } + } + + // Clamp to first or last key + if (ratio <= (keys[0].pos ?? keys[0].time ?? 0)) { + return extractValue(keys[0].value); + } + return extractValue(keys[keys.length - 1].value); +} + +/** + * Interpolate color between two gradient keys + */ +export function interpolateColorKeys(keys: IGradientKey[], ratio: number): { r: number; g: number; b: number; a: number } { + if (!keys || keys.length === 0) { + return { r: 1, g: 1, b: 1, a: 1 }; + } + + if (keys.length === 1) { + const val = keys[0].value; + return { + ...extractColorFromValue(val), + a: extractAlphaFromValue(val), + }; + } + + // Find the two keys to interpolate between + for (let i = 0; i < keys.length - 1; i++) { + const pos1 = keys[i].pos ?? keys[i].time ?? 0; + const pos2 = keys[i + 1].pos ?? keys[i + 1].time ?? 1; + + if (ratio >= pos1 && ratio <= pos2) { + const t = pos2 - pos1 !== 0 ? (ratio - pos1) / (pos2 - pos1) : 0; + const val1 = keys[i].value; + const val2 = keys[i + 1].value; + + const c1 = extractColorFromValue(val1); + const c2 = extractColorFromValue(val2); + const a1 = extractAlphaFromValue(val1); + const a2 = extractAlphaFromValue(val2); + + return { + r: c1.r + (c2.r - c1.r) * t, + g: c1.g + (c2.g - c1.g) * t, + b: c1.b + (c2.b - c1.b) * t, + a: a1 + (a2 - a1) * t, + }; + } + } + + // Clamp to first or last key + if (ratio <= (keys[0].pos ?? keys[0].time ?? 0)) { + const val = keys[0].value; + return { + ...extractColorFromValue(val), + a: extractAlphaFromValue(val), + }; + } + const val = keys[keys.length - 1].value; + return { + ...extractColorFromValue(val), + a: extractAlphaFromValue(val), + }; +} diff --git a/tools/src/effect/effect.ts b/tools/src/effect/effect.ts new file mode 100644 index 000000000..bafb0f776 --- /dev/null +++ b/tools/src/effect/effect.ts @@ -0,0 +1,476 @@ +import { IDisposable, Scene } from "@babylonjs/core/scene"; +import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; +import { EffectParticleSystem, EffectSolidParticleSystem } from "./systems"; +import { IData, IEffectNode, IParticleSystemConfig } from "./types"; +import { NodeFactory } from "./factories"; + +/** + * Effect containing multiple particle systems with hierarchy support + * Main entry point for loading and creating from Three.js particle JSON files + */ +export class Effect implements IDisposable { + /** Root node of the effect hierarchy */ + private _root: IEffectNode | null = null; + + /** + * Get root node of the effect hierarchy + */ + public get root(): IEffectNode | null { + return this._root; + } + + /** NodeFactory for creating groups and systems */ + private _nodeFactory: NodeFactory | null = null; + + /** + * Create Effect from IData + * + * + * @param data IData structure (required) + * @param scene Babylon.js scene (required) + * @param rootUrl Root URL for loading textures (optional) + */ + constructor(data: IData, scene: Scene, rootUrl: string = "") { + if (!data || !scene) { + throw new Error("Effect constructor requires IData and Scene"); + } + + this._nodeFactory = new NodeFactory(scene, data, rootUrl); + this._root = this._nodeFactory.create(); + } + + /** + * Recursively find a node by name in the tree + */ + private _findNodeByName(node: IEffectNode | null, name: string): IEffectNode | null { + if (!node) { + return null; + } + if (node.name === name) { + return node; + } + for (const child of node.children) { + const found = this._findNodeByName(child, name); + if (found) { + return found; + } + } + return null; + } + + /** + * Recursively find a node by UUID in the tree + */ + private _findNodeByUuid(node: IEffectNode | null, uuid: string): IEffectNode | null { + if (!node) { + return null; + } + if (node.uuid === uuid) { + return node; + } + for (const child of node.children) { + const found = this._findNodeByUuid(child, uuid); + if (found) { + return found; + } + } + return null; + } + + /** + * Recursively collect all systems from the tree + */ + private _collectAllSystems(node: IEffectNode | null, systems: (EffectParticleSystem | EffectSolidParticleSystem)[]): void { + if (!node) { + return; + } + if (node.type === "particle") { + const system = node.data as EffectParticleSystem | EffectSolidParticleSystem; + if (system) { + systems.push(system); + } + } + for (const child of node.children) { + this._collectAllSystems(child, systems); + } + } + + /** + * Find a particle system by name + */ + public findSystemByName(name: string): EffectParticleSystem | EffectSolidParticleSystem | null { + const node = this._findNodeByName(this._root, name); + if (node && node.type === "particle") { + return node.data as EffectParticleSystem | EffectSolidParticleSystem; + } + return null; + } + + /** + * Find a particle system by UUID + */ + public findSystemByUuid(uuid: string): EffectParticleSystem | EffectSolidParticleSystem | null { + const node = this._findNodeByUuid(this._root, uuid); + if (node && node.type === "particle") { + return node.data as EffectParticleSystem | EffectSolidParticleSystem; + } + return null; + } + + /** + * Find a group by name + */ + public findGroupByName(name: string): TransformNode | null { + const node = this._findNodeByName(this._root, name); + if (node && node.type === "group") { + return node.data as TransformNode; + } + return null; + } + + /** + * Find a group by UUID + */ + public findGroupByUuid(uuid: string): TransformNode | null { + const node = this._findNodeByUuid(this._root, uuid); + if (node && node.type === "group") { + return node.data as TransformNode; + } + return null; + } + + /** + * Find a node (system or group) by name + */ + public findNodeByName(name: string): IEffectNode | null { + return this._findNodeByName(this._root, name); + } + + /** + * Find a node (system or group) by UUID + */ + public findNodeByUuid(uuid: string): IEffectNode | null { + return this._findNodeByUuid(this._root, uuid); + } + + /** + * Get all systems in a group (recursively) + * Includes systems from nested child groups as well. + * Example: If Group1 contains Group2, and Group2 contains System1, + * then getSystemsInGroup("Group1") will return System1. + */ + public getSystemsInGroup(groupName: string): (EffectParticleSystem | EffectSolidParticleSystem)[] { + const groupNode = this.findNodeByName(groupName); + if (!groupNode || groupNode.type !== "group") { + return []; + } + + const systems: (EffectParticleSystem | EffectSolidParticleSystem)[] = []; + this._collectSystemsInGroupNode(groupNode, systems); + return systems; + } + + /** + * Recursively collect systems in a group node (including systems from all nested child groups) + */ + private _collectSystemsInGroupNode(groupNode: IEffectNode, systems: (EffectParticleSystem | EffectSolidParticleSystem)[]): void { + if (groupNode.type === "particle") { + const system = groupNode.data as EffectParticleSystem | EffectSolidParticleSystem; + if (system) { + systems.push(system); + } + } + for (const child of groupNode.children) { + this._collectSystemsInGroupNode(child, systems); + } + } + + /** + * Start a specific system by name + */ + public startSystem(name: string): boolean { + const system = this.findSystemByName(name); + if (system) { + system.start(); + return true; + } + return false; + } + + /** + * Stop a specific system by name + */ + public stopSystem(name: string): boolean { + const system = this.findSystemByName(name); + if (system) { + system.stop(); + return true; + } + return false; + } + + /** + * Start all systems in a group + */ + public startGroup(groupName: string): void { + const systems = this.getSystemsInGroup(groupName); + for (const system of systems) { + system.start(); + } + } + + /** + * Stop all systems in a group + */ + public stopGroup(groupName: string): void { + const systems = this.getSystemsInGroup(groupName); + for (const system of systems) { + system.stop(); + } + } + + /** + * Start a node (system or group) + */ + public startNode(node: IEffectNode): void { + if (node.type === "particle") { + const system = node.data as EffectParticleSystem | EffectSolidParticleSystem; + if (system && typeof system.start === "function") { + system.start(); + } + } else if (node.type === "group") { + // Find all systems in this group recursively + const systems = this._getSystemsInNode(node); + for (const system of systems) { + system.start(); + } + } + } + + /** + * Stop a node (system or group) + */ + public stopNode(node: IEffectNode): void { + if (node.type === "particle") { + const system = node.data as EffectParticleSystem | EffectSolidParticleSystem; + if (system && typeof system.stop === "function") { + system.stop(); + } + } else if (node.type === "group") { + // Find all systems in this group recursively + const systems = this._getSystemsInNode(node); + for (const system of systems) { + system.stop(); + } + } + } + + /** + * Reset a node (system or group) + */ + public resetNode(node: IEffectNode): void { + if (node.type === "particle") { + const system = node.data as EffectParticleSystem | EffectSolidParticleSystem; + if (system && typeof system.reset === "function") { + system.reset(); + } + } else if (node.type === "group") { + // Find all systems in this group recursively + const systems = this._getSystemsInNode(node); + for (const system of systems) { + system.reset(); + } + } + } + + /** + * Check if a node is started (system or group) + */ + public isNodeStarted(node: IEffectNode): boolean { + if (node.type === "particle") { + const system = node.data as EffectParticleSystem | EffectSolidParticleSystem; + if (system instanceof EffectParticleSystem) { + return (system as any).isStarted ? (system as any).isStarted() : false; + } else if (system instanceof EffectSolidParticleSystem) { + return (system as any)._started && !(system as any)._stopped; + } + return false; + } else if (node.type === "group") { + // Check if any system in this group is started + const systems = this._getSystemsInNode(node); + return systems.some((system) => { + if (system instanceof EffectParticleSystem) { + return (system as any).isStarted ? (system as any).isStarted() : false; + } else if (system instanceof EffectSolidParticleSystem) { + return (system as any)._started && !(system as any)._stopped; + } + return false; + }); + } + return false; + } + + /** + * Get all systems in a node recursively + */ + private _getSystemsInNode(node: IEffectNode): (EffectParticleSystem | EffectSolidParticleSystem)[] { + const systems: (EffectParticleSystem | EffectSolidParticleSystem)[] = []; + + if (node.type === "particle") { + const system = node.data as EffectParticleSystem | EffectSolidParticleSystem; + if (system) { + systems.push(system); + } + } else if (node.type === "group") { + // Recursively collect all systems from children + for (const child of node.children) { + systems.push(...this._getSystemsInNode(child)); + } + } + + return systems; + } + + /** + * Start all particle systems + */ + public start(): void { + const systems: (EffectParticleSystem | EffectSolidParticleSystem)[] = []; + this._collectAllSystems(this._root, systems); + for (const system of systems) { + system.start(); + } + } + + /** + * Stop all particle systems + */ + public stop(): void { + const systems: (EffectParticleSystem | EffectSolidParticleSystem)[] = []; + this._collectAllSystems(this._root, systems); + for (const system of systems) { + system.stop(); + } + } + + /** + * Reset all particle systems (stop and clear particles) + */ + public reset(): void { + const systems: (EffectParticleSystem | EffectSolidParticleSystem)[] = []; + this._collectAllSystems(this._root, systems); + for (const system of systems) { + system.reset(); + } + } + + /** + * Check if any system is started + */ + public isStarted(): boolean { + const systems: (EffectParticleSystem | EffectSolidParticleSystem)[] = []; + this._collectAllSystems(this._root, systems); + for (const system of systems) { + if (system instanceof EffectParticleSystem) { + if ((system as any).isStarted && (system as any).isStarted()) { + return true; + } + } else if (system instanceof EffectSolidParticleSystem) { + // Check internal _started flag for SPS + if ((system as any)._started && !(system as any)._stopped) { + return true; + } + } + } + return false; + } + + /** + * Create a new group node + * @param parentNode Parent node (if null, adds to root) + * @param name Optional name (defaults to "Group") + * @returns Created group node + */ + public createGroup(parentNode: IEffectNode | null = null, name: string = "Group"): IEffectNode | null { + if (!this._nodeFactory) { + console.error("Cannot create group: NodeFactory is not available"); + return null; + } + + const parent = parentNode || this._root; + if (!parent || parent.type !== "group") { + console.error("Cannot create group: parent is not a group"); + return null; + } + + // Ensure unique name + let uniqueName = name; + let counter = 1; + while (this._findNodeByName(this._root, uniqueName)) { + uniqueName = `${name} ${counter}`; + counter++; + } + + // Create group using NodeFactory + const newNode = this._nodeFactory.createGroup(uniqueName, parent); + + // Add to parent's children + parent.children.push(newNode); + + return newNode; + } + + /** + * Create a new particle system + * @param parentNode Parent node (if null, adds to root) + * @param systemType Type of system ("solid" or "base") + * @param name Optional name (defaults to "ParticleSystem") + * @param config Optional particle system config + * @returns Created particle system node + */ + public createParticleSystem( + parentNode: IEffectNode | null = null, + systemType: "solid" | "base" = "base", + name: string = "ParticleSystem", + config?: Partial + ): IEffectNode | null { + if (!this._nodeFactory) { + console.error("Cannot create particle system: NodeFactory is not available"); + return null; + } + + const parent = parentNode || this._root; + if (!parent || parent.type !== "group") { + console.error("Cannot create particle system: parent is not a group"); + return null; + } + + // Ensure unique name + let uniqueName = name; + let counter = 1; + while (this._findNodeByName(this._root, uniqueName)) { + uniqueName = `${name} ${counter}`; + counter++; + } + + // Create particle system using NodeFactory + const newNode = this._nodeFactory.createParticleSystem(uniqueName, systemType, config, parent); + + // Add to parent's children + parent.children.push(newNode); + + return newNode; + } + + /** + * Dispose all resources + */ + public dispose(): void { + const systems: (EffectParticleSystem | EffectSolidParticleSystem)[] = []; + this._collectAllSystems(this._root, systems); + for (const system of systems) { + system.dispose(); + } + this._root = null; + } +} diff --git a/tools/src/effect/emitters/index.ts b/tools/src/effect/emitters/index.ts new file mode 100644 index 000000000..2c35fc332 --- /dev/null +++ b/tools/src/effect/emitters/index.ts @@ -0,0 +1,6 @@ +export { SolidPointParticleEmitter } from "./solidPointEmitter"; +export { SolidSphereParticleEmitter } from "./solidSphereEmitter"; +export { SolidConeParticleEmitter } from "./solidConeEmitter"; +export { SolidBoxParticleEmitter } from "./solidBoxEmitter"; +export { SolidHemisphericParticleEmitter } from "./solidHemisphericEmitter"; +export { SolidCylinderParticleEmitter } from "./solidCylinderEmitter"; diff --git a/tools/src/effect/emitters/solidBoxEmitter.ts b/tools/src/effect/emitters/solidBoxEmitter.ts new file mode 100644 index 000000000..3fedcc5c2 --- /dev/null +++ b/tools/src/effect/emitters/solidBoxEmitter.ts @@ -0,0 +1,70 @@ +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { ISolidParticleEmitterType } from "../types"; + +/** + * Box emitter for SolidParticleSystem + * Emits particles from inside a box with random direction between direction1 and direction2 + */ +export class SolidBoxParticleEmitter implements ISolidParticleEmitterType { + /** + * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors. + */ + public direction1: Vector3 = new Vector3(0, 1, 0); + + /** + * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors. + */ + public direction2: Vector3 = new Vector3(0, 1, 0); + + /** + * Minimum box point around the emitter center. + */ + public minEmitBox: Vector3 = new Vector3(-0.5, -0.5, -0.5); + + /** + * Maximum box point around the emitter center. + */ + public maxEmitBox: Vector3 = new Vector3(0.5, 0.5, 0.5); + + constructor(direction1?: Vector3, direction2?: Vector3, minEmitBox?: Vector3, maxEmitBox?: Vector3) { + if (direction1) { + this.direction1 = direction1; + } + if (direction2) { + this.direction2 = direction2; + } + if (minEmitBox) { + this.minEmitBox = minEmitBox; + } + if (maxEmitBox) { + this.maxEmitBox = maxEmitBox; + } + } + + /** + * Random range helper + */ + private _randomRange(min: number, max: number): number { + return min + Math.random() * (max - min); + } + + /** + * Initialize particle position and velocity + * Note: Direction is NOT normalized, matching ParticleSystem behavior. + * The direction vector magnitude affects final velocity. + */ + public initializeParticle(particle: SolidParticle, startSpeed: number): void { + // Random position within the box + const randX = this._randomRange(this.minEmitBox.x, this.maxEmitBox.x); + const randY = this._randomRange(this.minEmitBox.y, this.maxEmitBox.y); + const randZ = this._randomRange(this.minEmitBox.z, this.maxEmitBox.z); + particle.position.set(randX, randY, randZ); + + // Random direction between direction1 and direction2 (NOT normalized, like ParticleSystem) + const dirX = this._randomRange(this.direction1.x, this.direction2.x); + const dirY = this._randomRange(this.direction1.y, this.direction2.y); + const dirZ = this._randomRange(this.direction1.z, this.direction2.z); + particle.velocity.set(dirX * startSpeed, dirY * startSpeed, dirZ * startSpeed); + } +} diff --git a/tools/src/effect/emitters/solidConeEmitter.ts b/tools/src/effect/emitters/solidConeEmitter.ts new file mode 100644 index 000000000..18d4b1ff9 --- /dev/null +++ b/tools/src/effect/emitters/solidConeEmitter.ts @@ -0,0 +1,35 @@ +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { ISolidParticleEmitterType } from "../types"; + +/** + * Cone emitter for SolidParticleSystem + */ +export class SolidConeParticleEmitter implements ISolidParticleEmitterType { + public radius: number; + public arc: number; + public thickness: number; + public angle: number; + + constructor(radius: number = 1, arc: number = Math.PI * 2, thickness: number = 1, angle: number = Math.PI / 6) { + this.radius = radius; + this.arc = arc; + this.thickness = thickness; + this.angle = angle; + } + + public initializeParticle(particle: SolidParticle, startSpeed: number): void { + const u = Math.random(); + const rand = 1 - this.thickness + Math.random() * this.thickness; + const theta = u * this.arc; + const r = Math.sqrt(rand); + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + + particle.position.set(r * cosTheta, r * sinTheta, 0); + const coneAngle = this.angle * r; + particle.velocity.set(0, 0, Math.cos(coneAngle)); + particle.velocity.addInPlace(particle.position.scale(Math.sin(coneAngle))); + particle.velocity.scaleInPlace(startSpeed); + particle.position.scaleInPlace(this.radius); + } +} diff --git a/tools/src/effect/emitters/solidCylinderEmitter.ts b/tools/src/effect/emitters/solidCylinderEmitter.ts new file mode 100644 index 000000000..c024ad5eb --- /dev/null +++ b/tools/src/effect/emitters/solidCylinderEmitter.ts @@ -0,0 +1,79 @@ +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { ISolidParticleEmitterType } from "../types"; + +/** + * Cylinder emitter for SolidParticleSystem + * Emits particles from inside a cylinder + */ +export class SolidCylinderParticleEmitter implements ISolidParticleEmitterType { + /** + * The radius of the emission cylinder + */ + public radius: number; + + /** + * The height of the emission cylinder + */ + public height: number; + + /** + * The range of emission [0-1] 0 Surface only, 1 Entire Radius + */ + public radiusRange: number; + + /** + * How much to randomize the particle direction [0-1] + */ + public directionRandomizer: number; + + private _tempVector: Vector3 = Vector3.Zero(); + + constructor(radius: number = 1, height: number = 1, radiusRange: number = 1, directionRandomizer: number = 0) { + this.radius = radius; + this.height = height; + this.radiusRange = radiusRange; + this.directionRandomizer = directionRandomizer; + } + + /** + * Random range helper + */ + private _randomRange(min: number, max: number): number { + return min + Math.random() * (max - min); + } + + /** + * Initialize particle position and velocity + */ + public initializeParticle(particle: SolidParticle, startSpeed: number): void { + // Random height position + const yPos = this._randomRange(-this.height / 2, this.height / 2); + + // Random angle around cylinder + const angle = this._randomRange(0, 2 * Math.PI); + + // Pick a properly distributed point within the circle + // https://programming.guide/random-point-within-circle.html + const radiusDistribution = this._randomRange((1 - this.radiusRange) * (1 - this.radiusRange), 1); + const positionRadius = Math.sqrt(radiusDistribution) * this.radius; + + const xPos = positionRadius * Math.cos(angle); + const zPos = positionRadius * Math.sin(angle); + + particle.position.set(xPos, yPos, zPos); + + // Direction is outward from cylinder axis with randomization + this._tempVector.set(xPos, 0, zPos); + this._tempVector.normalize(); + + // Apply direction randomization + const randY = this._randomRange(-this.directionRandomizer / 2, this.directionRandomizer / 2); + let dirAngle = Math.atan2(this._tempVector.x, this._tempVector.z); + dirAngle += this._randomRange(-Math.PI / 2, Math.PI / 2) * this.directionRandomizer; + + particle.velocity.set(Math.sin(dirAngle), randY, Math.cos(dirAngle)); + particle.velocity.normalize(); + particle.velocity.scaleInPlace(startSpeed); + } +} diff --git a/tools/src/effect/emitters/solidHemisphericEmitter.ts b/tools/src/effect/emitters/solidHemisphericEmitter.ts new file mode 100644 index 000000000..5c74d16f1 --- /dev/null +++ b/tools/src/effect/emitters/solidHemisphericEmitter.ts @@ -0,0 +1,68 @@ +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { ISolidParticleEmitterType } from "../types"; + +/** + * Hemispheric emitter for SolidParticleSystem + * Emits particles from the inside of a hemisphere (upper half of a sphere) + */ +export class SolidHemisphericParticleEmitter implements ISolidParticleEmitterType { + /** + * The radius of the emission hemisphere + */ + public radius: number; + + /** + * The range of emission [0-1] 0 Surface only, 1 Entire Radius + */ + public radiusRange: number; + + /** + * How much to randomize the particle direction [0-1] + */ + public directionRandomizer: number; + + constructor(radius: number = 1, radiusRange: number = 1, directionRandomizer: number = 0) { + this.radius = radius; + this.radiusRange = radiusRange; + this.directionRandomizer = directionRandomizer; + } + + /** + * Random range helper + */ + private _randomRange(min: number, max: number): number { + return min + Math.random() * (max - min); + } + + /** + * Initialize particle position and velocity + */ + public initializeParticle(particle: SolidParticle, startSpeed: number): void { + // Calculate random position within hemisphere + const randRadius = this.radius - this._randomRange(0, this.radius * this.radiusRange); + const v = Math.random(); + const phi = this._randomRange(0, 2 * Math.PI); + const theta = Math.acos(2 * v - 1); + + const x = randRadius * Math.cos(phi) * Math.sin(theta); + const y = randRadius * Math.cos(theta); + const z = randRadius * Math.sin(phi) * Math.sin(theta); + + // Use absolute y to keep particles in upper hemisphere + particle.position.set(x, Math.abs(y), z); + + // Direction is outward from center with optional randomization + particle.velocity.copyFrom(particle.position); + particle.velocity.normalize(); + + // Apply direction randomization + if (this.directionRandomizer > 0) { + particle.velocity.x += this._randomRange(0, this.directionRandomizer); + particle.velocity.y += this._randomRange(0, this.directionRandomizer); + particle.velocity.z += this._randomRange(0, this.directionRandomizer); + particle.velocity.normalize(); + } + + particle.velocity.scaleInPlace(startSpeed); + } +} diff --git a/tools/src/effect/emitters/solidPointEmitter.ts b/tools/src/effect/emitters/solidPointEmitter.ts new file mode 100644 index 000000000..c03402663 --- /dev/null +++ b/tools/src/effect/emitters/solidPointEmitter.ts @@ -0,0 +1,17 @@ +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { ISolidParticleEmitterType } from "../types"; + +/** + * Point emitter for SolidParticleSystem + */ +export class SolidPointParticleEmitter implements ISolidParticleEmitterType { + public initializeParticle(particle: SolidParticle, startSpeed: number): void { + const theta = Math.random() * Math.PI * 2; + const phi = Math.acos(2.0 * Math.random() - 1.0); + const direction = new Vector3(Math.sin(phi) * Math.cos(theta), Math.sin(phi) * Math.sin(theta), Math.cos(phi)); + particle.position.setAll(0); + particle.velocity.copyFrom(direction); + particle.velocity.scaleInPlace(startSpeed); + } +} diff --git a/tools/src/effect/emitters/solidSphereEmitter.ts b/tools/src/effect/emitters/solidSphereEmitter.ts new file mode 100644 index 000000000..43bfc986c --- /dev/null +++ b/tools/src/effect/emitters/solidSphereEmitter.ts @@ -0,0 +1,34 @@ +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { ISolidParticleEmitterType } from "../types"; + +/** + * Sphere emitter for SolidParticleSystem + */ +export class SolidSphereParticleEmitter implements ISolidParticleEmitterType { + public radius: number; + public arc: number; + public thickness: number; + + constructor(radius: number = 1, arc: number = Math.PI * 2, thickness: number = 1) { + this.radius = radius; + this.arc = arc; + this.thickness = thickness; + } + + public initializeParticle(particle: SolidParticle, startSpeed: number): void { + const u = Math.random(); + const v = Math.random(); + const rand = 1 - this.thickness + Math.random() * this.thickness; + const theta = u * this.arc; + const phi = Math.acos(2.0 * v - 1.0); + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + + particle.position.set(sinPhi * cosTheta, sinPhi * sinTheta, cosPhi); + particle.velocity.copyFrom(particle.position); + particle.velocity.scaleInPlace(startSpeed); + particle.position.scaleInPlace(this.radius * rand); + } +} diff --git a/tools/src/effect/factories/geometryFactory.ts b/tools/src/effect/factories/geometryFactory.ts new file mode 100644 index 000000000..0b87a2b7d --- /dev/null +++ b/tools/src/effect/factories/geometryFactory.ts @@ -0,0 +1,193 @@ +import { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { VertexData } from "@babylonjs/core/Meshes/mesh.vertexData"; +import { CreatePlane } from "@babylonjs/core/Meshes/Builders/planeBuilder"; +import { Scene } from "@babylonjs/core/scene"; +import type { IGeometryFactory, IGeometry, IData } from "../types"; +import { Nullable } from "@babylonjs/core/types"; +import { Tools } from "@babylonjs/core/Misc/tools"; + +/** + * Factory for creating meshes from Three.js geometry data + */ +export class GeometryFactory implements IGeometryFactory { + private _data: IData; + + constructor(data: IData) { + this._data = data; + } + + /** + * Create a mesh from geometry ID + */ + public createMesh(geometryId: string, name: string, scene: Scene): Mesh { + const geometryData = this._findGeometry(geometryId); + if (!geometryData) { + return new Mesh(name, scene); + } + + const mesh = this._createMeshFromGeometry(geometryData, name, scene); + if (!mesh) { + Tools.Warn(`Failed to create mesh from geometry ${geometryId}`); + return new Mesh(name, scene); + } + + return mesh; + } + + /** + * Create or load particle mesh for SPS. + * Uses instancingGeometry ID if provided, otherwise creates default plane. + */ + public createParticleMesh(name: string, scene: Scene, instancingGeometry?: string): Mesh { + let particleMesh = this._loadParticleGeometry(name, scene, instancingGeometry); + + if (!particleMesh) { + particleMesh = this._createDefaultPlaneMesh(name, scene); + } + + if (!particleMesh) { + Tools.Warn(`Cannot create particle mesh: particleMesh is null`); + } + + return particleMesh; + } + + /** + * Loads particle geometry if instancingGeometry ID is specified + */ + private _loadParticleGeometry(name: string, scene: Scene, instancingGeometry?: string): Nullable { + if (!instancingGeometry) { + return null; + } + + const mesh = this.createMesh(instancingGeometry, name + "_shape", scene); + if (!mesh) { + Tools.Warn(`Failed to load geometry ${instancingGeometry}, will create default plane`); + } + + return mesh; + } + + /** + * Creates default plane mesh + */ + private _createDefaultPlaneMesh(name: string, scene: Scene): Mesh { + return CreatePlane(name + "_shape", { width: 1, height: 1 }, scene); + } + + /** + * Finds geometry by UUID + */ + private _findGeometry(geometryId: string): IGeometry | null { + if (!this._data.geometries || this._data.geometries.length === 0) { + Tools.Warn("No geometries data available"); + return null; + } + + const geometry = this._data.geometries.find((g) => g.uuid === geometryId); + if (!geometry) { + Tools.Warn(`Geometry not found: ${geometryId}`); + return null; + } + + return geometry; + } + + /** + * Creates mesh from geometry data based on type + */ + private _createMeshFromGeometry(geometryData: IGeometry, name: string, scene: Scene): Nullable { + const geometryTypeHandlers: Record Nullable> = { + PlaneGeometry: (data, meshName, scene) => this._createPlaneGeometry(data, meshName, scene), + BufferGeometry: (data, meshName, scene) => this._createBufferGeometry(data, meshName, scene), + }; + + const handler = geometryTypeHandlers[geometryData.type]; + if (!handler) { + Tools.Warn(`Unsupported geometry type: ${geometryData.type}`); + return null; + } + + return handler(geometryData, name, scene); + } + + /** + * Creates plane geometry mesh + */ + private _createPlaneGeometry(geometryData: IGeometry, name: string, scene: Scene): Nullable { + const width = geometryData.width ?? 1; + const height = geometryData.height ?? 1; + const mesh = CreatePlane(name, { width, height }, scene); + return mesh; + } + + /** + * Creates buffer geometry mesh (already converted to left-handed) + */ + private _createBufferGeometry(geometryData: IGeometry, name: string, scene: Scene): Nullable { + if (!geometryData.data?.attributes) { + Tools.Warn("BufferGeometry missing data or attributes"); + return null; + } + + const vertexData = this._createVertexDataFromAttributes(geometryData); + if (!vertexData) { + return null; + } + + const mesh = new Mesh(name, scene); + vertexData.applyToMesh(mesh); + // Geometry is already converted to left-handed in DataConverter + + return mesh; + } + + /** + * Creates VertexData from BufferGeometry attributes (already converted to left-handed) + */ + private _createVertexDataFromAttributes(geometryData: IGeometry): Nullable { + if (!geometryData.data?.attributes) { + return null; + } + + const attrs = geometryData.data.attributes; + const positions = attrs.position; + if (!positions?.array) { + Tools.Warn("BufferGeometry missing position attribute"); + return null; + } + + const vertexData = new VertexData(); + vertexData.positions = Array.from(positions.array); + + this._applyAttribute(vertexData, attrs.normal, "normals"); + this._applyAttribute(vertexData, attrs.uv, "uvs"); + this._applyAttribute(vertexData, attrs.color, "colors"); + + const indices = geometryData.data.index; + if (indices?.array) { + vertexData.indices = Array.from(indices.array); + } else { + vertexData.indices = this._generateIndices(vertexData.positions.length); + } + + return vertexData; + } + + /** + * Applies attribute data to VertexData if available + */ + private _applyAttribute(vertexData: VertexData, attribute: { array?: number[] } | undefined, property: "normals" | "uvs" | "colors"): void { + if (attribute?.array) { + (vertexData as any)[property] = Array.from(attribute.array); + } + } + + /** + * Generates sequential indices for vertices + */ + private _generateIndices(positionsLength: number): number[] { + const vertexCount = positionsLength / 3; + return Array.from({ length: vertexCount }, (_, i) => i); + } +} diff --git a/tools/src/effect/factories/index.ts b/tools/src/effect/factories/index.ts new file mode 100644 index 000000000..974bb9ae1 --- /dev/null +++ b/tools/src/effect/factories/index.ts @@ -0,0 +1,3 @@ +export { MaterialFactory } from "./materialFactory"; +export { GeometryFactory } from "./geometryFactory"; +export { NodeFactory } from "./nodeFactory"; diff --git a/tools/src/effect/factories/materialFactory.ts b/tools/src/effect/factories/materialFactory.ts new file mode 100644 index 000000000..657a293fb --- /dev/null +++ b/tools/src/effect/factories/materialFactory.ts @@ -0,0 +1,297 @@ +import { Texture as BabylonTexture } from "@babylonjs/core/Materials/Textures/texture"; +import { PBRMaterial } from "@babylonjs/core/Materials/PBR/pbrMaterial"; +import { Material as BabylonMaterial } from "@babylonjs/core/Materials/material"; +import { Constants } from "@babylonjs/core/Engines/constants"; +import { Tools } from "@babylonjs/core/Misc/tools"; +import { Scene } from "@babylonjs/core/scene"; +import { Color3 } from "@babylonjs/core/Maths/math.color"; + +import type { IMaterialFactory, IData, IMaterial, ITexture, IImage } from "../types"; + +/** + * Factory for creating materials and textures from Three.js JSON data + */ +export class MaterialFactory implements IMaterialFactory { + private _scene: Scene; + private _data: IData; + private _rootUrl: string; + constructor(scene: Scene, data: IData, rootUrl: string) { + this._scene = scene; + this._data = data; + this._rootUrl = rootUrl; + } + + /** + * Create a texture from material ID (for ParticleSystem - no material needed) + */ + public createTexture(materialId: string): BabylonTexture { + const textureData = this._resolveTextureData(materialId); + if (!textureData) { + return new BabylonTexture(materialId, this._scene); + } + + const { texture, image } = textureData; + const textureUrl = this._buildTextureUrl(image); + return this._createTextureFromData(textureUrl, texture); + } + + /** + * Get blend mode from material blending value + */ + public getBlendMode(materialId: string): number | undefined { + const material = this._data.materials?.find((m: any) => m.uuid === materialId); + + if (material?.blending === undefined) { + return undefined; + } + + const blendModeMap: Record = { + 0: Constants.ALPHA_DISABLE, // NoBlending + 1: Constants.ALPHA_COMBINE, // NormalBlending + 2: Constants.ALPHA_ADD, // AdditiveBlending + }; + + return blendModeMap[material.blending]; + } + + /** + * Resolves material, texture, and image data from material ID + */ + private _resolveTextureData(materialId: string): { material: IMaterial; texture: ITexture; image: IImage } | null { + if (!this._hasRequiredData()) { + Tools.Warn(`Missing materials/textures/images data for material ${materialId}`); + return null; + } + + const material = this._findMaterial(materialId); + if (!material || !material.map) { + return null; + } + + const texture = this._findTexture(material.map); + if (!texture || !texture.image) { + return null; + } + + const image = this._findImage(texture.image); + if (!image || !image.url) { + return null; + } + + return { material, texture, image }; + } + + /** + * Checks if required JSON data is available + */ + private _hasRequiredData(): boolean { + return !!(this._data.materials && this._data.textures && this._data.images); + } + + /** + * Finds material by UUID + */ + private _findMaterial(materialId: string): IMaterial | null { + const material = this._data.materials?.find((m) => m.uuid === materialId); + if (!material) { + Tools.Warn(`Material not found: ${materialId}`); + return null; + } + return material; + } + + /** + * Finds texture by UUID + */ + private _findTexture(textureId: string): ITexture | null { + const texture = this._data.textures?.find((t) => t.uuid === textureId); + if (!texture) { + Tools.Warn(`Texture not found: ${textureId}`); + return null; + } + return texture; + } + + /** + * Finds image by UUID + */ + private _findImage(imageId: string): IImage | null { + const image = this._data.images?.find((img) => img.uuid === imageId); + if (!image) { + Tools.Warn(`Image not found: ${imageId}`); + return null; + } + return image; + } + + /** + * Builds texture URL from image data + */ + private _buildTextureUrl(image: IImage): string { + if (!image.url) { + return ""; + } + const isBase64 = image.url.startsWith("data:"); + return isBase64 ? image.url : Tools.GetAssetUrl(this._rootUrl + image.url); + } + + /** + * Applies texture properties from texture data to Babylon.js texture + */ + private _applyTextureProperties(babylonTexture: BabylonTexture, texture: ITexture): void { + if (texture.wrapU !== undefined) { + babylonTexture.wrapU = texture.wrapU; + } + if (texture.wrapV !== undefined) { + babylonTexture.wrapV = texture.wrapV; + } + if (texture.uScale !== undefined) { + babylonTexture.uScale = texture.uScale; + } + if (texture.vScale !== undefined) { + babylonTexture.vScale = texture.vScale; + } + if (texture.uOffset !== undefined) { + babylonTexture.uOffset = texture.uOffset; + } + if (texture.vOffset !== undefined) { + babylonTexture.vOffset = texture.vOffset; + } + if (texture.coordinatesIndex !== undefined) { + babylonTexture.coordinatesIndex = texture.coordinatesIndex; + } + if (texture.uAng !== undefined) { + babylonTexture.uAng = texture.uAng; + } + } + + /** + * Creates Babylon.js texture from texture data + */ + private _createTextureFromData(textureUrl: string, texture: ITexture): BabylonTexture { + const samplingMode = texture.samplingMode ?? BabylonTexture.TRILINEAR_SAMPLINGMODE; + + const babylonTexture = new BabylonTexture(textureUrl, this._scene, { + noMipmap: !texture.generateMipmaps, + invertY: texture.flipY !== false, + samplingMode, + }); + + this._applyTextureProperties(babylonTexture, texture); + return babylonTexture; + } + + /** + * Create a material from material ID, or default PBR material when materialId is undefined (like default geometry). + */ + public createMaterial(materialId: string | undefined, name: string): PBRMaterial { + if (!materialId) { + return new PBRMaterial(name + "_material", this._scene); + } + const textureData = this._resolveTextureData(materialId); + if (!textureData) { + return new PBRMaterial(name + "_material", this._scene); + } + + const { material, texture, image } = textureData; + const materialType = material.type || "MeshStandardMaterial"; + + const textureUrl = this._buildTextureUrl(image); + const babylonTexture = this._createTextureFromData(textureUrl, texture); + const materialColor = material.color || new Color3(1, 1, 1); + + if (materialType === "MeshBasicMaterial") { + return this._createUnlitMaterial(name, material, babylonTexture, materialColor); + } + + // Create PBR material for other material types + // Note: Vertex colors are automatically used by PBR materials if mesh has vertex colors + // The VERTEXCOLOR define is set automatically based on mesh.isVerticesDataPresent(VertexBuffer.ColorKind) + const pbrMaterial = new PBRMaterial(name + "_material", this._scene); + pbrMaterial.albedoTexture = babylonTexture; + pbrMaterial.albedoColor = materialColor; + + this._applyTransparency(pbrMaterial, material, babylonTexture); + this._applyDepthWrite(pbrMaterial, material); + this._applySideSettings(pbrMaterial, material); + this._applyBlendMode(pbrMaterial, material); + + return pbrMaterial; + } + + /** + * Creates unlit material (MeshBasicMaterial equivalent) + */ + private _createUnlitMaterial(name: string, material: IMaterial, texture: BabylonTexture, color: Color3): PBRMaterial { + const unlitMaterial = new PBRMaterial(name + "_material", this._scene); + + unlitMaterial.unlit = true; + unlitMaterial.albedoColor = color; + unlitMaterial.albedoTexture = texture; + // Note: Vertex colors are automatically used by PBR materials if mesh has vertex colors + + this._applyTransparency(unlitMaterial, material, texture); + this._applyDepthWrite(unlitMaterial, material); + this._applySideSettings(unlitMaterial, material); + this._applyBlendMode(unlitMaterial, material); + + return unlitMaterial; + } + + /** + * Applies transparency settings to material + */ + private _applyTransparency(material: PBRMaterial, Material: IMaterial, texture: BabylonTexture): void { + if (Material.transparent) { + material.transparencyMode = BabylonMaterial.MATERIAL_ALPHABLEND; + material.needDepthPrePass = false; + texture.hasAlpha = true; + material.useAlphaFromAlbedoTexture = true; + } else { + material.transparencyMode = BabylonMaterial.MATERIAL_OPAQUE; + material.alpha = 1.0; + } + } + + /** + * Applies depth write settings to material + */ + private _applyDepthWrite(material: PBRMaterial, Material: IMaterial): void { + if (Material.depthWrite !== undefined) { + material.disableDepthWrite = !Material.depthWrite; + } else { + material.disableDepthWrite = true; + } + } + + /** + * Applies side orientation settings to material + */ + private _applySideSettings(material: PBRMaterial, Material: IMaterial): void { + material.backFaceCulling = false; + + if (Material.side !== undefined) { + material.sideOrientation = Material.side; + } + } + + /** + * Applies blend mode to material + */ + private _applyBlendMode(material: PBRMaterial, Material: IMaterial): void { + if (Material.blending === undefined) { + return; + } + + const blendModeMap: Record = { + 0: Constants.ALPHA_DISABLE, // NoBlending + 1: Constants.ALPHA_COMBINE, // NormalBlending + 2: Constants.ALPHA_ADD, // AdditiveBlending + }; + + const alphaMode = blendModeMap[Material.blending]; + if (alphaMode !== undefined) { + material.alphaMode = alphaMode; + } + } +} diff --git a/tools/src/effect/factories/nodeFactory.ts b/tools/src/effect/factories/nodeFactory.ts new file mode 100644 index 000000000..7145f82cf --- /dev/null +++ b/tools/src/effect/factories/nodeFactory.ts @@ -0,0 +1,471 @@ +import { Quaternion, Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; +import { Scene } from "@babylonjs/core/scene"; +import { Tools } from "@babylonjs/core/Misc/tools"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; + +import { EffectParticleSystem, EffectSolidParticleSystem } from "../systems"; +import { IData, IGroup, IEmitter, ITransform, IParticleSystemConfig, IMaterialFactory, IGeometryFactory, IEffectNode, isSystem } from "../types"; +import { calculateForParticleSystem, parseConstantValue } from "../utils"; +import { MaterialFactory } from "./materialFactory"; +import { GeometryFactory } from "./geometryFactory"; +/** + * Factory for creating particle systems from data + * Creates all nodes, sets parents, and applies transformations in a single pass + */ +export class NodeFactory { + private _scene: Scene; + private _data: IData; + + private _materialFactory: IMaterialFactory; + private _geometryFactory: IGeometryFactory; + + constructor(scene: Scene, data: IData, rootUrl: string) { + this._scene = scene; + this._data = data; + this._materialFactory = new MaterialFactory(scene, data, rootUrl); + this._geometryFactory = new GeometryFactory(data); + } + + /** + * Create particle systems from data + * Creates all nodes, sets parents, and applies transformations in one pass + */ + public create(): IEffectNode { + if (!this._data.root) { + Tools.Warn("No root object found in data"); + return this._createRootNode(); + } + return this._createNode(this._data.root, null); + } + + /** + * Create a new group node + * @param name Group name + * @param parentNode Parent node (optional) + * @returns Created group node + */ + public createGroup(name: string, parentNode: IEffectNode | null = null): IEffectNode { + const groupUuid = Tools.RandomId(); + const group: IGroup = { + uuid: groupUuid, + name, + transform: { + position: Vector3.Zero(), + rotation: Quaternion.Identity(), + scale: Vector3.One(), + }, + children: [], + }; + + return this._createGroupNode(group, parentNode); + } + + /** + * Create a new particle system node + * @param name System name + * @param systemType Type of system ("solid" or "base") + * @param config Optional particle system config + * @param parentNode Parent node (optional) + * @returns Created particle system node + */ + public createParticleSystem(name: string, systemType: "solid" | "base" = "base", config?: Partial, parentNode: IEffectNode | null = null): IEffectNode { + const systemUuid = Tools.RandomId(); + const defaultConfig: IParticleSystemConfig = { + systemType, + targetStopDuration: 0, // looping + manualEmitCount: -1, + emitRate: 10, + minLifeTime: 1, + maxLifeTime: 1, + minEmitPower: 1, + maxEmitPower: 1, + minSize: 1, + maxSize: 1, + color1: new Color4(1, 1, 1, 1), + color2: new Color4(1, 1, 1, 1), + behaviors: [], + ...config, + }; + + const emitter: IEmitter = { + uuid: systemUuid, + name, + transform: { + position: Vector3.Zero(), + rotation: Quaternion.Identity(), + scale: Vector3.One(), + }, + config: defaultConfig, + systemType, + }; + + return this._createParticleNode(emitter, parentNode); + } + + private _createRootNode(): IEffectNode { + const rootGroup = new TransformNode("Root", this._scene); + const rootUuid = Tools.RandomId(); + rootGroup.id = rootUuid; + const rootNode: IEffectNode = { + name: "Root", + uuid: rootUuid, + data: rootGroup, + children: [], + type: "group", + }; + return rootNode; + } + /** + * Recursively process object hierarchy + * Creates nodes, sets parents, and applies transformations in one pass + */ + private _createNode(obj: IGroup | IEmitter, parentNode: IEffectNode | null): IEffectNode { + if ("children" in obj && obj.children) { + const groupNode = this._createGroupNode(obj as IGroup, parentNode); + groupNode.children = obj.children.map((child) => this._createNode(child, groupNode)); + return groupNode; + } + return this._createParticleNode(obj as IEmitter, parentNode); + } + + /** + * Create a TransformNode for a Group + */ + private _createGroupNode(group: IGroup, parentNode: IEffectNode | null): IEffectNode { + const transformNode = new TransformNode(group.name, this._scene); + transformNode.id = group.uuid; + const node: IEffectNode = { + name: group.name, + uuid: group.uuid, + children: [], + data: transformNode, + type: "group", + }; + + this._applyTransform(node, group.transform); + + if (parentNode) { + (node.data as TransformNode).parent = parentNode.data as TransformNode; + } + + return node; + } + + /** + * Create a particle system from a Emitter + */ + private _createParticleNode(emitter: IEmitter, parentNode: IEffectNode | null): IEffectNode { + let particleSystem: EffectParticleSystem | EffectSolidParticleSystem; + + if (emitter.config.systemType === "solid") { + particleSystem = this._createEffectSolidParticleSystem(emitter); + } else { + particleSystem = this._createEffectParticleSystem(emitter); + } + + const node: IEffectNode = { + name: emitter.name, + uuid: emitter.uuid, + children: [], + data: particleSystem, + type: "particle", + }; + + particleSystem.emitter = new TransformNode(emitter.name + "_emitter", this._scene) as AbstractMesh; + + if (parentNode) { + particleSystem.emitter.parent = parentNode.data as TransformNode; + } + + this._applyTransform({ name: emitter.name, uuid: emitter.uuid, children: [], data: particleSystem.emitter, type: "particle" } as IEffectNode, emitter.transform); + + return node; + } + + /** + * Apply common native properties to both ParticleSystem and SolidParticleSystem + */ + private _applyCommonProperties(system: EffectParticleSystem | EffectSolidParticleSystem, config: IParticleSystemConfig): void { + if (config.minSize !== undefined) { + system.minSize = config.minSize; + } + if (config.maxSize !== undefined) { + system.maxSize = config.maxSize; + } + if (config.minLifeTime !== undefined) { + system.minLifeTime = config.minLifeTime; + } + if (config.maxLifeTime !== undefined) { + system.maxLifeTime = config.maxLifeTime; + } + if (config.minEmitPower !== undefined) { + system.minEmitPower = config.minEmitPower; + } + if (config.maxEmitPower !== undefined) { + system.maxEmitPower = config.maxEmitPower; + } + if (config.emitRate !== undefined) { + system.emitRate = config.emitRate; + } + if (config.targetStopDuration !== undefined) { + system.targetStopDuration = config.targetStopDuration; + } + if (config.manualEmitCount !== undefined) { + system.manualEmitCount = config.manualEmitCount; + } + if (config.preWarmCycles !== undefined) { + system.preWarmCycles = config.preWarmCycles; + } + if (config.preWarmStepOffset !== undefined) { + system.preWarmStepOffset = config.preWarmStepOffset; + } + if (config.color1 !== undefined) { + system.color1 = config.color1; + } + if (config.color2 !== undefined) { + system.color2 = config.color2; + } + if (config.colorDead !== undefined) { + system.colorDead = config.colorDead; + } + if (config.minInitialRotation !== undefined) { + system.minInitialRotation = config.minInitialRotation; + } + if (config.maxInitialRotation !== undefined) { + system.maxInitialRotation = config.maxInitialRotation; + } + if (config.isLocal !== undefined) { + system.isLocal = config.isLocal; + } + if (config.disposeOnStop !== undefined) { + system.disposeOnStop = config.disposeOnStop; + } + if (config.gravity !== undefined) { + system.gravity = config.gravity; + } + if (config.noiseStrength !== undefined) { + system.noiseStrength = config.noiseStrength; + } + if (config.updateSpeed !== undefined) { + system.updateSpeed = config.updateSpeed; + } + if (config.minAngularSpeed !== undefined) { + system.minAngularSpeed = config.minAngularSpeed; + } + if (config.maxAngularSpeed !== undefined) { + system.maxAngularSpeed = config.maxAngularSpeed; + } + if (config.minScaleX !== undefined) { + system.minScaleX = config.minScaleX; + } + if (config.maxScaleX !== undefined) { + system.maxScaleX = config.maxScaleX; + } + if (config.minScaleY !== undefined) { + system.minScaleY = config.minScaleY; + } + if (config.maxScaleY !== undefined) { + system.maxScaleY = config.maxScaleY; + } + } + + /** + * Apply gradients (PiecewiseBezier) to both ParticleSystem and SolidParticleSystem + */ + private _applyGradients(system: EffectParticleSystem | EffectSolidParticleSystem, config: IParticleSystemConfig): void { + if (config.startSizeGradients) { + for (const grad of config.startSizeGradients) { + system.addStartSizeGradient(grad.gradient, grad.factor, grad.factor2); + } + } + if (config.lifeTimeGradients) { + for (const grad of config.lifeTimeGradients) { + system.addLifeTimeGradient(grad.gradient, grad.factor, grad.factor2); + } + } + if (config.emitRateGradients) { + for (const grad of config.emitRateGradients) { + system.addEmitRateGradient(grad.gradient, grad.factor, grad.factor2); + } + } + } + + /** + * Apply common rendering and behavior options + */ + private _applyCommonOptions(system: EffectParticleSystem | EffectSolidParticleSystem, config: IParticleSystemConfig): void { + // Rendering + if (config.renderOrder !== undefined) { + if (system instanceof EffectParticleSystem) { + system.renderingGroupId = config.renderOrder; + } else { + system.renderOrder = config.renderOrder; + } + } + if (config.layers !== undefined) { + if (system instanceof EffectParticleSystem) { + system.layerMask = config.layers; + } else { + system.layers = config.layers; + } + } + + // Billboard + if (config.isBillboardBased !== undefined) { + system.isBillboardBased = config.isBillboardBased; + } + + // Behaviors + if (config.behaviors) { + system.setBehaviors(config.behaviors); + } + } + + /** + * Apply emission bursts by converting them to emit rate gradients + * Unified approach for both ParticleSystem and SolidParticleSystem + */ + private _applyEmissionBursts(system: EffectParticleSystem | EffectSolidParticleSystem, config: IParticleSystemConfig): void { + if (!config.emissionBursts || config.emissionBursts.length === 0) { + return; + } + + const duration = config.targetStopDuration !== undefined && config.targetStopDuration > 0 ? config.targetStopDuration : 5; + const baseEmitRate = config.emitRate || 10; + for (const burst of config.emissionBursts) { + if (burst.time !== undefined && burst.count !== undefined) { + const burstTime = parseConstantValue(burst.time); + const burstCount = parseConstantValue(burst.count); + const timeRatio = Math.min(Math.max(burstTime / duration, 0), 1); + const windowSize = 0.02; + const burstEmitRate = burstCount / windowSize; + const beforeTime = Math.max(0, timeRatio - windowSize); + const afterTime = Math.min(1, timeRatio + windowSize); + system.addEmitRateGradient(beforeTime, baseEmitRate); + system.addEmitRateGradient(timeRatio, burstEmitRate); + system.addEmitRateGradient(afterTime, baseEmitRate); + } + } + } + + /** + * Create a ParticleSystem instance + */ + private _createEffectParticleSystem(emitter: IEmitter): EffectParticleSystem { + const { name, config } = emitter; + + // Calculate capacity + const duration = config.targetStopDuration !== undefined && config.targetStopDuration > 0 ? config.targetStopDuration : 5; + const emitRate = config.emitRate || 10; + const capacity = calculateForParticleSystem(emitRate, duration); + + // Create instance (simple constructor) + const particleSystem = new EffectParticleSystem(name, capacity, this._scene); + + // Apply common properties and gradients + this._applyCommonProperties(particleSystem, config); + this._applyGradients(particleSystem, config); + + // === Настройка текстуры и blend mode === + if (emitter.materialId) { + const texture = this._materialFactory.createTexture(emitter.materialId); + if (texture) { + particleSystem.particleTexture = texture; + } + const blendMode = this._materialFactory.getBlendMode(emitter.materialId); + if (blendMode !== undefined) { + particleSystem.blendMode = blendMode; + } + } + + // === Настройка sprite tiles === + if (config.uTileCount !== undefined && config.vTileCount !== undefined) { + if (config.uTileCount > 1 || config.vTileCount > 1) { + particleSystem.isAnimationSheetEnabled = true; + particleSystem.spriteCellWidth = config.uTileCount; + particleSystem.spriteCellHeight = config.vTileCount; + if (config.startTileIndex !== undefined) { + const startTile = parseConstantValue(config.startTileIndex); + particleSystem.startSpriteCellID = Math.floor(startTile); + particleSystem.endSpriteCellID = Math.floor(startTile); + } + } + } + + // Apply common rendering and behavior options + this._applyCommonOptions(particleSystem, config); + + // Apply emission bursts (converted to gradients) + this._applyEmissionBursts(particleSystem, config); + + // ParticleSystem-specific: billboard mode + if (config.billboardMode !== undefined) { + particleSystem.billboardMode = config.billboardMode; + } + + if (config.shape) { + particleSystem.configureEmitterFromShape(config.shape); + } + + return particleSystem; + } + + /** + * Create a SolidParticleSystem instance + */ + private _createEffectSolidParticleSystem(emitter: IEmitter): EffectSolidParticleSystem { + const { name, config, materialId } = emitter; + + const particleMesh = this._geometryFactory.createParticleMesh(name, this._scene, config.instancingGeometry); + + const sps = new EffectSolidParticleSystem(name, this._scene); + + sps.particleMesh = particleMesh; + sps.meshMaterial = this._materialFactory.createMaterial(materialId, name); + + this._applyCommonProperties(sps, config); + this._applyGradients(sps, config); + this._applyCommonOptions(sps, config); + this._applyEmissionBursts(sps, config); + + if (config.emissionOverDistance !== undefined) { + sps.emissionOverDistance = config.emissionOverDistance; + } + + if (config.shape) { + sps.configureEmitterFromShape(config.shape); + } + + particleMesh.dispose(); + + return sps; + } + + /** + * Apply transform to a node + */ + private _applyTransform(node: IEffectNode, transform: ITransform): void { + if (!transform) { + Tools.Warn(`Transform is undefined for node: ${node.name}`); + return; + } + + const object = isSystem(node.data) ? node.data.emitter : node.data; + + if (transform.position && object && "position" in object) { + object.position.copyFrom(transform.position); + } + + if (transform.rotation) { + if (object && "rotationQuaternion" in object) { + object.rotationQuaternion = new Quaternion().copyFrom(transform.rotation); + } + } + + if (transform.scale && object && "scaling" in object) { + object.scaling.copyFrom(transform.scale); + } + } +} diff --git a/tools/src/effect/index.ts b/tools/src/effect/index.ts new file mode 100644 index 000000000..590139360 --- /dev/null +++ b/tools/src/effect/index.ts @@ -0,0 +1,7 @@ +export * from "./types"; +export * from "./factories"; +export * from "./utils"; +export * from "./systems"; +export * from "./effect"; +export * from "./emitters"; +export * from "./behaviors"; diff --git a/tools/src/effect/systems/effectParticleSystem.ts b/tools/src/effect/systems/effectParticleSystem.ts new file mode 100644 index 000000000..c17bd0fe9 --- /dev/null +++ b/tools/src/effect/systems/effectParticleSystem.ts @@ -0,0 +1,254 @@ +import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem"; +import { Scene } from "@babylonjs/core/scene"; +import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; +import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; +import { Particle } from "@babylonjs/core/Particles/particle"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import type { + Behavior, + IColorOverLifeBehavior, + ISizeOverLifeBehavior, + IRotationOverLifeBehavior, + IForceOverLifeBehavior, + IGravityForceBehavior, + ISpeedOverLifeBehavior, + IFrameOverLifeBehavior, + ILimitSpeedOverLifeBehavior, + IColorBySpeedBehavior, + ISizeBySpeedBehavior, + IRotationBySpeedBehavior, + IOrbitOverLifeBehavior, + PerParticleBehaviorFunction, + ISystem, + ParticleWithSystem, + IShape, +} from "../types"; +import { + applyColorOverLifePS, + applySizeOverLifePS, + applyRotationOverLifePS, + applyForceOverLifePS, + applyGravityForcePS, + applySpeedOverLifePS, + applyFrameOverLifePS, + applyLimitSpeedOverLifePS, + applyColorBySpeedPS, + applySizeBySpeedPS, + applyRotationBySpeedPS, + applyOrbitOverLifePS, +} from "../behaviors"; + +/** + * Extended ParticleSystem with behaviors support + * Integrates per-particle behaviors (ColorBySpeed, OrbitOverLife, etc.) + * into the native Babylon.js particle update loop + */ +export class EffectParticleSystem extends ParticleSystem implements ISystem { + private _perParticleBehaviors: PerParticleBehaviorFunction[] = []; + private _behaviorConfigs: Behavior[] = []; + private _parent: AbstractMesh | TransformNode | null; + + constructor(name: string, capacity: number, scene: Scene) { + super(name, capacity, scene); + this._setupEmitter(); + this._setupCustomUpdateFunction(); + } + + public get parent(): AbstractMesh | TransformNode | null { + return this._parent; + } + + public set parent(parent: AbstractMesh | TransformNode | null) { + this._parent = parent; + // Set emitter's parent (emitter is a TransformNode) + if (this.emitter && this.emitter instanceof TransformNode) { + this.emitter.parent = parent; + } + } + + private _setupEmitter(): void { + this.emitter = new TransformNode("Emitter", this._scene) as AbstractMesh; + } + + /** + * Setup custom updateFunction that extends default behavior + * with per-particle behavior execution + */ + private _setupCustomUpdateFunction(): void { + const defaultUpdateFunction = this.updateFunction; + this.updateFunction = (particles: Particle[]): void => { + // First, run the default Babylon.js update logic + // This handles: age, gradients (color, size, angular speed, velocity), position, gravity, etc. + defaultUpdateFunction(particles); + + // Then apply per-particle behaviors if any exist + if (this._perParticleBehaviors.length === 0) { + return; + } + + // Apply per-particle behaviors to each active particle + for (const particle of particles) { + // Attach system reference for behaviors that need it + (particle as ParticleWithSystem).particleSystem = this; + + // Execute all per-particle behavior functions + for (const behaviorFn of this._perParticleBehaviors) { + behaviorFn(particle); + } + } + }; + } + + /** + * Get current behavior configurations (read-only copy) + */ + public get behaviorConfigs(): Behavior[] { + return [...this._behaviorConfigs]; + } + + /** + * Set behaviors and apply them to the particle system + * System-level behaviors configure gradients, per-particle behaviors run each frame + */ + public setBehaviors(behaviors: Behavior[]): void { + this._behaviorConfigs = [...behaviors]; // Copy array + + // Apply system-level behaviors (gradients) to ParticleSystem + this._applySystemLevelBehaviors(behaviors); + + // Build per-particle behavior functions for update loop + this._perParticleBehaviors = this._buildPerParticleBehaviors(behaviors); + } + + /** + * Add a single behavior + */ + public addBehavior(behavior: Behavior): void { + this._behaviorConfigs.push(behavior); + this.setBehaviors(this._behaviorConfigs); + } + + /** + * Build per-particle behavior functions from configurations + * Per-particle behaviors run each frame for each particle (ColorBySpeed, OrbitOverLife, etc.) + */ + private _buildPerParticleBehaviors(behaviors: Behavior[]): PerParticleBehaviorFunction[] { + const functions: PerParticleBehaviorFunction[] = []; + + for (const behavior of behaviors) { + switch (behavior.type) { + case "ColorBySpeed": { + const b = behavior as IColorBySpeedBehavior; + functions.push((particle: Particle) => applyColorBySpeedPS(b, particle)); + break; + } + + case "SizeBySpeed": { + const b = behavior as ISizeBySpeedBehavior; + functions.push((particle: Particle) => applySizeBySpeedPS(particle, b)); + break; + } + + case "RotationBySpeed": { + const b = behavior as IRotationBySpeedBehavior; + functions.push((particle: Particle) => applyRotationBySpeedPS(particle, b)); + break; + } + + case "OrbitOverLife": { + const b = behavior as IOrbitOverLifeBehavior; + functions.push((particle: Particle) => applyOrbitOverLifePS(particle, b)); + break; + } + } + } + + return functions; + } + + /** + * Apply system-level behaviors (gradients) to ParticleSystem + * These configure native Babylon.js gradients once, not per-particle + */ + private _applySystemLevelBehaviors(behaviors: Behavior[]): void { + for (const behavior of behaviors) { + if (!behavior.type) { + continue; + } + + switch (behavior.type) { + case "ColorOverLife": + applyColorOverLifePS(this, behavior as IColorOverLifeBehavior); + break; + case "SizeOverLife": + applySizeOverLifePS(this, behavior as ISizeOverLifeBehavior); + break; + case "RotationOverLife": + case "Rotation3DOverLife": + applyRotationOverLifePS(this, behavior as IRotationOverLifeBehavior); + break; + case "ForceOverLife": + case "ApplyForce": + applyForceOverLifePS(this, behavior as IForceOverLifeBehavior); + break; + case "GravityForce": + applyGravityForcePS(this, behavior as IGravityForceBehavior); + break; + case "SpeedOverLife": + applySpeedOverLifePS(this, behavior as ISpeedOverLifeBehavior); + break; + case "FrameOverLife": + applyFrameOverLifePS(this, behavior as IFrameOverLifeBehavior); + break; + case "LimitSpeedOverLife": + applyLimitSpeedOverLifePS(this, behavior as ILimitSpeedOverLifeBehavior); + break; + } + } + } + + /** + * Configure emitter from shape config + * This replaces the need for EmitterFactory + */ + public configureEmitterFromShape(shape: IShape): void { + if (!shape || !shape.type) { + this.createPointEmitter(new Vector3(0, 1, 0), new Vector3(0, 1, 0)); + return; + } + + const shapeType = shape.type.toLowerCase(); + const radius = shape.radius ?? 1; + const angle = shape.angle ?? Math.PI / 4; + + switch (shapeType) { + case "cone": + this.createConeEmitter(radius, angle); + break; + case "sphere": + this.createSphereEmitter(radius); + break; + case "point": + this.createPointEmitter(new Vector3(0, 1, 0), new Vector3(0, 1, 0)); + break; + case "box": { + const boxSize = shape.size || [1, 1, 1]; + const minBox = new Vector3(-boxSize[0] / 2, -boxSize[1] / 2, -boxSize[2] / 2); + const maxBox = new Vector3(boxSize[0] / 2, boxSize[1] / 2, boxSize[2] / 2); + this.createBoxEmitter(new Vector3(0, 1, 0), new Vector3(0, 1, 0), minBox, maxBox); + break; + } + case "hemisphere": + this.createHemisphericEmitter(radius); + break; + case "cylinder": { + const height = shape.height ?? 1; + this.createCylinderEmitter(radius, height); + break; + } + default: + this.createPointEmitter(new Vector3(0, 1, 0), new Vector3(0, 1, 0)); + break; + } + } +} diff --git a/tools/src/effect/systems/effectSolidParticleSystem.ts b/tools/src/effect/systems/effectSolidParticleSystem.ts new file mode 100644 index 000000000..368807ba6 --- /dev/null +++ b/tools/src/effect/systems/effectSolidParticleSystem.ts @@ -0,0 +1,1354 @@ +import { Quaternion, Vector3, Matrix } from "@babylonjs/core/Maths/math.vector"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { AbstractMesh } from "@babylonjs/core/Meshes/abstractMesh"; +import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem"; +import type { Material } from "@babylonjs/core/Materials/material"; +import type { + Behavior, + IForceOverLifeBehavior, + IColorBySpeedBehavior, + ISizeBySpeedBehavior, + IRotationBySpeedBehavior, + IOrbitOverLifeBehavior, + IEmissionBurst, + ISolidParticleEmitterType, + PerSolidParticleBehaviorFunction, + ISystem, + SolidParticleWithSystem, + Value, +} from "../types"; +import { + SolidPointParticleEmitter, + SolidSphereParticleEmitter, + SolidConeParticleEmitter, + SolidBoxParticleEmitter, + SolidHemisphericParticleEmitter, + SolidCylinderParticleEmitter, +} from "../emitters"; +import { parseConstantValue, parseIntervalValue, calculateForSolidParticleSystem, ColorGradientSystem, NumberGradientSystem } from "../utils"; +import { + applyColorOverLifeSPS, + applyLimitSpeedOverLifeSPS, + applyRotationOverLifeSPS, + applySizeOverLifeSPS, + applySpeedOverLifeSPS, + interpolateColorKeys, + interpolateGradientKeys, + extractNumberFromValue, +} from "../behaviors"; + +/** + * Emission state matching three.quarks EmissionState structure + */ +interface IEmissionState { + time: number; + waitEmiting: number; + travelDistance: number; + previousWorldPos?: Vector3; + burstIndex: number; + burstWaveIndex: number; + burstParticleIndex: number; + burstParticleCount: number; + isBursting: boolean; +} + +/** + * Extended SolidParticleSystem implementing three.quarks Mesh systemType (systemType = "solid") logic + * This class replicates the exact behavior of three.quarks ParticleSystem with systemType = "solid" + */ +export class EffectSolidParticleSystem extends SolidParticleSystem implements ISystem { + private _emissionState: IEmissionState; + private _behaviors: PerSolidParticleBehaviorFunction[]; + public particleEmitterType: ISolidParticleEmitterType | null; + private _emitEnded: boolean; + private _emitter: AbstractMesh | Vector3 | null; + private _meshMaterial: Material | null = null; + // Gradient systems for "OverLife" behaviors (similar to ParticleSystem native gradients) + private _colorGradients: ColorGradientSystem; + private _sizeGradients: NumberGradientSystem; + private _velocityGradients: NumberGradientSystem; + private _angularSpeedGradients: NumberGradientSystem; + private _limitVelocityGradients: NumberGradientSystem; + private _limitVelocityDamping: number; + + // === Native Babylon.js properties (like ParticleSystem) === + public minSize: number = 1; + public maxSize: number = 1; + public minLifeTime: number = 1; + public maxLifeTime: number = 1; + public minEmitPower: number = 1; + public maxEmitPower: number = 1; + public emitRate: number = 10; + public targetStopDuration: number = 5; + public manualEmitCount: number = -1; + public preWarmCycles: number = 0; + public preWarmStepOffset: number = 0.016; + public color1: Color4 = new Color4(1, 1, 1, 1); + public color2: Color4 = new Color4(1, 1, 1, 1); + public colorDead: Color4 = new Color4(1, 1, 1, 0); + public minInitialRotation: number = 0; + public maxInitialRotation: number = 0; + public isLocal: boolean = false; + public disposeOnStop: boolean = false; + public gravity?: Vector3; + public noiseStrength?: Vector3; + // Note: inherited from SolidParticleSystem, default is 0.01 + // We don't override it, using the base class default + public minAngularSpeed: number = 0; + public maxAngularSpeed: number = 0; + public minScaleX: number = 1; + public maxScaleX: number = 1; + public minScaleY: number = 1; + public maxScaleY: number = 1; + + // Gradients for PiecewiseBezier (like ParticleSystem) + private _startSizeGradients: NumberGradientSystem; + private _lifeTimeGradients: NumberGradientSystem; + private _emitRateGradients: NumberGradientSystem; + + // === Other properties === + public emissionOverDistance?: Value; // For distance-based emission + public emissionBursts?: IEmissionBurst[]; // Legacy: converted to gradients in Factory + public renderOrder?: number; + public layers?: number; + public isBillboardBased?: boolean; + private _behaviorConfigs: Behavior[]; + + /** + * Get current behavior configurations (read-only copy) + */ + public get behaviorConfigs(): Behavior[] { + return [...this._behaviorConfigs]; + } + + /** + * Set behaviors and apply them to the system + */ + public setBehaviors(behaviors: Behavior[]): void { + this._behaviorConfigs = [...behaviors]; // Copy array + this._rebuildBehaviors(); + } + + /** + * Add a single behavior + */ + public addBehavior(behavior: Behavior): void { + this._behaviorConfigs.push(behavior); + this._rebuildBehaviors(); + } + + /** + * Rebuild all behavior functions and gradients + */ + private _rebuildBehaviors(): void { + // Clear existing gradients + this._colorGradients.clear(); + this._sizeGradients.clear(); + this._velocityGradients.clear(); + this._angularSpeedGradients.clear(); + this._limitVelocityGradients.clear(); + + // Apply system-level behaviors (gradients) + this._applySystemLevelBehaviors(); + + // Build per-particle behavior functions + this._behaviors = this._buildPerParticleBehaviors(this._behaviorConfigs); + } + + /** + * Add start size gradient (like ParticleSystem) + */ + public addStartSizeGradient(gradient: number, factor: number, factor2?: number): void { + if (factor2 !== undefined) { + this._startSizeGradients.addGradient(gradient, factor); + this._startSizeGradients.addGradient(gradient, factor2); + } else { + this._startSizeGradients.addGradient(gradient, factor); + } + } + + /** + * Add life time gradient (like ParticleSystem) + */ + public addLifeTimeGradient(gradient: number, factor: number, factor2?: number): void { + if (factor2 !== undefined) { + this._lifeTimeGradients.addGradient(gradient, factor); + this._lifeTimeGradients.addGradient(gradient, factor2); + } else { + this._lifeTimeGradients.addGradient(gradient, factor); + } + } + + /** + * Add emit rate gradient (like ParticleSystem) + */ + public addEmitRateGradient(gradient: number, factor: number, factor2?: number): void { + if (factor2 !== undefined) { + this._emitRateGradients.addGradient(gradient, factor); + this._emitRateGradients.addGradient(gradient, factor2); + } else { + this._emitRateGradients.addGradient(gradient, factor); + } + } + + public get emitter(): AbstractMesh | Vector3 | null { + return this._emitter; + } + + public set emitter(emitter: AbstractMesh | Vector3 | null) { + this._emitter = emitter; + } + + /** + * Set particle mesh to use for rendering + * Only adds shape and configures billboard mode. + * Does NOT build mesh - building happens in start(). + * Does NOT dispose source mesh - disposal is caller's responsibility. + */ + public set particleMesh(mesh: Mesh) { + this._addParticleMeshShape(mesh); + } + + /** + * Set material for the SPS mesh (applied when mesh is built in start() or after replaceParticleMesh). + * Caller's responsibility to dispose when no longer needed. + */ + public set meshMaterial(material: Material | null) { + this._meshMaterial = material; + if (this.mesh) { + this.mesh.material = material; + } + } + + public get meshMaterial(): Material | null { + return this._meshMaterial; + } + + /** + * Replace the current particle mesh with a new one + * This completely rebuilds the SPS with the new geometry + */ + public replaceParticleMesh(newMesh: Mesh): void { + if (!newMesh) { + return; + } + + // Stop the system before rebuilding + const wasStarted = this._started; + if (wasStarted) { + this.stop(); + } + + // Dispose old mesh if exists + if (this.mesh) { + this.mesh.dispose(false, true); + } + + // Clear all particles and shapes + this.particles = []; + this.nbParticles = 0; + + // Calculate capacity + const isLooping = this.targetStopDuration === 0; + const capacity = calculateForSolidParticleSystem(this.emitRate, this.targetStopDuration, isLooping); + + // Add new shape + this.addShape(newMesh, capacity); + + // Configure billboard mode + this._configureBillboard(); + + // Build mesh + this.buildMesh(); + this._setupMeshProperties(); + + // Initialize all particles as dead/invisible + this._initializeDeadParticles(); + this.setParticles(); + + // Dispose the source mesh (SPS has already cloned it) + newMesh.dispose(); + + // Restart if was running + if (wasStarted) { + this.start(); + } + } + + /** + * Start the particle system + * Overrides base class to ensure proper initialization + */ + public override start(delay = 0): void { + // Call base class start + super.start(delay); + + // Reset emission state when starting + if (delay === 0) { + this._emissionState.time = 0; + this._emissionState.waitEmiting = 0; + this._emissionState.travelDistance = 0; + this._emissionState.burstIndex = 0; + this._emissionState.burstWaveIndex = 0; + this._emissionState.burstParticleIndex = 0; + this._emissionState.burstParticleCount = 0; + this._emissionState.isBursting = false; + this._emitEnded = false; + } + } + + /** + * Stop the particle system + * Overrides base class to hide all particles when stopped + */ + public override stop(): void { + // Hide all particles before stopping + const particles = this.particles; + const nbParticles = this.nbParticles; + for (let i = 0; i < nbParticles; i++) { + const particle = particles[i]; + if (particle.alive) { + particle.isVisible = false; + } + } + + // Update particles to apply visibility changes + this.setParticles(); + + // Call base class stop + super.stop(); + } + + /** + * Reset the particle system (stop and clear all particles) + * Stops emission, resets emission state, and rebuilds particles to initial state + */ + public reset(): void { + // Stop the system if it's running + this.stop(); + + // Reset emission state + this._emissionState.time = 0; + this._emissionState.waitEmiting = 0; + this._emissionState.travelDistance = 0; + this._emissionState.burstIndex = 0; + this._emissionState.burstWaveIndex = 0; + this._emissionState.burstParticleIndex = 0; + this._emissionState.burstParticleCount = 0; + this._emissionState.isBursting = false; + this._emitEnded = false; + + // Rebuild mesh to reset all particles to initial state (reset=true) + this.rebuildMesh(true); + } + + /** + * Get behavior functions (internal use) + */ + public get behaviors(): PerSolidParticleBehaviorFunction[] { + return this._behaviors; + } + + /** + * Add color gradient (for ColorOverLife behavior) + */ + public addColorGradient(gradient: number, color: Color4): void { + this._colorGradients.addGradient(gradient, color); + } + + /** + * Add size gradient (for SizeOverLife behavior) + */ + public addSizeGradient(gradient: number, size: number): void { + this._sizeGradients.addGradient(gradient, size); + } + + /** + * Add velocity gradient (for SpeedOverLife behavior) + */ + public addVelocityGradient(gradient: number, velocity: number): void { + this._velocityGradients.addGradient(gradient, velocity); + } + + /** + * Add angular speed gradient (for RotationOverLife behavior) + */ + public addAngularSpeedGradient(gradient: number, angularSpeed: number): void { + this._angularSpeedGradients.addGradient(gradient, angularSpeed); + } + + /** + * Add limit velocity gradient (for LimitSpeedOverLife behavior) + */ + public addLimitVelocityGradient(gradient: number, limit: number): void { + this._limitVelocityGradients.addGradient(gradient, limit); + } + + /** + * Set limit velocity damping (for LimitSpeedOverLife behavior) + */ + public set limitVelocityDamping(value: number) { + this._limitVelocityDamping = value; + } + + public get limitVelocityDamping(): number { + return this._limitVelocityDamping; + } + + /** + * Add particle mesh as shape to SPS + * Only adds shape and configures billboard - does NOT build mesh + */ + private _addParticleMeshShape(particleMesh: Mesh): void { + if (!particleMesh) { + return; + } + + // Stop if already running + const wasStarted = this._started; + if (wasStarted) { + this.stop(); + } + + // Dispose old mesh if exists + if (this.mesh) { + this.mesh.dispose(false, true); + } + + // Clear existing shapes + this.particles = []; + this.nbParticles = 0; + + // Calculate capacity and add shape + const isLooping = this.targetStopDuration === 0; + const capacity = calculateForSolidParticleSystem(this.emitRate, this.targetStopDuration, isLooping); + this.addShape(particleMesh, capacity); + + // Configure billboard mode before buildMesh() + this._configureBillboard(); + + // Restart if was running (start() will call buildMesh()) + if (wasStarted) { + this.start(); + } + } + + /** + * Configure billboard mode based on isBillboardBased property + * Must be called after addShape() but before buildMesh() + */ + private _configureBillboard(): void { + if (this.isBillboardBased !== undefined) { + this.billboard = this.isBillboardBased; + } else { + this.billboard = false; + } + } + + private _normalMatrix: Matrix; + private _tempVec: Vector3; + private _tempVec2: Vector3; + private _tempQuat: Quaternion; + + constructor( + name: string, + scene: any, + options?: { + updatable?: boolean; + isPickable?: boolean; + enableDepthSort?: boolean; + particleIntersection?: boolean; + boundingSphereOnly?: boolean; + bSphereRadiusFactor?: number; + expandable?: boolean; + useModelMaterial?: boolean; + enableMultiMaterial?: boolean; + computeBoundingBox?: boolean; + autoFixFaceOrientation?: boolean; + } + ) { + super(name, scene, options); + + this.name = name; + this._behaviors = []; + this.particleEmitterType = new SolidBoxParticleEmitter(); // Default emitter (like ParticleSystem) + this._emitter = null; + + // Gradient systems for "OverLife" behaviors + this._colorGradients = new ColorGradientSystem(); + this._sizeGradients = new NumberGradientSystem(); + this._velocityGradients = new NumberGradientSystem(); + this._angularSpeedGradients = new NumberGradientSystem(); + this._limitVelocityGradients = new NumberGradientSystem(); + this._limitVelocityDamping = 0.1; + + // Gradients for PiecewiseBezier (like ParticleSystem) + this._startSizeGradients = new NumberGradientSystem(); + this._lifeTimeGradients = new NumberGradientSystem(); + this._emitRateGradients = new NumberGradientSystem(); + + this._behaviorConfigs = []; + this._behaviors = []; + + this._emitEnded = false; + this._normalMatrix = new Matrix(); + this._tempVec = Vector3.Zero(); + this._tempVec2 = Vector3.Zero(); + this._tempQuat = Quaternion.Identity(); + + this.updateParticle = this._updateParticle.bind(this); + + this._emissionState = { + time: 0, + waitEmiting: 0, + travelDistance: 0, + burstIndex: 0, + burstWaveIndex: 0, + burstParticleIndex: 0, + burstParticleCount: 0, + isBursting: false, + }; + } + + /** + * Find a dead particle for recycling + */ + private _findDeadParticle(): SolidParticle | null { + const particles = this.particles; + const nbParticles = this.nbParticles; + for (let j = 0; j < nbParticles; j++) { + if (!particles[j].alive) { + return particles[j]; + } + } + return null; + } + + /** + * Reset particle to initial state for recycling + */ + private _resetParticle(particle: SolidParticle): void { + particle.age = 0; + particle.alive = true; + particle.isVisible = true; + particle._stillInvisible = false; + particle.position.setAll(0); + particle.velocity.setAll(0); + particle.rotation.setAll(0); + particle.scaling.setAll(1); + + if (particle.color) { + particle.color.set(1, 1, 1, 1); + } else { + particle.color = new Color4(1, 1, 1, 1); + } + + const props = (particle.props ||= {}); + props.speedModifier = 1.0; + } + + /** + * Initialize particle color + */ + private _initializeParticleColor(particle: SolidParticle): void { + const props = particle.props!; + props.startColor = this.color1.clone(); + if (particle.color) { + particle.color.copyFrom(this.color1); + } else { + particle.color = this.color1.clone(); + } + } + + /** + * Initialize particle speed + * Uses minEmitPower/maxEmitPower like ParticleSystem + */ + private _initializeParticleSpeed(particle: SolidParticle): void { + const props = particle.props!; + // Simply use random between min and max emit power (like ParticleSystem) + props.startSpeed = this._randomRange(this.minEmitPower, this.maxEmitPower); + } + + /** + * Initialize particle lifetime + */ + private _initializeParticleLife(particle: SolidParticle, normalizedTime: number): void { + // Use min/max or gradient + const lifeTimeGradients = this._lifeTimeGradients.getGradients(); + if (lifeTimeGradients.length > 0 && this.targetStopDuration > 0) { + const ratio = Math.max(0, Math.min(1, normalizedTime)); + const gradientValue = this._lifeTimeGradients.getValue(ratio); + if (gradientValue !== null) { + particle.lifeTime = gradientValue; + return; + } + } + particle.lifeTime = this._randomRange(this.minLifeTime, this.maxLifeTime); + } + + /** + * Initialize particle size + * Uses minSize/maxSize and minScaleX/maxScaleX/minScaleY/maxScaleY (like ParticleSystem) + */ + private _initializeParticleSize(particle: SolidParticle, normalizedTime: number): void { + const props = particle.props!; + // Use min/max or gradient for base size + let sizeValue: number; + const startSizeGradients = this._startSizeGradients.getGradients(); + if (startSizeGradients.length > 0 && this.targetStopDuration > 0) { + const ratio = Math.max(0, Math.min(1, normalizedTime)); + const gradientValue = this._startSizeGradients.getValue(ratio); + if (gradientValue !== null) { + sizeValue = gradientValue; + } else { + sizeValue = this._randomRange(this.minSize, this.maxSize); + } + } else { + sizeValue = this._randomRange(this.minSize, this.maxSize); + } + props.startSize = sizeValue; + + // Apply scale modifiers (like ParticleSystem: scale.copyFromFloats) + const scaleX = this._randomRange(this.minScaleX, this.maxScaleX); + const scaleY = this._randomRange(this.minScaleY, this.maxScaleY); + props.startScaleX = scaleX; + props.startScaleY = scaleY; + particle.scaling.set(sizeValue * scaleX, sizeValue * scaleY, sizeValue); + } + + /** + * Random range helper + */ + private _randomRange(min: number, max: number): number { + return min + Math.random() * (max - min); + } + + /** + * Initialize particle rotation and angular speed + * Uses minInitialRotation/maxInitialRotation and minAngularSpeed/maxAngularSpeed (like ParticleSystem) + */ + private _initializeParticleRotation(particle: SolidParticle, _normalizedTime: number): void { + const props = particle.props!; + const angleZ = this._randomRange(this.minInitialRotation, this.maxInitialRotation); + particle.rotation.set(0, 0, angleZ); + // Store angular speed for per-frame rotation (like ParticleSystem) + props.startAngularSpeed = this._randomRange(this.minAngularSpeed, this.maxAngularSpeed); + } + + /** + * Spawn particles from dead pool + */ + private _spawn(count: number): void { + if (count <= 0) { + return; + } + + const emissionState = this._emissionState; + + const emitterMatrix = this._getEmitterMatrix(); + const translation = this._tempVec; + const quaternion = this._tempQuat; + const scale = this._tempVec2; + emitterMatrix.decompose(scale, quaternion, translation); + emitterMatrix.toNormalMatrix(this._normalMatrix); + + const normalizedTime = this.targetStopDuration > 0 ? this._emissionState.time / this.targetStopDuration : 0; + + for (let i = 0; i < count; i++) { + emissionState.burstParticleIndex = i; + + const particle = this._findDeadParticle(); + if (!particle) { + break; + } + + this._resetParticle(particle); + this._initializeParticleColor(particle); + this._initializeParticleSpeed(particle); + this._initializeParticleLife(particle, normalizedTime); + this._initializeParticleSize(particle, normalizedTime); + this._initializeParticleRotation(particle, normalizedTime); + this._initializeEmitterShape(particle); + } + } + + /** + * Initialize emitter shape for particle using particleEmitterType + */ + private _initializeEmitterShape(particle: SolidParticle): void { + const startSpeed = particle.props?.startSpeed ?? 0; + if (this.particleEmitterType) { + this.particleEmitterType.initializeParticle(particle, startSpeed); + } else { + particle.position.setAll(0); + particle.velocity.set(0, 1, 0); + particle.velocity.scaleInPlace(startSpeed); + } + } + + /** + * Create point emitter for SolidParticleSystem + */ + public createPointEmitter(): SolidPointParticleEmitter { + const emitter = new SolidPointParticleEmitter(); + this.particleEmitterType = emitter; + return emitter; + } + + /** + * Create sphere emitter for SolidParticleSystem + */ + public createSphereEmitter(radius: number = 1, arc: number = Math.PI * 2, thickness: number = 1): SolidSphereParticleEmitter { + const emitter = new SolidSphereParticleEmitter(radius, arc, thickness); + this.particleEmitterType = emitter; + return emitter; + } + + /** + * Create cone emitter for SolidParticleSystem + */ + public createConeEmitter(radius: number = 1, arc: number = Math.PI * 2, thickness: number = 1, angle: number = Math.PI / 6): SolidConeParticleEmitter { + const emitter = new SolidConeParticleEmitter(radius, arc, thickness, angle); + this.particleEmitterType = emitter; + return emitter; + } + + /** + * Create box emitter for SolidParticleSystem + */ + public createBoxEmitter( + direction1: Vector3 = new Vector3(0, 1, 0), + direction2: Vector3 = new Vector3(0, 1, 0), + minEmitBox: Vector3 = new Vector3(-0.5, -0.5, -0.5), + maxEmitBox: Vector3 = new Vector3(0.5, 0.5, 0.5) + ): SolidBoxParticleEmitter { + const emitter = new SolidBoxParticleEmitter(direction1, direction2, minEmitBox, maxEmitBox); + this.particleEmitterType = emitter; + return emitter; + } + + /** + * Create hemispheric emitter for SolidParticleSystem + */ + public createHemisphericEmitter(radius: number = 1, radiusRange: number = 1, directionRandomizer: number = 0): SolidHemisphericParticleEmitter { + const emitter = new SolidHemisphericParticleEmitter(radius, radiusRange, directionRandomizer); + this.particleEmitterType = emitter; + return emitter; + } + + /** + * Create cylinder emitter for SolidParticleSystem + */ + public createCylinderEmitter(radius: number = 1, height: number = 1, radiusRange: number = 1, directionRandomizer: number = 0): SolidCylinderParticleEmitter { + const emitter = new SolidCylinderParticleEmitter(radius, height, radiusRange, directionRandomizer); + this.particleEmitterType = emitter; + return emitter; + } + + /** + * Configure emitter from shape config + * This replaces the need for EmitterFactory + */ + public configureEmitterFromShape(shape: any): void { + if (!shape || !shape.type) { + this.createPointEmitter(); + return; + } + + const shapeType = shape.type.toLowerCase(); + const radius = shape.radius ?? 1; + const arc = shape.arc ?? Math.PI * 2; + const thickness = shape.thickness ?? 1; + const angle = shape.angle ?? Math.PI / 6; + const height = shape.height ?? 1; + const radiusRange = shape.radiusRange ?? 1; + const directionRandomizer = shape.directionRandomizer ?? 0; + + switch (shapeType) { + case "sphere": + this.createSphereEmitter(radius, arc, thickness); + break; + case "cone": + this.createConeEmitter(radius, arc, thickness, angle); + break; + case "box": { + const minEmitBox = shape.minEmitBox + ? new Vector3(shape.minEmitBox[0] ?? -0.5, shape.minEmitBox[1] ?? -0.5, shape.minEmitBox[2] ?? -0.5) + : new Vector3(-0.5, -0.5, -0.5); + const maxEmitBox = shape.maxEmitBox ? new Vector3(shape.maxEmitBox[0] ?? 0.5, shape.maxEmitBox[1] ?? 0.5, shape.maxEmitBox[2] ?? 0.5) : new Vector3(0.5, 0.5, 0.5); + const direction1 = shape.direction1 ? new Vector3(shape.direction1[0] ?? 0, shape.direction1[1] ?? 1, shape.direction1[2] ?? 0) : new Vector3(0, 1, 0); + const direction2 = shape.direction2 ? new Vector3(shape.direction2[0] ?? 0, shape.direction2[1] ?? 1, shape.direction2[2] ?? 0) : new Vector3(0, 1, 0); + this.createBoxEmitter(direction1, direction2, minEmitBox, maxEmitBox); + break; + } + case "hemisphere": + this.createHemisphericEmitter(radius, radiusRange, directionRandomizer); + break; + case "cylinder": + this.createCylinderEmitter(radius, height, radiusRange, directionRandomizer); + break; + case "point": + this.createPointEmitter(); + break; + default: + this.createPointEmitter(); + break; + } + } + + private _getEmitterMatrix(): Matrix { + const matrix = Matrix.Identity(); + if (this.mesh) { + this.mesh.computeWorldMatrix(true); + matrix.copyFrom(this.mesh.getWorldMatrix()); + } + return matrix; + } + + private _handleEmissionLooping(): void { + const emissionState = this._emissionState; + const isLooping = this.targetStopDuration === 0; + const duration = isLooping ? 5 : this.targetStopDuration; // Use default 5s for looping + + if (emissionState.time > duration) { + if (isLooping) { + // Loop: reset time and burst index + emissionState.time -= duration; + emissionState.burstIndex = 0; + } else if (!this._emitEnded) { + // Not looping: end emission + this._emitEnded = true; + } + } + } + + private _spawnFromWaitEmiting(): void { + const emissionState = this._emissionState; + const totalSpawn = Math.floor(emissionState.waitEmiting); + if (totalSpawn > 0) { + this._spawn(totalSpawn); + emissionState.waitEmiting -= totalSpawn; + } + } + + private _spawnBursts(): void { + const emissionState = this._emissionState; + + if (!this.emissionBursts || !Array.isArray(this.emissionBursts)) { + return; + } + + while (emissionState.burstIndex < this.emissionBursts.length && this._getBurstTime(this.emissionBursts[emissionState.burstIndex]) <= emissionState.time) { + const burst = this.emissionBursts[emissionState.burstIndex]; + const burstCount = parseConstantValue(burst.count); + emissionState.isBursting = true; + emissionState.burstParticleCount = burstCount; + this._spawn(burstCount); + emissionState.isBursting = false; + emissionState.burstIndex++; + } + } + + private _accumulateEmission(delta: number): void { + const emissionState = this._emissionState; + + if (this._emitEnded) { + return; + } + + // Check for manual emit count (like ParticleSystem) + // When manualEmitCount > -1, emit that exact number and reset to 0 + if (this.manualEmitCount > -1) { + emissionState.waitEmiting = this.manualEmitCount; + this.manualEmitCount = 0; + return; + } + + // Get emit rate (use gradient if available) + let emissionRate = this.emitRate; + const emitRateGradients = this._emitRateGradients.getGradients(); + if (emitRateGradients.length > 0 && this.targetStopDuration > 0) { + const normalizedTime = this.targetStopDuration > 0 ? this._emissionState.time / this.targetStopDuration : 0; + const ratio = Math.max(0, Math.min(1, normalizedTime)); + const gradientValue = this._emitRateGradients.getValue(ratio); + if (gradientValue !== null) { + emissionRate = gradientValue; + } + } + emissionState.waitEmiting += delta * emissionRate; + + if (this.emissionOverDistance !== undefined && this.mesh && this.mesh.position) { + const emitPerMeter = parseConstantValue(this.emissionOverDistance); + if (emitPerMeter > 0 && emissionState.previousWorldPos) { + const distance = Vector3.Distance(emissionState.previousWorldPos, this.mesh.position); + emissionState.travelDistance += distance; + if (emissionState.travelDistance * emitPerMeter > 0) { + const count = Math.floor(emissionState.travelDistance * emitPerMeter); + emissionState.travelDistance -= count / emitPerMeter; + emissionState.waitEmiting += count; + } + } + if (!emissionState.previousWorldPos) { + emissionState.previousWorldPos = Vector3.Zero(); + } + emissionState.previousWorldPos.copyFrom(this.mesh.position); + } + } + + private _emit(delta: number): void { + this._accumulateEmission(delta); + this._spawnFromWaitEmiting(); + this._spawnBursts(); + } + + private _getBurstTime(burst: IEmissionBurst): number { + return parseConstantValue(burst.time); + } + + /** + * Setup mesh properties after buildMesh() + * Sets parent, rendering group, layers, vertex alpha + */ + private _setupMeshProperties(): void { + if (!this.mesh) { + return; + } + + // Enable vertex alpha for color blending + if (!this.mesh.hasVertexAlpha) { + this.mesh.hasVertexAlpha = true; + } + + // Set rendering group + if (this.renderOrder !== undefined) { + this.mesh.renderingGroupId = this.renderOrder; + } + + // Set layer mask + if (this.layers !== undefined) { + this.mesh.layerMask = this.layers; + } + + // Set parent (transform hierarchy) + if (this._emitter) { + this.mesh.parent = this._emitter as AbstractMesh; + } + + // Apply mesh material (set via meshMaterial before start()) + if (this._meshMaterial) { + this.mesh.material = this._meshMaterial; + } + } + + private _initializeDeadParticles(): void { + for (let i = 0; i < this.nbParticles; i++) { + const particle = this.particles[i]; + particle.alive = false; + particle.isVisible = false; + particle.age = 0; + particle.lifeTime = Infinity; + particle.position.setAll(0); + particle.velocity.setAll(0); + particle.rotation.setAll(0); + particle.scaling.setAll(1); + if (particle.color) { + particle.color.set(1, 1, 1, 1); + } else { + particle.color = new Color4(1, 1, 1, 1); + } + } + } + + private _resetEmissionState(): void { + this._emissionState.time = 0; + this._emissionState.waitEmiting = 0; + this._emissionState.travelDistance = 0; + this._emissionState.burstIndex = 0; + this._emissionState.burstWaveIndex = 0; + this._emissionState.burstParticleIndex = 0; + this._emissionState.burstParticleCount = 0; + this._emissionState.isBursting = false; + if (this.mesh && this.mesh.position) { + this._emissionState.previousWorldPos = this.mesh.position.clone(); + } + this._emitEnded = false; + } + + public override initParticles(): void { + this._setupMeshProperties(); + this._initializeDeadParticles(); + this._resetEmissionState(); + } + + /** + * Build per-particle behavior functions from configurations + * Per-particle behaviors run each frame for each particle + * "OverLife" behaviors are handled by gradients (system-level) + * + * IMPORTANT: Parse all values ONCE here, not every frame! + */ + private _buildPerParticleBehaviors(behaviors: Behavior[]): PerSolidParticleBehaviorFunction[] { + const functions: PerSolidParticleBehaviorFunction[] = []; + + for (const behavior of behaviors) { + switch (behavior.type) { + case "ForceOverLife": + case "ApplyForce": { + const b = behavior as IForceOverLifeBehavior; + // Pre-parse force values ONCE (not every frame!) + const forceX = b.x ?? b.force?.x; + const forceY = b.y ?? b.force?.y; + const forceZ = b.z ?? b.force?.z; + const fx = forceX !== undefined ? parseConstantValue(forceX) : 0; + const fy = forceY !== undefined ? parseConstantValue(forceY) : 0; + const fz = forceZ !== undefined ? parseConstantValue(forceZ) : 0; + + if (fx !== 0 || fy !== 0 || fz !== 0) { + // Capture 'this' to access _scaledUpdateSpeed + const system = this; + functions.push((particle: SolidParticle) => { + // Use _scaledUpdateSpeed for FPS-independent force application + const deltaTime = system._scaledUpdateSpeed || system.updateSpeed; + particle.velocity.x += fx * deltaTime; + particle.velocity.y += fy * deltaTime; + particle.velocity.z += fz * deltaTime; + }); + } + break; + } + + case "ColorBySpeed": { + const b = behavior as IColorBySpeedBehavior; + // Pre-parse min/max speed ONCE + const minSpeed = b.minSpeed !== undefined ? parseConstantValue(b.minSpeed) : 0; + const maxSpeed = b.maxSpeed !== undefined ? parseConstantValue(b.maxSpeed) : 1; + // New structure: b.color is IColorFunction with data.colorKeys + const colorKeys = b.color?.data?.colorKeys; + + if (colorKeys && colorKeys.length > 0) { + functions.push((particle: SolidParticle) => { + if (!particle.color) { + return; + } + const vel = particle.velocity; + const currentSpeed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z); + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + const interpolatedColor = interpolateColorKeys(colorKeys, speedRatio); + const startColor = particle.props?.startColor; + + if (startColor) { + particle.color.r = interpolatedColor.r * startColor.r; + particle.color.g = interpolatedColor.g * startColor.g; + particle.color.b = interpolatedColor.b * startColor.b; + particle.color.a = startColor.a; + } else { + particle.color.r = interpolatedColor.r; + particle.color.g = interpolatedColor.g; + particle.color.b = interpolatedColor.b; + } + }); + } + break; + } + + case "SizeBySpeed": { + const b = behavior as ISizeBySpeedBehavior; + // Pre-parse min/max speed ONCE + const minSpeed = b.minSpeed !== undefined ? parseConstantValue(b.minSpeed) : 0; + const maxSpeed = b.maxSpeed !== undefined ? parseConstantValue(b.maxSpeed) : 1; + const sizeKeys = b.size?.keys; + + if (sizeKeys && sizeKeys.length > 0) { + functions.push((particle: SolidParticle) => { + const vel = particle.velocity; + const currentSpeed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z); + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + const sizeMultiplier = interpolateGradientKeys(sizeKeys, speedRatio, extractNumberFromValue); + const startSize = particle.props?.startSize ?? 1; + const newSize = startSize * sizeMultiplier; + particle.scaling.setAll(newSize); + }); + } + break; + } + + case "RotationBySpeed": { + const b = behavior as IRotationBySpeedBehavior; + // Pre-parse values ONCE + const minSpeed = b.minSpeed !== undefined ? parseConstantValue(b.minSpeed) : 0; + const maxSpeed = b.maxSpeed !== undefined ? parseConstantValue(b.maxSpeed) : 1; + const angularVelocity = b.angularVelocity; + const hasKeys = + typeof angularVelocity === "object" && + angularVelocity !== null && + "keys" in angularVelocity && + Array.isArray(angularVelocity.keys) && + angularVelocity.keys.length > 0; + + // Pre-parse constant angular velocity if not using keys + let constantAngularSpeed = 0; + if (!hasKeys && angularVelocity) { + const parsed = parseIntervalValue(angularVelocity); + constantAngularSpeed = (parsed.min + parsed.max) / 2; + } + + const system = this; + functions.push((particle: SolidParticle) => { + const vel = particle.velocity; + const currentSpeed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z); + const deltaTime = system._scaledUpdateSpeed || system.updateSpeed; + + let angularSpeed = constantAngularSpeed; + if (hasKeys) { + const speedRatio = Math.max(0, Math.min(1, (currentSpeed - minSpeed) / (maxSpeed - minSpeed || 1))); + angularSpeed = interpolateGradientKeys((angularVelocity as any).keys, speedRatio, extractNumberFromValue); + } + + particle.rotation.z += angularSpeed * deltaTime; + }); + break; + } + + case "OrbitOverLife": { + const b = behavior as IOrbitOverLifeBehavior; + // Pre-parse constant values ONCE + const speed = b.speed !== undefined ? parseConstantValue(b.speed) : 1; + const centerX = b.center?.x ?? 0; + const centerY = b.center?.y ?? 0; + const centerZ = b.center?.z ?? 0; + const hasRadiusKeys = + b.radius !== undefined && + b.radius !== null && + typeof b.radius === "object" && + "keys" in b.radius && + Array.isArray(b.radius.keys) && + b.radius.keys.length > 0; + + // Pre-parse constant radius if not using keys + let constantRadius = 1; + if (!hasRadiusKeys && b.radius !== undefined) { + const parsed = parseIntervalValue(b.radius as Value); + constantRadius = (parsed.min + parsed.max) / 2; + } + + functions.push((particle: SolidParticle) => { + if (particle.lifeTime <= 0) { + return; + } + + const lifeRatio = particle.age / particle.lifeTime; + + // Get radius (from keys or constant) + let radius = constantRadius; + if (hasRadiusKeys) { + radius = interpolateGradientKeys((b.radius as any).keys, lifeRatio, extractNumberFromValue); + } + + const angle = lifeRatio * speed * Math.PI * 2; + + // Calculate orbit offset (NOT replacement!) + const orbitX = Math.cos(angle) * radius; + const orbitY = Math.sin(angle) * radius; + + // Store initial position if not stored yet + const props = (particle.props ||= {}) as any; + if (props.orbitInitialPos === undefined) { + props.orbitInitialPos = { + x: particle.position.x, + y: particle.position.y, + z: particle.position.z, + }; + } + + // Apply orbit as OFFSET from initial position (NOT replacement!) + particle.position.x = props.orbitInitialPos.x + centerX + orbitX; + particle.position.y = props.orbitInitialPos.y + centerY + orbitY; + particle.position.z = props.orbitInitialPos.z + centerZ; + }); + break; + } + } + } + + return functions; + } + + /** + * Apply system-level behaviors (gradients) to SolidParticleSystem + * These are applied once when behaviors change, not per-particle + * Similar to ParticleSystem native gradients + */ + private _applySystemLevelBehaviors(): void { + for (const behavior of this.behaviorConfigs) { + if (!behavior.type) { + continue; + } + + switch (behavior.type) { + case "ColorOverLife": + applyColorOverLifeSPS(this, behavior as any); + break; + case "SizeOverLife": + applySizeOverLifeSPS(this, behavior as any); + break; + case "RotationOverLife": + case "Rotation3DOverLife": + applyRotationOverLifeSPS(this, behavior as any); + break; + case "SpeedOverLife": + applySpeedOverLifeSPS(this, behavior as any); + break; + case "LimitSpeedOverLife": + applyLimitSpeedOverLifeSPS(this, behavior as any); + break; + } + } + } + + public override beforeUpdateParticles(start?: number, stop?: number, update?: boolean): void { + super.beforeUpdateParticles(start, stop, update); + + // Hide particles when stopped + if (this._stopped) { + const particles = this.particles; + const nbParticles = this.nbParticles; + for (let i = 0; i < nbParticles; i++) { + const particle = particles[i]; + if (particle.alive) { + particle.isVisible = false; + } + } + } + } + + /** + * Called AFTER particle updates in setParticles(). + * This is the correct place for emission because _scaledUpdateSpeed is already calculated. + */ + public override afterUpdateParticles(start?: number, stop?: number, update?: boolean): void { + super.afterUpdateParticles(start, stop, update); + + if (this._stopped || !this._started) { + return; + } + + // Use _scaledUpdateSpeed for emission (same as ThinParticleSystem) + // Now it's properly calculated by the base class + const deltaTime = this._scaledUpdateSpeed; + + // Debug logging (aggregated per second) + this._debugFrameCount++; + this._debugDeltaSum += deltaTime; + const now = performance.now(); + if (now - this._debugLastLog > 1000) { + this._debugLastLog = now; + this._debugFrameCount = 0; + this._debugDeltaSum = 0; + } + + this._emissionState.time += deltaTime; + + this._emit(deltaTime); + + this._handleEmissionLooping(); + } + + private _debugLastLog = 0; + private _debugFrameCount = 0; + private _debugDeltaSum = 0; + + private _updateParticle(particle: SolidParticle): SolidParticle { + if (!particle.alive) { + particle.isVisible = false; + + if (!particle._stillInvisible && this._positions32 && particle._model) { + const shape = particle._model._shape; + const startIdx = particle._pos; + const positions32 = this._positions32; + for (let pt = 0, len = shape.length; pt < len; pt++) { + const idx = startIdx + pt * 3; + positions32[idx] = positions32[idx + 1] = positions32[idx + 2] = 0; + } + particle._stillInvisible = true; + } + + return particle; + } + + const lifeRatio = particle.lifeTime > 0 ? particle.age / particle.lifeTime : 0; + + this._applyGradients(particle, lifeRatio); + + const particleWithSystem = particle as SolidParticleWithSystem; + particleWithSystem.system = this; + + const behaviors = this._behaviors; + for (let i = 0, len = behaviors.length; i < len; i++) { + behaviors[i](particle); + } + + const props = particle.props; + const speedModifier = props?.speedModifier ?? 1.0; + // Use _scaledUpdateSpeed for FPS-independent movement (like ParticleSystem) + const deltaTime = this._scaledUpdateSpeed || this.updateSpeed; + particle.position.addInPlace(particle.velocity.scale(deltaTime * speedModifier)); + + return particle; + } + + /** + * Apply gradients to particle based on lifeRatio + */ + private _applyGradients(particle: SolidParticle, lifeRatio: number): void { + const props = (particle.props ||= {}); + // Use _scaledUpdateSpeed for FPS-independent gradients + const deltaTime = this._scaledUpdateSpeed || this.updateSpeed; + + const color = this._colorGradients.getValue(lifeRatio); + if (color && particle.color) { + particle.color.copyFrom(color); + + const startColor = props.startColor; + if (startColor) { + particle.color.r *= startColor.r; + particle.color.g *= startColor.g; + particle.color.b *= startColor.b; + particle.color.a *= startColor.a; + } + } + + // Apply size gradients with scale modifiers (like ParticleSystem) + const size = this._sizeGradients.getValue(lifeRatio); + if (size !== null && props.startSize !== undefined) { + const scaleX = props.startScaleX ?? 1; + const scaleY = props.startScaleY ?? 1; + particle.scaling.set(props.startSize * size * scaleX, props.startSize * size * scaleY, props.startSize * size); + } + + const velocity = this._velocityGradients.getValue(lifeRatio); + if (velocity !== null) { + props.speedModifier = velocity; + } + + // Apply angular speed: use gradient if available, otherwise use particle's startAngularSpeed (like ParticleSystem) + const angularSpeedFromGradient = this._angularSpeedGradients.getValue(lifeRatio); + if (angularSpeedFromGradient !== null) { + particle.rotation.z += angularSpeedFromGradient * deltaTime; + } else if (props.startAngularSpeed !== undefined && props.startAngularSpeed !== 0) { + // Apply base angular speed (like ParticleSystem._ProcessAngularSpeed) + particle.rotation.z += props.startAngularSpeed * deltaTime; + } + + const limitVelocity = this._limitVelocityGradients.getValue(lifeRatio); + if (limitVelocity !== null && this._limitVelocityDamping > 0) { + const vel = particle.velocity; + const currentSpeed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z); + if (currentSpeed > limitVelocity) { + vel.scaleInPlace((limitVelocity / currentSpeed) * this._limitVelocityDamping); + } + } + } +} diff --git a/tools/src/effect/systems/index.ts b/tools/src/effect/systems/index.ts new file mode 100644 index 000000000..e0db1369e --- /dev/null +++ b/tools/src/effect/systems/index.ts @@ -0,0 +1,2 @@ +export { EffectParticleSystem } from "./effectParticleSystem"; +export { EffectSolidParticleSystem } from "./effectSolidParticleSystem"; diff --git a/tools/src/effect/types/behaviors.ts b/tools/src/effect/types/behaviors.ts new file mode 100644 index 000000000..0531e79e4 --- /dev/null +++ b/tools/src/effect/types/behaviors.ts @@ -0,0 +1,172 @@ +import type { Value } from "./values"; +import type { IGradientKey } from "./gradients"; +import { Particle } from "@babylonjs/core/Particles/particle"; +import { ParticleSystem } from "@babylonjs/core/Particles/particleSystem"; +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { SolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem"; + +/** + * Per-particle behavior function for ParticleSystem + * Behavior config is captured in closure, only particle is needed + */ +export type PerParticleBehaviorFunction = (particle: Particle) => void; + +/** + * Per-particle behavior function for SolidParticleSystem + * Behavior config is captured in closure, only particle is needed + */ +export type PerSolidParticleBehaviorFunction = (particle: SolidParticle) => void; + +/** + * System-level behavior function (applied once during initialization) + * Takes only system and behavior config - all data comes from system + */ +export type SystemBehaviorFunction = (system: ParticleSystem | SolidParticleSystem, behavior: Behavior) => void; + +/** + * behavior types (converted from Quarks) + */ +/** + * Color function - unified structure for all color-related behaviors + */ +export interface IColorFunction { + colorFunctionType: "Gradient" | "ConstantColor" | "ColorRange" | "RandomColor" | "RandomColorBetweenGradient"; + data: { + color?: { r: number; g: number; b: number; a: number }; + colorA?: { r: number; g: number; b: number; a: number }; + colorB?: { r: number; g: number; b: number; a: number }; + colorKeys?: IGradientKey[]; + alphaKeys?: IGradientKey[]; + gradient1?: { + colorKeys?: IGradientKey[]; + alphaKeys?: IGradientKey[]; + }; + gradient2?: { + colorKeys?: IGradientKey[]; + alphaKeys?: IGradientKey[]; + }; + }; +} + +export interface IColorOverLifeBehavior { + type: "ColorOverLife"; + color: IColorFunction; +} + +export interface ISizeOverLifeBehavior { + type: "SizeOverLife"; + size?: { + keys?: IGradientKey[]; + functions?: Array<{ + start: number; + function: { + p0?: number; + p3?: number; + }; + }>; + }; +} + +export interface IRotationOverLifeBehavior { + type: "RotationOverLife" | "Rotation3DOverLife"; + angularVelocity?: Value; +} + +export interface IForceOverLifeBehavior { + type: "ForceOverLife" | "ApplyForce"; + force?: { + x?: Value; + y?: Value; + z?: Value; + }; + x?: Value; + y?: Value; + z?: Value; +} + +export interface IGravityForceBehavior { + type: "GravityForce"; + gravity?: Value; +} + +export interface ISpeedOverLifeBehavior { + type: "SpeedOverLife"; + speed?: + | { + keys?: IGradientKey[]; + functions?: Array<{ + start: number; + function: { + p0?: number; + p3?: number; + }; + }>; + } + | Value; +} + +export interface IFrameOverLifeBehavior { + type: "FrameOverLife"; + frame?: + | { + keys?: IGradientKey[]; + } + | Value; +} + +export interface ILimitSpeedOverLifeBehavior { + type: "LimitSpeedOverLife"; + maxSpeed?: Value; + speed?: Value | { keys?: IGradientKey[] }; + dampen?: Value; +} + +export interface IColorBySpeedBehavior { + type: "ColorBySpeed"; + color: IColorFunction; + minSpeed?: Value; + maxSpeed?: Value; + speedRange?: { min: number; max: number }; +} + +export interface ISizeBySpeedBehavior { + type: "SizeBySpeed"; + size?: { + keys: IGradientKey[]; + }; + minSpeed?: Value; + maxSpeed?: Value; +} + +export interface IRotationBySpeedBehavior { + type: "RotationBySpeed"; + angularVelocity?: Value; + minSpeed?: Value; + maxSpeed?: Value; +} + +export interface IOrbitOverLifeBehavior { + type: "OrbitOverLife"; + center?: { + x?: number; + y?: number; + z?: number; + }; + radius?: Value | { keys?: IGradientKey[] }; + speed?: Value; +} + +export type Behavior = + | IColorOverLifeBehavior + | ISizeOverLifeBehavior + | IRotationOverLifeBehavior + | IForceOverLifeBehavior + | IGravityForceBehavior + | ISpeedOverLifeBehavior + | IFrameOverLifeBehavior + | ILimitSpeedOverLifeBehavior + | IColorBySpeedBehavior + | ISizeBySpeedBehavior + | IRotationBySpeedBehavior + | IOrbitOverLifeBehavior + | { type: string; [key: string]: unknown }; // Fallback for unknown behaviors diff --git a/tools/src/effect/types/colors.ts b/tools/src/effect/types/colors.ts new file mode 100644 index 000000000..304f99201 --- /dev/null +++ b/tools/src/effect/types/colors.ts @@ -0,0 +1,41 @@ +import type { IGradientKey } from "./gradients"; + +/** + * color types (converted from Quarks) + */ +export interface IConstantColor { + type: "ConstantColor"; + value: [number, number, number, number]; // RGBA +} + +export interface IColorRange { + type: "ColorRange"; + colorA: [number, number, number, number]; // RGBA + colorB: [number, number, number, number]; // RGBA +} + +export interface IGradientColor { + type: "Gradient"; + colorKeys: IGradientKey[]; + alphaKeys?: IGradientKey[]; +} + +export interface IRandomColor { + type: "RandomColor"; + colorA: [number, number, number, number]; // RGBA + colorB: [number, number, number, number]; // RGBA +} + +export interface IRandomColorBetweenGradient { + type: "RandomColorBetweenGradient"; + gradient1: { + colorKeys: IGradientKey[]; + alphaKeys?: IGradientKey[]; + }; + gradient2: { + colorKeys: IGradientKey[]; + alphaKeys?: IGradientKey[]; + }; +} + +export type Color = IConstantColor | IColorRange | IGradientColor | IRandomColor | IRandomColorBetweenGradient | [number, number, number, number] | string; diff --git a/tools/src/effect/types/emitter.ts b/tools/src/effect/types/emitter.ts new file mode 100644 index 000000000..e7f0dc090 --- /dev/null +++ b/tools/src/effect/types/emitter.ts @@ -0,0 +1,118 @@ +import { Nullable } from "@babylonjs/core/types"; +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; +import { Vector3 } from "@babylonjs/core/Maths/math.vector"; +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import type { IEmitter } from "./hierarchy"; +import type { Value } from "./values"; +import type { IShape } from "./shapes"; +import type { Behavior } from "./behaviors"; + +/** + * emission burst (converted from Quarks) + */ +export interface IEmissionBurst { + time: Value; + count: Value; +} + +/** + * Particle system configuration (converted from Quarks to native Babylon.js properties) + */ +export interface IParticleSystemConfig { + version?: string; + systemType: "solid" | "base"; + + // === Native Babylon.js properties (converted from Quarks Value) === + + // Life & Size + minLifeTime?: number; + maxLifeTime?: number; + minSize?: number; + maxSize?: number; + minScaleX?: number; + maxScaleX?: number; + minScaleY?: number; + maxScaleY?: number; + + // Speed & Power + minEmitPower?: number; + maxEmitPower?: number; + emitRate?: number; + + // Rotation + minInitialRotation?: number; + maxInitialRotation?: number; + minAngularSpeed?: number; + maxAngularSpeed?: number; + + // Color + color1?: Color4; + color2?: Color4; + colorDead?: Color4; + + // Duration & Looping + targetStopDuration?: number; // 0 = infinite (looping), >0 = duration + manualEmitCount?: number; // -1 = automatic, otherwise specific count + + // Prewarm + preWarmCycles?: number; + preWarmStepOffset?: number; + + // Physics + gravity?: Vector3; + noiseStrength?: Vector3; + updateSpeed?: number; + + // World space + isLocal?: boolean; + + // Auto destroy + disposeOnStop?: boolean; + + // Gradients for PiecewiseBezier + startSizeGradients?: Array<{ gradient: number; factor: number; factor2?: number }>; + lifeTimeGradients?: Array<{ gradient: number; factor: number; factor2?: number }>; + emitRateGradients?: Array<{ gradient: number; factor: number; factor2?: number }>; + + // === Other properties === + shape?: IShape; + emissionBursts?: IEmissionBurst[]; + emissionOverDistance?: Value; // For solid system only + instancingGeometry?: string; // Custom geometry ID for SPS + renderOrder?: number; + layers?: number; + isBillboardBased?: boolean; + billboardMode?: number; + // Sprite animation (ParticleSystem only) + startTileIndex?: Value; + uTileCount?: number; + vTileCount?: number; + // Behaviors + behaviors?: Behavior[]; +} + +/** + * Data structure for emitter creation + */ +export interface IEmitterData { + name: string; + config: IParticleSystemConfig; + materialId?: string; + matrix?: number[]; + position?: number[]; + parentGroup: Nullable; + cumulativeScale: Vector3; + emitter?: IEmitter; +} + +/** + * Interface for SolidParticleSystem emitter types + * Similar to IParticleEmitterType for ParticleSystem + */ +export interface ISolidParticleEmitterType { + /** + * Initialize particle position and velocity based on emitter shape + */ + initializeParticle(particle: SolidParticle, startSpeed: number): void; +} diff --git a/tools/src/effect/types/factories.ts b/tools/src/effect/types/factories.ts new file mode 100644 index 000000000..3fb37c00e --- /dev/null +++ b/tools/src/effect/types/factories.ts @@ -0,0 +1,18 @@ +import { Mesh } from "@babylonjs/core/Meshes/mesh"; +import { PBRMaterial } from "@babylonjs/core/Materials/PBR/pbrMaterial"; +import { Texture } from "@babylonjs/core/Materials/Textures/texture"; +import { Scene } from "@babylonjs/core/scene"; + +/** + * Factory interfaces for dependency injection + */ +export interface IMaterialFactory { + createMaterial(materialId: string | undefined, name: string): PBRMaterial; + createTexture(materialId: string): Texture; + getBlendMode(materialId: string): number | undefined; +} + +export interface IGeometryFactory { + createMesh(geometryId: string, name: string, scene: Scene): Mesh; + createParticleMesh(name: string, scene: Scene, instancingGeometry?: string): Mesh; +} diff --git a/tools/src/effect/types/gradients.ts b/tools/src/effect/types/gradients.ts new file mode 100644 index 000000000..ff5467855 --- /dev/null +++ b/tools/src/effect/types/gradients.ts @@ -0,0 +1,8 @@ +/** + * gradient key (converted from Quarks) + */ +export interface IGradientKey { + time?: number; + value: number | [number, number, number, number] | { r: number; g: number; b: number; a?: number }; + pos?: number; +} diff --git a/tools/src/effect/types/hierarchy.ts b/tools/src/effect/types/hierarchy.ts new file mode 100644 index 000000000..cb2141fb6 --- /dev/null +++ b/tools/src/effect/types/hierarchy.ts @@ -0,0 +1,48 @@ +import { Quaternion, Vector3 } from "@babylonjs/core/Maths/math.vector"; +import type { IParticleSystemConfig } from "./emitter"; +import type { IMaterial, ITexture, IImage, IGeometry } from "./resources"; + +/** + * transform (converted from Quarks, left-handed coordinate system) + */ +export interface ITransform { + position: Vector3; + rotation: Quaternion; + scale: Vector3; +} + +/** + * group (converted from Quarks) + */ +export interface IGroup { + uuid: string; + name: string; + transform: ITransform; + children: (IGroup | IEmitter)[]; +} + +/** + * emitter (converted from Quarks) + */ +export interface IEmitter { + uuid: string; + name: string; + transform: ITransform; + config: IParticleSystemConfig; + materialId?: string; + parentUuid?: string; + systemType: "solid" | "base"; // Determined from renderMode: 2 = solid, otherwise base + matrix?: number[]; // Original Three.js matrix array for rotation extraction +} + +/** + * data (converted from Quarks) + * Contains the converted structure with groups, emitters, and resources + */ +export interface IData { + root: IGroup | IEmitter | null; + materials: IMaterial[]; + textures: ITexture[]; + images: IImage[]; + geometries: IGeometry[]; +} diff --git a/tools/src/effect/types/index.ts b/tools/src/effect/types/index.ts new file mode 100644 index 000000000..20812df0d --- /dev/null +++ b/tools/src/effect/types/index.ts @@ -0,0 +1,11 @@ +export * from "./values"; +export * from "./colors"; +export * from "./rotations"; +export * from "./gradients"; +export * from "./shapes"; +export * from "./behaviors"; +export * from "./emitter"; +export * from "./system"; +export * from "./hierarchy"; +export * from "./resources"; +export * from "./factories"; diff --git a/tools/src/effect/types/resources.ts b/tools/src/effect/types/resources.ts new file mode 100644 index 000000000..cfa14e87f --- /dev/null +++ b/tools/src/effect/types/resources.ts @@ -0,0 +1,84 @@ +import { Color3 } from "@babylonjs/core/Maths/math.color"; + +/** + * Material (converted from Quarks, ready for Babylon.js) + */ +export interface IMaterial { + uuid: string; + type?: string; + color?: Color3; // Converted from hex/array to Color3 + opacity?: number; + transparent?: boolean; + depthWrite?: boolean; + side?: number; + blending?: number; // Converted to Babylon.js constants + map?: string; // Texture UUID reference +} + +/** + * Texture (converted from Quarks, ready for Babylon.js) + */ +export interface ITexture { + uuid: string; + image?: string; // Image UUID reference + wrapU?: number; // Converted to Babylon.js wrap mode + wrapV?: number; // Converted to Babylon.js wrap mode + uScale?: number; // From repeat[0] + vScale?: number; // From repeat[1] + uOffset?: number; // From offset[0] + vOffset?: number; // From offset[1] + uAng?: number; // From rotation + coordinatesIndex?: number; // From channel + samplingMode?: number; // Converted from Three.js filters to Babylon.js sampling mode + generateMipmaps?: boolean; + flipY?: boolean; +} + +/** + * Image (converted from Quarks, normalized URL) + */ +export interface IImage { + uuid: string; + url: string; // Normalized URL (ready for use) +} + +/** + * Geometry Attribute Data + */ +export interface IGeometryAttribute { + array: number[]; + itemSize?: number; +} + +/** + * Geometry Index Data + */ +export interface IGeometryIndex { + array: number[]; +} + +/** + * Geometry Data (converted from Quarks, left-handed coordinate system) + */ +export interface IGeometryData { + attributes: { + position?: IGeometryAttribute; + normal?: IGeometryAttribute; + uv?: IGeometryAttribute; + color?: IGeometryAttribute; + }; + index?: IGeometryIndex; +} + +/** + * Geometry (converted from Quarks, ready for Babylon.js) + */ +export interface IGeometry { + uuid: string; + type: "PlaneGeometry" | "BufferGeometry"; + // For PlaneGeometry + width?: number; + height?: number; + // For BufferGeometry (already converted to left-handed) + data?: IGeometryData; +} diff --git a/tools/src/effect/types/rotations.ts b/tools/src/effect/types/rotations.ts new file mode 100644 index 000000000..92b7a6a56 --- /dev/null +++ b/tools/src/effect/types/rotations.ts @@ -0,0 +1,26 @@ +import type { Value } from "./values"; + +/** + * rotation types (converted from Quarks) + */ +export interface IEulerRotation { + type: "Euler"; + angleX?: Value; + angleY?: Value; + angleZ?: Value; + order?: "xyz" | "zyx"; +} + +export interface IAxisAngleRotation { + type: "AxisAngle"; + x?: Value; + y?: Value; + z?: Value; + angle?: Value; +} + +export interface IRandomQuatRotation { + type: "RandomQuat"; +} + +export type Rotation = IEulerRotation | IAxisAngleRotation | IRandomQuatRotation | Value; diff --git a/tools/src/effect/types/shapes.ts b/tools/src/effect/types/shapes.ts new file mode 100644 index 000000000..04232da8f --- /dev/null +++ b/tools/src/effect/types/shapes.ts @@ -0,0 +1,17 @@ +import type { Value } from "./values"; + +/** + * shape configuration (converted from Quarks) + */ +export interface IShape { + type: string; + radius?: number; + arc?: number; + thickness?: number; + angle?: number; + mode?: number; + spread?: number; + speed?: Value; + size?: number[]; + height?: number; +} diff --git a/tools/src/effect/types/system.ts b/tools/src/effect/types/system.ts new file mode 100644 index 000000000..d153316b9 --- /dev/null +++ b/tools/src/effect/types/system.ts @@ -0,0 +1,67 @@ +import { TransformNode } from "@babylonjs/core/Meshes/transformNode"; +import { Particle } from "@babylonjs/core/Particles/particle"; +import { SolidParticle } from "@babylonjs/core/Particles/solidParticle"; +import type { EffectParticleSystem, EffectSolidParticleSystem } from "../systems"; + +/** + * Common interface for all particle systems + * Provides type-safe access to common properties and methods + */ +export interface ISystem { + /** System name */ + name: string; + /** Start the particle system */ + start(): void; + /** Stop the particle system */ + stop(): void; + /** Dispose the particle system */ + dispose(): void; +} + +/** + * Extended Particle type with system reference + * Used for behaviors that need access to the particle system + * Uses intersection type to add custom property without conflicting with base type + */ +export type ParticleWithSystem = Particle & { + particleSystem?: EffectParticleSystem; +}; + +/** + * Extended SolidParticle type with system reference + * Used for behaviors that need access to the solid particle system + * Uses intersection type to add custom property without conflicting with base type + */ +export type SolidParticleWithSystem = SolidParticle & { + system?: EffectSolidParticleSystem; +}; + +/** + * Type guard to check if a system implements ISystem + */ +export function isSystem(system: unknown): system is ISystem { + return ( + typeof system === "object" && + system !== null && + "start" in system && + typeof (system as ISystem).start === "function" && + "stop" in system && + typeof (system as ISystem).stop === "function" + ); +} + +/** + * Effect Node - represents either a particle system or a group + */ +export interface IEffectNode { + /** Node name */ + name: string; + /** Node UUID from original JSON */ + uuid: string; + /** Particle system (if this is a particle emitter) */ + data: EffectParticleSystem | EffectSolidParticleSystem | TransformNode; + /** Child nodes */ + children: IEffectNode[]; + /** Node type */ + type: "particle" | "group"; +} diff --git a/tools/src/effect/types/values.ts b/tools/src/effect/types/values.ts new file mode 100644 index 000000000..3b300e578 --- /dev/null +++ b/tools/src/effect/types/values.ts @@ -0,0 +1,27 @@ +/** + * value types (converted from Quarks) + */ +export interface IConstantValue { + type: "ConstantValue"; + value: number; +} + +export interface IIntervalValue { + type: "IntervalValue"; + min: number; + max: number; +} + +export interface IPiecewiseBezier { + type: "PiecewiseBezier"; + functions: Array<{ + function: { + p0: number; + p1: number; + p2: number; + p3: number; + }; + start: number; + }>; +} +export type Value = IConstantValue | IIntervalValue | IPiecewiseBezier | number; diff --git a/tools/src/effect/utils/capacityCalculator.ts b/tools/src/effect/utils/capacityCalculator.ts new file mode 100644 index 000000000..8fa4280b4 --- /dev/null +++ b/tools/src/effect/utils/capacityCalculator.ts @@ -0,0 +1,27 @@ +import { parseConstantValue } from "./valueParser"; +import type { Value } from "../types/values"; + +/** + * Calculate capacity for ParticleSystem + * Formula: emissionRate * duration * 2 (for non-looping systems) + */ +export function calculateForParticleSystem(emissionOverTime: Value | undefined, duration: number): number { + const emissionRate = emissionOverTime !== undefined ? parseConstantValue(emissionOverTime) : 10; + return Math.ceil(emissionRate * duration * 2); +} + +/** + * Calculate capacity for SolidParticleSystem + * Formula depends on looping: + * - Looping: max(emissionRate * particleLifetime, 1) + * - Non-looping: emissionRate * particleLifetime * 2 + */ +export function calculateForSolidParticleSystem(emissionOverTime: Value | undefined, duration: number, isLooping: boolean): number { + const emissionRate = emissionOverTime !== undefined ? parseConstantValue(emissionOverTime) : 10; + const particleLifetime = duration || 5; + + if (isLooping) { + return Math.max(Math.ceil(emissionRate * particleLifetime), 1); + } + return Math.ceil(emissionRate * particleLifetime * 2); +} diff --git a/tools/src/effect/utils/deserializer.ts b/tools/src/effect/utils/deserializer.ts new file mode 100644 index 000000000..bee8693c6 --- /dev/null +++ b/tools/src/effect/utils/deserializer.ts @@ -0,0 +1,186 @@ +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { Vector3, Quaternion } from "@babylonjs/core/Maths/math.vector"; +import type { IData, IParticleSystemConfig, ITransform, IGroup, IEmitter } from "../types"; + +/** + * Deserialize Color4 from JSON (supports both object {r,g,b,a} and array [r,g,b,a] formats) + */ +export function deserializeColor4(value: any): Color4 | undefined { + if (!value) { + return undefined; + } + if (value instanceof Color4) { + return value; + } + if (Array.isArray(value)) { + return new Color4(value[0] ?? 1, value[1] ?? 1, value[2] ?? 1, value[3] ?? 1); + } + if (typeof value === "object") { + return new Color4(value.r ?? value[0] ?? 1, value.g ?? value[1] ?? 1, value.b ?? value[2] ?? 1, value.a ?? value[3] ?? 1); + } + return undefined; +} + +/** + * Deserialize Vector3 from JSON (supports both object {x,y,z} and array [x,y,z] formats) + */ +export function deserializeVector3(value: any): Vector3 | undefined { + if (!value) { + return undefined; + } + if (value instanceof Vector3) { + return value; + } + if (Array.isArray(value)) { + return new Vector3(value[0] ?? 0, value[1] ?? 0, value[2] ?? 0); + } + if (typeof value === "object") { + return new Vector3(value.x ?? value[0] ?? 0, value.y ?? value[1] ?? 0, value.z ?? value[2] ?? 0); + } + return undefined; +} + +/** + * Deserialize Quaternion from JSON (supports both object {x,y,z,w} and array [x,y,z,w] formats) + */ +export function deserializeQuaternion(value: any): Quaternion | undefined { + if (!value) { + return undefined; + } + if (value instanceof Quaternion) { + return value; + } + if (Array.isArray(value)) { + return new Quaternion(value[0] ?? 0, value[1] ?? 0, value[2] ?? 0, value[3] ?? 1); + } + if (typeof value === "object") { + return new Quaternion(value.x ?? value[0] ?? 0, value.y ?? value[1] ?? 0, value.z ?? value[2] ?? 0, value.w ?? value[3] ?? 1); + } + return undefined; +} + +/** + * Deserialize ITransform from JSON + */ +export function deserializeTransform(transform: any): ITransform { + if (!transform) { + return { + position: Vector3.Zero(), + rotation: Quaternion.Identity(), + scale: Vector3.One(), + }; + } + + return { + position: deserializeVector3(transform.position) || Vector3.Zero(), + rotation: deserializeQuaternion(transform.rotation) || Quaternion.Identity(), + scale: deserializeVector3(transform.scale) || Vector3.One(), + }; +} + +/** + * Deserialize IParticleSystemConfig from JSON + * Converts Color4, Vector3 from plain objects/arrays to proper class instances + */ +export function deserializeParticleSystemConfig(config: any): IParticleSystemConfig { + if (!config) { + return { + systemType: "base", + }; + } + + const deserialized: IParticleSystemConfig = { + ...config, + }; + + // Deserialize colors + if (config.color1 !== undefined) { + deserialized.color1 = deserializeColor4(config.color1); + } + if (config.color2 !== undefined) { + deserialized.color2 = deserializeColor4(config.color2); + } + if (config.colorDead !== undefined) { + deserialized.colorDead = deserializeColor4(config.colorDead); + } + + // Deserialize vectors + if (config.gravity !== undefined) { + deserialized.gravity = deserializeVector3(config.gravity); + } + if (config.noiseStrength !== undefined) { + deserialized.noiseStrength = deserializeVector3(config.noiseStrength); + } + + return deserialized; +} + +/** + * Deserialize IEmitter from JSON + */ +export function deserializeEmitter(emitter: any): IEmitter { + if (!emitter) { + throw new Error("Cannot deserialize null emitter"); + } + + return { + ...emitter, + transform: deserializeTransform(emitter.transform), + config: deserializeParticleSystemConfig(emitter.config), + }; +} + +/** + * Deserialize IGroup from JSON (recursively) + */ +export function deserializeGroup(group: any): IGroup { + if (!group) { + throw new Error("Cannot deserialize null group"); + } + + return { + ...group, + transform: deserializeTransform(group.transform), + children: group.children?.map((child: any) => { + if (child.children !== undefined) { + return deserializeGroup(child); + } + return deserializeEmitter(child); + }) || [], + }; +} + +/** + * Deserialize IData from JSON + * Converts all Color4, Vector3, Quaternion from plain objects/arrays to proper class instances + */ +export function deserializeData(data: any): IData { + if (!data) { + return { + root: null, + materials: [], + textures: [], + images: [], + geometries: [], + }; + } + + const deserialized: IData = { + materials: data.materials || [], + textures: data.textures || [], + images: data.images || [], + geometries: data.geometries || [], + root: null, + }; + + // Deserialize root (can be IGroup or IEmitter) + if (data.root) { + if (data.root.children !== undefined) { + deserialized.root = deserializeGroup(data.root); + } else { + deserialized.root = deserializeEmitter(data.root); + } + } + + return deserialized; +} diff --git a/tools/src/effect/utils/gradientSystem.ts b/tools/src/effect/utils/gradientSystem.ts new file mode 100644 index 000000000..3bdcc4c3a --- /dev/null +++ b/tools/src/effect/utils/gradientSystem.ts @@ -0,0 +1,99 @@ +import { Color4 } from "@babylonjs/core/Maths/math.color"; + +/** + * Generic gradient system for storing and interpolating gradient values + * Similar to Babylon.js native gradients but for SolidParticleSystem + */ +export class GradientSystem { + private _gradients: Array<{ gradient: number; value: T }>; + + constructor() { + this._gradients = []; + } + + /** + * Add a gradient point + */ + public addGradient(gradient: number, value: T): void { + // Insert in sorted order + const index = this._gradients.findIndex((g) => g.gradient > gradient); + if (index === -1) { + this._gradients.push({ gradient, value }); + } else { + this._gradients.splice(index, 0, { gradient, value }); + } + } + + /** + * Get interpolated value at given gradient position (0-1) + */ + public getValue(gradient: number): T | null { + if (this._gradients.length === 0) { + return null; + } + + if (this._gradients.length === 1) { + return this._gradients[0].value; + } + + // Clamp gradient to [0, 1] + const clampedGradient = Math.max(0, Math.min(1, gradient)); + + // Find the two gradients to interpolate between + for (let i = 0; i < this._gradients.length - 1; i++) { + const g1 = this._gradients[i]; + const g2 = this._gradients[i + 1]; + + if (clampedGradient >= g1.gradient && clampedGradient <= g2.gradient) { + const t = g2.gradient - g1.gradient !== 0 ? (clampedGradient - g1.gradient) / (g2.gradient - g1.gradient) : 0; + return this.interpolate(g1.value, g2.value, t); + } + } + + // Clamp to first or last gradient + if (clampedGradient <= this._gradients[0].gradient) { + return this._gradients[0].value; + } + return this._gradients[this._gradients.length - 1].value; + } + + /** + * Clear all gradients + */ + public clear(): void { + this._gradients = []; + } + + /** + * Get all gradients (for debugging) + */ + public getGradients(): Array<{ gradient: number; value: T }> { + return [...this._gradients]; + } + + /** + * Interpolate between two values (to be overridden by subclasses) + */ + protected interpolate(value1: T, _value2: T, _t: number): T { + // Default implementation - should be overridden + return value1; + } +} + +/** + * Color gradient system for Color4 + */ +export class ColorGradientSystem extends GradientSystem { + protected interpolate(value1: Color4, value2: Color4, t: number): Color4 { + return new Color4(value1.r + (value2.r - value1.r) * t, value1.g + (value2.g - value1.g) * t, value1.b + (value2.b - value1.b) * t, value1.a + (value2.a - value1.a) * t); + } +} + +/** + * Number gradient system + */ +export class NumberGradientSystem extends GradientSystem { + protected interpolate(value1: number, value2: number, t: number): number { + return value1 + (value2 - value1) * t; + } +} diff --git a/tools/src/effect/utils/index.ts b/tools/src/effect/utils/index.ts new file mode 100644 index 000000000..f57f2165b --- /dev/null +++ b/tools/src/effect/utils/index.ts @@ -0,0 +1,4 @@ +export * from "./valueParser"; +export * from "./capacityCalculator"; +export * from "./gradientSystem"; +export * from "./deserializer"; diff --git a/tools/src/effect/utils/valueParser.ts b/tools/src/effect/utils/valueParser.ts new file mode 100644 index 000000000..8670344bd --- /dev/null +++ b/tools/src/effect/utils/valueParser.ts @@ -0,0 +1,189 @@ +import { Color4 } from "@babylonjs/core/Maths/math.color"; +import { ColorGradient } from "@babylonjs/core/Misc/gradients"; +import type { IPiecewiseBezier, Value, Color, IGradientKey } from "../types"; + +/** + * Parse a constant value + */ +export function parseConstantValue(value: Value): number { + if (value && typeof value === "object" && value.type === "ConstantValue") { + return value.value || 0; + } + return typeof value === "number" ? value : 0; +} + +/** + * Parse an interval value (returns min and max) + */ +export function parseIntervalValue(value: Value): { min: number; max: number } { + if (value && typeof value === "object" && "type" in value && value.type === "IntervalValue") { + return { + min: value.min ?? 0, + max: value.max ?? 0, + }; + } + const constant = parseConstantValue(value); + return { min: constant, max: constant }; +} + +/** + * Parse a constant color + * Supports formats: + * - { type: "ConstantColor", value: [r, g, b, a] } + * - { type: "ConstantColor", color: { r, g, b, a } } + * - [r, g, b, a] (array) + */ +export function parseConstantColor(value: Color): Color4 { + if (value && typeof value === "object" && !Array.isArray(value)) { + if ("type" in value && value.type === "ConstantColor") { + // Format: { type: "ConstantColor", value: [r, g, b, a] } + if (value.value && Array.isArray(value.value)) { + return new Color4(value.value[0] || 0, value.value[1] || 0, value.value[2] || 0, value.value[3] !== undefined ? value.value[3] : 1); + } + // Format: { type: "ConstantColor", color: { r, g, b, a } } + const anyValue = value as any; + if (anyValue.color && typeof anyValue.color === "object") { + return new Color4(anyValue.color.r ?? 1, anyValue.color.g ?? 1, anyValue.color.b ?? 1, anyValue.color.a !== undefined ? anyValue.color.a : 1); + } + } + } + // Array format [r, g, b, a?] + if (Array.isArray(value) && value.length >= 3) { + return new Color4(value[0] || 0, value[1] || 0, value[2] || 0, value[3] !== undefined ? value[3] : 1); + } + return new Color4(1, 1, 1, 1); +} + +/** + * Parse a value for particle spawn (returns a single value based on type) + * Handles ConstantValue, IntervalValue, PiecewiseBezier, and number + * @param value The value to parse + * @param normalizedTime Normalized time (0-1) for PiecewiseBezier, default is random for IntervalValue + */ +export function parseValue(value: Value, normalizedTime?: number): number { + if (!value || typeof value === "number") { + return typeof value === "number" ? value : 0; + } + + if (value.type === "ConstantValue") { + return value.value || 0; + } + + if (value.type === "IntervalValue") { + const min = value.min ?? 0; + const max = value.max ?? 0; + return min + Math.random() * (max - min); + } + + if (value.type === "PiecewiseBezier") { + // Use provided normalizedTime or random for spawn + const t = normalizedTime !== undefined ? normalizedTime : Math.random(); + return evaluatePiecewiseBezier(value, t); + } + + // Fallback + return 0; +} + +/** + * Evaluate PiecewiseBezier at normalized time t (0-1) + */ +function evaluatePiecewiseBezier(bezier: IPiecewiseBezier, t: number): number { + if (!bezier.functions || bezier.functions.length === 0) { + return 0; + } + + // Clamp t to [0, 1] + const clampedT = Math.max(0, Math.min(1, t)); + + // Find which function segment contains t + let segmentIndex = -1; + for (let i = 0; i < bezier.functions.length; i++) { + const func = bezier.functions[i]; + const start = func.start; + const end = i < bezier.functions.length - 1 ? bezier.functions[i + 1].start : 1; + + if (clampedT >= start && clampedT < end) { + segmentIndex = i; + break; + } + } + + // If t is at the end (1.0), use last segment + if (segmentIndex === -1 && clampedT >= 1) { + segmentIndex = bezier.functions.length - 1; + } + + // If still not found, use first segment + if (segmentIndex === -1) { + segmentIndex = 0; + } + + const func = bezier.functions[segmentIndex]; + const start = func.start; + const end = segmentIndex < bezier.functions.length - 1 ? bezier.functions[segmentIndex + 1].start : 1; + + // Normalize t within this segment + const segmentT = end > start ? (clampedT - start) / (end - start) : 0; + + // Evaluate cubic Bezier: B(t) = (1-t)³P₀ + 3(1-t)²tP₁ + 3(1-t)t²P₂ + t³P₃ + const p0 = func.function.p0; + const p1 = func.function.p1; + const p2 = func.function.p2; + const p3 = func.function.p3; + + const t2 = segmentT * segmentT; + const t3 = t2 * segmentT; + const mt = 1 - segmentT; + const mt2 = mt * mt; + const mt3 = mt2 * mt; + + return mt3 * p0 + 3 * mt2 * segmentT * p1 + 3 * mt * t2 * p2 + t3 * p3; +} + +/** + * Parse gradient color keys + */ +export function parseGradientColorKeys(keys: IGradientKey[]): ColorGradient[] { + const gradients: ColorGradient[] = []; + for (const key of keys) { + const pos = key.pos ?? key.time ?? 0; + if (key.value !== undefined && pos !== undefined) { + let color4: Color4; + if (typeof key.value === "number") { + // Single number - grayscale + color4 = new Color4(key.value, key.value, key.value, 1); + } else if (Array.isArray(key.value)) { + // Array format [r, g, b, a?] + color4 = new Color4(key.value[0] || 0, key.value[1] || 0, key.value[2] || 0, key.value[3] !== undefined ? key.value[3] : 1); + } else { + // Object format { r, g, b, a? } + color4 = new Color4(key.value.r || 0, key.value.g || 0, key.value.b || 0, key.value.a !== undefined ? key.value.a : 1); + } + gradients.push(new ColorGradient(pos, color4)); + } + } + return gradients; +} + +/** + * Parse gradient alpha keys + */ +export function parseGradientAlphaKeys(keys: IGradientKey[]): { gradient: number; factor: number }[] { + const gradients: { gradient: number; factor: number }[] = []; + for (const key of keys) { + const pos = key.pos ?? key.time ?? 0; + if (key.value !== undefined && pos !== undefined) { + let factor: number; + if (typeof key.value === "number") { + factor = key.value; + } else if (Array.isArray(key.value)) { + factor = key.value[3] !== undefined ? key.value[3] : 1; + } else { + factor = key.value.a !== undefined ? key.value.a : 1; + } + gradients.push({ gradient: pos, factor }); + } + } + return gradients; +} diff --git a/tools/src/index.ts b/tools/src/index.ts index 93161fbca..e25cadc50 100644 --- a/tools/src/index.ts +++ b/tools/src/index.ts @@ -34,3 +34,5 @@ export * from "./cinematic/typings"; export * from "./cinematic/generate"; export * from "./cinematic/guards"; export * from "./cinematic/cinematic"; + +export * from "./effect"; diff --git a/yarn.lock b/yarn.lock index f185504e3..4d0f9c735 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,24 +7,11 @@ resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.2.0.tgz#7a03314684dd6572b7dfa89e68ce31d60286854d" integrity sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A== -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - "@alloc/quick-lru@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - "@aws-crypto/crc32@5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@aws-crypto/crc32/-/crc32-5.2.0.tgz#cfcc22570949c98c6689cfcbd2d693d36cdae2e1" @@ -154,44 +141,44 @@ "@smithy/util-waiter" "^4.2.8" tslib "^2.6.2" -"@aws-sdk/client-sso@3.975.0": - version "3.975.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.975.0.tgz#f22aca83b566fb5ced2c974020c42be60b350782" - integrity sha512-HpgJuleH7P6uILxzJKQOmlHdwaCY+xYC6VgRDzlwVEqU/HXjo4m2gOAyjUbpXlBOCWfGgMUzfBlNJ9z3MboqEQ== +"@aws-sdk/client-sso@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.989.0.tgz#d5dce053b4cac2d6c1b0f25a6609e74e795df74c" + integrity sha512-3sC+J1ru5VFXLgt9KZmXto0M7mnV5RkS6FNGwRMK3XrojSjHso9DLOWjbnXhbNv4motH8vu53L1HK2VC1+Nj5w== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "^3.973.1" - "@aws-sdk/middleware-host-header" "^3.972.1" - "@aws-sdk/middleware-logger" "^3.972.1" - "@aws-sdk/middleware-recursion-detection" "^3.972.1" - "@aws-sdk/middleware-user-agent" "^3.972.2" - "@aws-sdk/region-config-resolver" "^3.972.1" - "@aws-sdk/types" "^3.973.0" - "@aws-sdk/util-endpoints" "3.972.0" - "@aws-sdk/util-user-agent-browser" "^3.972.1" - "@aws-sdk/util-user-agent-node" "^3.972.1" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/middleware-host-header" "^3.972.3" + "@aws-sdk/middleware-logger" "^3.972.3" + "@aws-sdk/middleware-recursion-detection" "^3.972.3" + "@aws-sdk/middleware-user-agent" "^3.972.9" + "@aws-sdk/region-config-resolver" "^3.972.3" + "@aws-sdk/types" "^3.973.1" + "@aws-sdk/util-endpoints" "3.989.0" + "@aws-sdk/util-user-agent-browser" "^3.972.3" + "@aws-sdk/util-user-agent-node" "^3.972.7" "@smithy/config-resolver" "^4.4.6" - "@smithy/core" "^3.21.1" + "@smithy/core" "^3.23.0" "@smithy/fetch-http-handler" "^5.3.9" "@smithy/hash-node" "^4.2.8" "@smithy/invalid-dependency" "^4.2.8" "@smithy/middleware-content-length" "^4.2.8" - "@smithy/middleware-endpoint" "^4.4.11" - "@smithy/middleware-retry" "^4.4.27" + "@smithy/middleware-endpoint" "^4.4.14" + "@smithy/middleware-retry" "^4.4.31" "@smithy/middleware-serde" "^4.2.9" "@smithy/middleware-stack" "^4.2.8" "@smithy/node-config-provider" "^4.3.8" - "@smithy/node-http-handler" "^4.4.8" + "@smithy/node-http-handler" "^4.4.10" "@smithy/protocol-http" "^5.3.8" - "@smithy/smithy-client" "^4.10.12" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" "@smithy/url-parser" "^4.2.8" "@smithy/util-base64" "^4.3.0" "@smithy/util-body-length-browser" "^4.2.0" "@smithy/util-body-length-node" "^4.2.1" - "@smithy/util-defaults-mode-browser" "^4.3.26" - "@smithy/util-defaults-mode-node" "^4.2.29" + "@smithy/util-defaults-mode-browser" "^4.3.30" + "@smithy/util-defaults-mode-node" "^4.2.33" "@smithy/util-endpoints" "^3.2.8" "@smithy/util-middleware" "^4.2.8" "@smithy/util-retry" "^4.2.8" @@ -217,19 +204,19 @@ "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/core@^3.973.1", "@aws-sdk/core@^3.973.2": - version "3.973.3" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.973.3.tgz#b6db884f295239561106969db52531e4b36780cf" - integrity sha512-ZbM2Xy8ytAcfnNpkBltr6Qdw36W/4NW5nZdZieCuTfacoBFpi/NYiwb8U05KNJvLKeZnrV9Vi696i+r2DQFORg== +"@aws-sdk/core@^3.973.1", "@aws-sdk/core@^3.973.9": + version "3.973.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.973.9.tgz#a42eb97e3e340df7f58f460116c848da376d8ef7" + integrity sha512-cyUOfJSizn8da7XrBEFBf4UMI4A6JQNX6ZFcKtYmh/CrwfzsDcabv3k/z0bNwQ3pX5aeq5sg/8Bs/ASiL0bJaA== dependencies: "@aws-sdk/types" "^3.973.1" - "@aws-sdk/xml-builder" "^3.972.2" - "@smithy/core" "^3.21.1" + "@aws-sdk/xml-builder" "^3.972.4" + "@smithy/core" "^3.23.0" "@smithy/node-config-provider" "^4.3.8" "@smithy/property-provider" "^4.2.8" "@smithy/protocol-http" "^5.3.8" "@smithy/signature-v4" "^5.3.8" - "@smithy/smithy-client" "^4.10.12" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" "@smithy/util-base64" "^4.3.0" "@smithy/util-middleware" "^4.2.8" @@ -244,46 +231,46 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-env@^3.972.2": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.2.tgz#ae9dab80f2de70b8573eb5cc73693136f54d9eb0" - integrity sha512-wzH1EdrZsytG1xN9UHaK12J9+kfrnd2+c8y0LVoS4O4laEjPoie1qVK3k8/rZe7KOtvULzyMnO3FT4Krr9Z0Dg== +"@aws-sdk/credential-provider-env@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.7.tgz#bdb19770d7ebddd9a12115575cc75ab83a322853" + integrity sha512-r8kBtglvLjGxBT87l6Lqkh9fL8yJJ6O4CYQPjKlj3AkCuL4/4784x3rxxXWw9LTKXOo114VB6mjxAuy5pI7XIg== dependencies: - "@aws-sdk/core" "^3.973.2" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-http@^3.972.3": - version "3.972.3" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.3.tgz#602db1ebf63e3712cd8e07180ba4dd424685f5f7" - integrity sha512-IbBGWhaxiEl64fznwh5PDEB0N7YJEAvK5b6nRtPVUKdKAHlOPgo6B9XB8mqWDs8Ct0oF/E34ZLiq2U0L5xDkrg== +"@aws-sdk/credential-provider-http@^3.972.9": + version "3.972.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.9.tgz#4c266169f071e21ffc49b15b02f4f80ec03b2e62" + integrity sha512-40caFblEg/TPrp9EpvyMxp4xlJ5TuTI+A8H6g8FhHn2hfH2PObFAPLF9d5AljK/G69E1YtTklkuQeAwPlV3w8Q== dependencies: - "@aws-sdk/core" "^3.973.2" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@smithy/fetch-http-handler" "^5.3.9" - "@smithy/node-http-handler" "^4.4.8" + "@smithy/node-http-handler" "^4.4.10" "@smithy/property-provider" "^4.2.8" "@smithy/protocol-http" "^5.3.8" - "@smithy/smithy-client" "^4.10.12" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" - "@smithy/util-stream" "^4.5.10" + "@smithy/util-stream" "^4.5.12" tslib "^2.6.2" -"@aws-sdk/credential-provider-ini@^3.972.2": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.2.tgz#4a26aed6af446880cbba8ede95b38a0678697840" - integrity sha512-Jrb8sLm6k8+L7520irBrvCtdLxNtrG7arIxe9TCeMJt/HxqMGJdbIjw8wILzkEHLMIi4MecF2FbXCln7OT1Tag== - dependencies: - "@aws-sdk/core" "^3.973.2" - "@aws-sdk/credential-provider-env" "^3.972.2" - "@aws-sdk/credential-provider-http" "^3.972.3" - "@aws-sdk/credential-provider-login" "^3.972.2" - "@aws-sdk/credential-provider-process" "^3.972.2" - "@aws-sdk/credential-provider-sso" "^3.972.2" - "@aws-sdk/credential-provider-web-identity" "^3.972.2" - "@aws-sdk/nested-clients" "3.975.0" +"@aws-sdk/credential-provider-ini@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.7.tgz#28fd9fc9e6da712f392240bd1b882d99f4e5d98a" + integrity sha512-zeYKrMwM5bCkHFho/x3+1OL0vcZQ0OhTR7k35tLq74+GP5ieV3juHXTZfa2LVE0Bg75cHIIerpX0gomVOhzo/w== + dependencies: + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/credential-provider-env" "^3.972.7" + "@aws-sdk/credential-provider-http" "^3.972.9" + "@aws-sdk/credential-provider-login" "^3.972.7" + "@aws-sdk/credential-provider-process" "^3.972.7" + "@aws-sdk/credential-provider-sso" "^3.972.7" + "@aws-sdk/credential-provider-web-identity" "^3.972.7" + "@aws-sdk/nested-clients" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/credential-provider-imds" "^4.2.8" "@smithy/property-provider" "^4.2.8" @@ -291,13 +278,13 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-login@^3.972.2": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.2.tgz#2a022a80950041db4520983568290e57d06399fb" - integrity sha512-mlaw2aiI3DrimW85ZMn3g7qrtHueidS58IGytZ+mbFpsYLK5wMjCAKZQtt7VatLMtSBG/dn/EY4njbnYXIDKeQ== +"@aws-sdk/credential-provider-login@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.7.tgz#c98aa999c1538c28aff2eb8d61c82d359acb0404" + integrity sha512-Q103cLU6OjAllYjX7+V+PKQw654jjvZUkD+lbUUiFbqut6gR5zwl1DrelvJPM5hnzIty7BCaxaRB3KMuz3M/ug== dependencies: - "@aws-sdk/core" "^3.973.2" - "@aws-sdk/nested-clients" "3.975.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/nested-clients" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/protocol-http" "^5.3.8" @@ -306,16 +293,16 @@ tslib "^2.6.2" "@aws-sdk/credential-provider-node@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.2.tgz#7f308337fc0674c340878da6c7061caffe03501d" - integrity sha512-Lz1J5IZdTjLYTVIcDP5DVDgi1xlgsF3p1cnvmbfKbjCRhQpftN2e2J4NFfRRvPD54W9+bZ8l5VipPXtTYK7aEg== - dependencies: - "@aws-sdk/credential-provider-env" "^3.972.2" - "@aws-sdk/credential-provider-http" "^3.972.3" - "@aws-sdk/credential-provider-ini" "^3.972.2" - "@aws-sdk/credential-provider-process" "^3.972.2" - "@aws-sdk/credential-provider-sso" "^3.972.2" - "@aws-sdk/credential-provider-web-identity" "^3.972.2" + version "3.972.8" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.8.tgz#6dabc10f104a6cfa7a8bfbae9000fbce7453b0d0" + integrity sha512-AaDVOT7iNJyLjc3j91VlucPZ4J8Bw+eu9sllRDugJqhHWYyR3Iyp2huBUW8A3+DfHoh70sxGkY92cThAicSzlQ== + dependencies: + "@aws-sdk/credential-provider-env" "^3.972.7" + "@aws-sdk/credential-provider-http" "^3.972.9" + "@aws-sdk/credential-provider-ini" "^3.972.7" + "@aws-sdk/credential-provider-process" "^3.972.7" + "@aws-sdk/credential-provider-sso" "^3.972.7" + "@aws-sdk/credential-provider-web-identity" "^3.972.7" "@aws-sdk/types" "^3.973.1" "@smithy/credential-provider-imds" "^4.2.8" "@smithy/property-provider" "^4.2.8" @@ -323,39 +310,39 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-process@^3.972.2": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.2.tgz#15a841b2ed063342878f224cb7bc9b10228a0804" - integrity sha512-NLKLTT7jnUe9GpQAVkPTJO+cs2FjlQDt5fArIYS7h/Iw/CvamzgGYGFRVD2SE05nOHCMwafUSi42If8esGFV+g== +"@aws-sdk/credential-provider-process@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.7.tgz#a32117662790f8811ee08af9d5c7f2542dd9a289" + integrity sha512-hxMo1V3ujWWrQSONxQJAElnjredkRpB6p8SDjnvRq70IwYY38R/CZSys0IbhRPxdgWZ5j12yDRk2OXhxw4Gj3g== dependencies: - "@aws-sdk/core" "^3.973.2" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-sso@^3.972.2": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.2.tgz#530df0dd80f9be2bdf2a2de8c38578ab71c859e2" - integrity sha512-YpwDn8g3gCGUl61cCV0sRxP2pFIwg+ZsMfWQ/GalSyjXtRkctCMFA+u0yPb/Q4uTfNEiya1Y4nm0C5rIHyPW5Q== +"@aws-sdk/credential-provider-sso@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.7.tgz#87cfeeaf907eb574388fd65e3b749044d57cca54" + integrity sha512-ZGKBOHEj8Ap15jhG2XMncQmKLTqA++2DVU2eZfLu3T/pkwDyhCp5eZv5c/acFxbZcA/6mtxke+vzO/n+aeHs4A== dependencies: - "@aws-sdk/client-sso" "3.975.0" - "@aws-sdk/core" "^3.973.2" - "@aws-sdk/token-providers" "3.975.0" + "@aws-sdk/client-sso" "3.989.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/token-providers" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-web-identity@^3.972.2": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.2.tgz#30d253baee3e4e35dcc15aa9219e18befd3d17bf" - integrity sha512-x9DAiN9Qz+NjJ99ltDiVQ8d511M/tuF/9MFbe2jUgo7HZhD6+x4S3iT1YcP07ndwDUjmzKGmeOEgE24k4qvfdg== +"@aws-sdk/credential-provider-web-identity@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.7.tgz#c983dd478c0a1be4069abb10ff11527e07c7b224" + integrity sha512-AbYupBIoSJoVMlbMqBhNvPhqj+CdGtzW7Uk4ZIMBm2br18pc3rkG1VaKVFV85H87QCvLHEnni1idJjaX1wOmIw== dependencies: - "@aws-sdk/core" "^3.973.2" - "@aws-sdk/nested-clients" "3.975.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/nested-clients" "3.989.0" "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" @@ -363,9 +350,9 @@ tslib "^2.6.2" "@aws-sdk/middleware-bucket-endpoint@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.2.tgz#04ab6d109a8ead757a711ee8cb18a1bd65b404da" - integrity sha512-ofuXBnitp9j8t05O4NQVrpMZDECPtUhRIWdLzR35baR5njOIPY7YqNtJE+yELVpSn2m4jt2sV1ezYMBY4/Lo+w== + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.3.tgz#158507d55505e5e7b5b8cdac9f037f6aa326f202" + integrity sha512-fmbgWYirF67YF1GfD7cg5N6HHQ96EyRNx/rDIrTF277/zTWVuPI2qS/ZHgofwR1NZPe/NWvoppflQY01LrbVLg== dependencies: "@aws-sdk/types" "^3.973.1" "@aws-sdk/util-arn-parser" "^3.972.2" @@ -376,9 +363,9 @@ tslib "^2.6.2" "@aws-sdk/middleware-expect-continue@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.2.tgz#3bf62c912de18d9179dac9f192ab8b86f09a6f58" - integrity sha512-d9bBQlGk1T5j5rWfof20M2tErddOSoSLDauP2/yyuXfeOfQRCSBUZNrApSxjJ9Hw+/RDGR/XL+LEOqmXxSlV3A== + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.3.tgz#c60bd81e81dde215b9f3f67e3c5448b608afd530" + integrity sha512-4msC33RZsXQpUKR5QR4HnvBSNCPLGHmB55oDiROqqgyOc+TOfVu2xgi5goA7ms6MdZLeEh2905UfWMnMMF4mRg== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/protocol-http" "^5.3.8" @@ -386,14 +373,14 @@ tslib "^2.6.2" "@aws-sdk/middleware-flexible-checksums@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.2.tgz#038be2a6acb817cae1b12cd9084f1e5b7a0b38c0" - integrity sha512-GgWVZJdzXzqhXxzNAYB3TnZCj7d5rZNdovqSIV91e97nowHVaExRoyaZ3H/Ydqot7veHGPTl8nBp464zZeLDTQ== + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.972.7.tgz#b812fd2ad23c3eae79d7d0d5cc44660d84862b15" + integrity sha512-YU/5rpz8k2mwFGi2M0px9ChOQZY7Bbow5knB2WLRVPqDM/cG8T5zj55UaWS1qcaFpE7vCX9a9/kvYBlKGcD+KA== dependencies: "@aws-crypto/crc32" "5.2.0" "@aws-crypto/crc32c" "5.2.0" "@aws-crypto/util" "5.2.0" - "@aws-sdk/core" "^3.973.2" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/crc64-nvme" "3.972.0" "@aws-sdk/types" "^3.973.1" "@smithy/is-array-buffer" "^4.2.0" @@ -401,14 +388,14 @@ "@smithy/protocol-http" "^5.3.8" "@smithy/types" "^4.12.0" "@smithy/util-middleware" "^4.2.8" - "@smithy/util-stream" "^4.5.10" + "@smithy/util-stream" "^4.5.12" "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-host-header@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.2.tgz#0d0a7fb4a5c71b4697c8f00d7de975be8146ffcf" - integrity sha512-42hZ8jEXT2uR6YybCzNq9OomqHPw43YIfRfz17biZjMQA4jKSQUaHIl6VvqO2Ddl5904pXg2Yd/ku78S0Ikgog== +"@aws-sdk/middleware-host-header@^3.972.1", "@aws-sdk/middleware-host-header@^3.972.3": + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.3.tgz#47c161dec62d89c66c89f4d17ff4434021e04af5" + integrity sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/protocol-http" "^5.3.8" @@ -416,27 +403,27 @@ tslib "^2.6.2" "@aws-sdk/middleware-location-constraint@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.2.tgz#8080605dd95e1103e5e4f42ea2ad2469973de6da" - integrity sha512-pyayzpq+VQiG1o9pEUyr6BXEJ2g2t4JIPdNxDkIHp2AhR63Gy/10WQkXTBOgRnfQ7/aLPLOnjRIWwOPp0CfUlA== + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.3.tgz#b4f504f75baa19064b7457e5c6e3c8cecb4c32eb" + integrity sha512-nIg64CVrsXp67vbK0U1/Is8rik3huS3QkRHn2DRDx4NldrEFMgdkZGI/+cZMKD9k4YOS110Dfu21KZLHrFA/1g== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-logger@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.972.2.tgz#132cf8945f27c7f93ba4f1742cefda04d18aff21" - integrity sha512-iUzdXKOgi4JVDDEG/VvoNw50FryRCEm0qAudw12DcZoiNJWl0rN6SYVLcL1xwugMfQncCXieK5UBlG6mhH7iYA== +"@aws-sdk/middleware-logger@^3.972.1", "@aws-sdk/middleware-logger@^3.972.3": + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.972.3.tgz#ef1afd4a0b70fe72cf5f7c817f82da9f35c7e836" + integrity sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-recursion-detection@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.2.tgz#12de11a9c4327418cf6edc20907813b2ecf4c179" - integrity sha512-/mzlyzJDtngNFd/rAYvqx29a2d0VuiYKN84Y/Mu9mGw7cfMOCyRK+896tb9wV6MoPRHUX7IXuKCIL8nzz2Pz5A== +"@aws-sdk/middleware-recursion-detection@^3.972.1", "@aws-sdk/middleware-recursion-detection@^3.972.3": + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.3.tgz#5b95dcecff76a0d2963bd954bdef87700d1b1c8c" + integrity sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q== dependencies: "@aws-sdk/types" "^3.973.1" "@aws/lambda-invoke-store" "^0.2.2" @@ -465,95 +452,95 @@ tslib "^2.6.2" "@aws-sdk/middleware-sdk-s3@^3.972.2": - version "3.972.3" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.3.tgz#42af15f02b5153c6b4864d20badbc8d750de3047" - integrity sha512-ZVtakKpQ7vI9l7tE2SJjQgoPYv2f/Bw/HMip5wBigsQBDvVbN300h+6nPnm0gnEQwIGGG0yJF3XCvr1/4pZW9A== + version "3.972.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.9.tgz#6b3fad9a22a25b8a28fd7491b1888e796eb986eb" + integrity sha512-F4Ak2HM7te/o3izFTqg/jUTBLjavpaJ5iynKM6aLMwNddXbwAZQ1VbIG8RFUHBo7fBHj2eeN2FNLtIFT4ejWYQ== dependencies: - "@aws-sdk/core" "^3.973.2" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" "@aws-sdk/util-arn-parser" "^3.972.2" - "@smithy/core" "^3.21.1" + "@smithy/core" "^3.23.0" "@smithy/node-config-provider" "^4.3.8" "@smithy/protocol-http" "^5.3.8" "@smithy/signature-v4" "^5.3.8" - "@smithy/smithy-client" "^4.10.12" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" "@smithy/util-config-provider" "^4.2.0" "@smithy/util-middleware" "^4.2.8" - "@smithy/util-stream" "^4.5.10" + "@smithy/util-stream" "^4.5.12" "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" "@aws-sdk/middleware-ssec@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.2.tgz#73620c2401b6a64de25fd9bae1a9028ff3ca28ba" - integrity sha512-HJ3OmQnlQ1es6esrDWnx3nVPhBAN89WaFCzsDcb6oT7TMjBPUfZ5+1BpI7B0Hnme8cc6kp7qc4cgo2plrlROJA== + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.3.tgz#4f81d310fd91164e6e18ba3adab6bcf906920333" + integrity sha512-dU6kDuULN3o3jEHcjm0c4zWJlY1zWVkjG9NPe9qxYLLpcbdj5kRYBS2DdWYD+1B9f910DezRuws7xDEqKkHQIg== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/middleware-user-agent@^3.972.2", "@aws-sdk/middleware-user-agent@^3.972.3": - version "3.972.3" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.3.tgz#7c01223804db94079ee7281e2cd7d4eb00d825f9" - integrity sha512-zq6aTiO/BiAIOA8EH8nB+wYvvnZ14Md9Gomm5DDhParshVEVglAyNPO5ADK4ZXFQbftIoO+Vgcvf4gewW/+iYQ== +"@aws-sdk/middleware-user-agent@^3.972.2", "@aws-sdk/middleware-user-agent@^3.972.9": + version "3.972.9" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.9.tgz#998e38d32b4fa4bda71c017c3044f7f46dc4f031" + integrity sha512-1g1B7yf7KzessB0mKNiV9gAHEwbM662xgU+VE4LxyGe6kVGZ8LqYsngjhE+Stna09CJ7Pxkjr6Uq1OtbGwJJJg== dependencies: - "@aws-sdk/core" "^3.973.2" + "@aws-sdk/core" "^3.973.9" "@aws-sdk/types" "^3.973.1" - "@aws-sdk/util-endpoints" "3.972.0" - "@smithy/core" "^3.21.1" + "@aws-sdk/util-endpoints" "3.989.0" + "@smithy/core" "^3.23.0" "@smithy/protocol-http" "^5.3.8" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/nested-clients@3.975.0": - version "3.975.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.975.0.tgz#566d4508dfd2b83e86a829670d9219d307f6f1a5" - integrity sha512-OkeFHPlQj2c/Y5bQGkX14pxhDWUGUFt3LRHhjcDKsSCw6lrxKcxN3WFZN0qbJwKNydP+knL5nxvfgKiCLpTLRA== +"@aws-sdk/nested-clients@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.989.0.tgz#0fbe4db7af0c38b7b41f31dba6f26b29dc8b7082" + integrity sha512-Dbk2HMPU3mb6RrSRzgf0WCaWSbgtZG258maCpuN2/ONcAQNpOTw99V5fU5CA1qVK6Vkm4Fwj2cnOnw7wbGVlOw== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "^3.973.1" - "@aws-sdk/middleware-host-header" "^3.972.1" - "@aws-sdk/middleware-logger" "^3.972.1" - "@aws-sdk/middleware-recursion-detection" "^3.972.1" - "@aws-sdk/middleware-user-agent" "^3.972.2" - "@aws-sdk/region-config-resolver" "^3.972.1" - "@aws-sdk/types" "^3.973.0" - "@aws-sdk/util-endpoints" "3.972.0" - "@aws-sdk/util-user-agent-browser" "^3.972.1" - "@aws-sdk/util-user-agent-node" "^3.972.1" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/middleware-host-header" "^3.972.3" + "@aws-sdk/middleware-logger" "^3.972.3" + "@aws-sdk/middleware-recursion-detection" "^3.972.3" + "@aws-sdk/middleware-user-agent" "^3.972.9" + "@aws-sdk/region-config-resolver" "^3.972.3" + "@aws-sdk/types" "^3.973.1" + "@aws-sdk/util-endpoints" "3.989.0" + "@aws-sdk/util-user-agent-browser" "^3.972.3" + "@aws-sdk/util-user-agent-node" "^3.972.7" "@smithy/config-resolver" "^4.4.6" - "@smithy/core" "^3.21.1" + "@smithy/core" "^3.23.0" "@smithy/fetch-http-handler" "^5.3.9" "@smithy/hash-node" "^4.2.8" "@smithy/invalid-dependency" "^4.2.8" "@smithy/middleware-content-length" "^4.2.8" - "@smithy/middleware-endpoint" "^4.4.11" - "@smithy/middleware-retry" "^4.4.27" + "@smithy/middleware-endpoint" "^4.4.14" + "@smithy/middleware-retry" "^4.4.31" "@smithy/middleware-serde" "^4.2.9" "@smithy/middleware-stack" "^4.2.8" "@smithy/node-config-provider" "^4.3.8" - "@smithy/node-http-handler" "^4.4.8" + "@smithy/node-http-handler" "^4.4.10" "@smithy/protocol-http" "^5.3.8" - "@smithy/smithy-client" "^4.10.12" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" "@smithy/url-parser" "^4.2.8" "@smithy/util-base64" "^4.3.0" "@smithy/util-body-length-browser" "^4.2.0" "@smithy/util-body-length-node" "^4.2.1" - "@smithy/util-defaults-mode-browser" "^4.3.26" - "@smithy/util-defaults-mode-node" "^4.2.29" + "@smithy/util-defaults-mode-browser" "^4.3.30" + "@smithy/util-defaults-mode-node" "^4.2.33" "@smithy/util-endpoints" "^3.2.8" "@smithy/util-middleware" "^4.2.8" "@smithy/util-retry" "^4.2.8" "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/region-config-resolver@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.2.tgz#962dc4099a3c43248724746dc2faa0d43499c374" - integrity sha512-/7vRBsfmiOlg2X67EdKrzzQGw5/SbkXb7ALHQmlQLkZh8qNgvS2G2dDC6NtF3hzFlpP3j2k+KIEtql/6VrI6JA== +"@aws-sdk/region-config-resolver@^3.972.1", "@aws-sdk/region-config-resolver@^3.972.3": + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.3.tgz#25af64235ca6f4b6b21f85d4b3c0b432efc4ae04" + integrity sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/config-resolver" "^4.4.6" @@ -573,14 +560,14 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@aws-sdk/token-providers@3.975.0": - version "3.975.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.975.0.tgz#57d41c54fe8cf296816f2142de0c32f4c79b2bff" - integrity sha512-AWQt64hkVbDQ+CmM09wnvSk2mVyH4iRROkmYkr3/lmUtFNbE2L/fnw26sckZnUcFCsHPqbkQrcsZAnTcBLbH4w== +"@aws-sdk/token-providers@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.989.0.tgz#4bc8c2c122f91de6b9eb174a14d3f8d8a72f441a" + integrity sha512-OdBByMv+OjOZoekrk4THPFpLuND5aIQbDHCGh3n2rvifAbm31+6e0OLhxSeCF1UMPm+nKq12bXYYEoCIx5SQBg== dependencies: - "@aws-sdk/core" "^3.973.1" - "@aws-sdk/nested-clients" "3.975.0" - "@aws-sdk/types" "^3.973.0" + "@aws-sdk/core" "^3.973.9" + "@aws-sdk/nested-clients" "3.989.0" + "@aws-sdk/types" "^3.973.1" "@smithy/property-provider" "^4.2.8" "@smithy/shared-ini-file-loader" "^4.4.3" "@smithy/types" "^4.12.0" @@ -627,6 +614,17 @@ "@smithy/util-endpoints" "^3.2.8" tslib "^2.6.2" +"@aws-sdk/util-endpoints@3.989.0": + version "3.989.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.989.0.tgz#08301e145a658c4a1a682354f108a5b0eb58af92" + integrity sha512-eKmAOeQM4Qusq0jtcbZPiNWky8XaojByKC/n+THbJ8vJf7t4ys8LlcZ4PrBSHZISe9cC484mQsPVOQh6iySjqw== + dependencies: + "@aws-sdk/types" "^3.973.1" + "@smithy/types" "^4.12.0" + "@smithy/url-parser" "^4.2.8" + "@smithy/util-endpoints" "^3.2.8" + tslib "^2.6.2" + "@aws-sdk/util-locate-window@^3.0.0": version "3.965.4" resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.965.4.tgz#f62d279e1905f6939b6dffb0f76ab925440f72bf" @@ -634,22 +632,22 @@ dependencies: tslib "^2.6.2" -"@aws-sdk/util-user-agent-browser@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.2.tgz#f5af782d42aed4c87059406b6f2ddf258fbb9586" - integrity sha512-gz76bUyebPZRxIsBHJUd/v+yiyFzm9adHbr8NykP2nm+z/rFyvQneOHajrUejtmnc5tTBeaDPL4X25TnagRk4A== +"@aws-sdk/util-user-agent-browser@^3.972.1", "@aws-sdk/util-user-agent-browser@^3.972.3": + version "3.972.3" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.3.tgz#1363b388cb3af86c5322ef752c0cf8d7d25efa8a" + integrity sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw== dependencies: "@aws-sdk/types" "^3.973.1" "@smithy/types" "^4.12.0" bowser "^2.11.0" tslib "^2.6.2" -"@aws-sdk/util-user-agent-node@^3.972.1": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.2.tgz#cbdb14a2e412b39d7751636133de604ce4727506" - integrity sha512-vnxOc4C6AR7hVbwyFo1YuH0GB6dgJlWt8nIOOJpnzJAWJPkUMPJ9Zv2lnKsSU7TTZbhP2hEO8OZ4PYH59XFv8Q== +"@aws-sdk/util-user-agent-node@^3.972.1", "@aws-sdk/util-user-agent-node@^3.972.7": + version "3.972.7" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.7.tgz#c55e1eb7911215127bfd5dfb29c1bf2e3247581d" + integrity sha512-oyhv+FjrgHjP+F16cmsrJzNP4qaRJzkV1n9Lvv4uyh3kLqo3rIe9NSBSBa35f2TedczfG2dD+kaQhHBB47D6Og== dependencies: - "@aws-sdk/middleware-user-agent" "^3.972.3" + "@aws-sdk/middleware-user-agent" "^3.972.9" "@aws-sdk/types" "^3.973.1" "@smithy/node-config-provider" "^4.3.8" "@smithy/types" "^4.12.0" @@ -664,13 +662,13 @@ fast-xml-parser "5.2.5" tslib "^2.6.2" -"@aws-sdk/xml-builder@^3.972.2": - version "3.972.2" - resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.972.2.tgz#c63a6a788ff398491748908af528c8294c562f65" - integrity sha512-jGOOV/bV1DhkkUhHiZ3/1GZ67cZyOXaDb7d1rYD6ZiXf5V9tBNOcgqXwRRPvrCbYaFRa1pPMFb3ZjqjWpR3YfA== +"@aws-sdk/xml-builder@^3.972.4": + version "3.972.4" + resolved "https://registry.yarnpkg.com/@aws-sdk/xml-builder/-/xml-builder-3.972.4.tgz#8115c8cf90c71cf484a52c82eac5344cd3a5e921" + integrity sha512-0zJ05ANfYqI6+rGqj8samZBFod0dPPousBjLEqg8WdxSgbMAkRgLyn81lP215Do0rFJ/17LIXwr7q0yK24mP6Q== dependencies: "@smithy/types" "^4.12.0" - fast-xml-parser "5.2.5" + fast-xml-parser "5.3.4" tslib "^2.6.2" "@aws/lambda-invoke-store@^0.2.2": @@ -678,66 +676,58 @@ resolved "https://registry.yarnpkg.com/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.3.tgz#f1137f56209ccc69c15f826242cbf37f828617dd" integrity sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw== -"@babel/code-frame@^7.0.0": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" - integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== - dependencies: - "@babel/highlight" "^7.24.2" - picocolors "^1.0.0" - -"@babel/code-frame@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" - integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== dependencies: - "@babel/helper-validator-identifier" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.27.2": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.0.tgz#9fc6fd58c2a6a15243cd13983224968392070790" - integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw== +"@babel/compat-data@^7.28.6": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d" + integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg== "@babel/core@^7.23.3": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.0.tgz#55dad808d5bf3445a108eefc88ea3fdf034749a4" - integrity sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.0" - "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-module-transforms" "^7.27.3" - "@babel/helpers" "^7.27.6" - "@babel/parser" "^7.28.0" - "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.0" - "@babel/types" "^7.28.0" + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322" + integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helpers" "^7.28.6" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.23.6", "@babel/generator@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.0.tgz#9cc2f7bd6eb054d77dc66c2664148a0c5118acd2" - integrity sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg== +"@babel/generator@^7.23.6", "@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== dependencies: - "@babel/parser" "^7.28.0" - "@babel/types" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" "@jridgewell/gen-mapping" "^0.3.12" "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" -"@babel/helper-compilation-targets@^7.27.2": - version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" - integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== +"@babel/helper-compilation-targets@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25" + integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA== dependencies: - "@babel/compat-data" "^7.27.2" + "@babel/compat-data" "^7.28.6" "@babel/helper-validator-option" "^7.27.1" browserslist "^4.24.0" lru-cache "^5.1.1" @@ -755,65 +745,33 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-module-imports@^7.16.7": - version "7.24.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128" - integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg== - dependencies: - "@babel/types" "^7.24.0" - -"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" - integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" + integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" -"@babel/helper-module-transforms@^7.27.3": - version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz#db0bbcfba5802f9ef7870705a7ef8788508ede02" - integrity sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg== +"@babel/helper-module-transforms@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e" + integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== dependencies: - "@babel/helper-module-imports" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.3" - -"@babel/helper-plugin-utils@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" - integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== - -"@babel/helper-string-parser@^7.23.4": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" - integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.6" -"@babel/helper-string-parser@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" - integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== +"@babel/helper-plugin-utils@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== "@babel/helper-string-parser@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/helper-validator-identifier@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" - integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== - -"@babel/helper-validator-identifier@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" - integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== - "@babel/helper-validator-identifier@^7.28.5": version "7.28.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" @@ -824,108 +782,59 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== -"@babel/helpers@^7.27.6": - version "7.27.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.27.6.tgz#6456fed15b2cb669d2d1fabe84b66b34991d812c" - integrity sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug== - dependencies: - "@babel/template" "^7.27.2" - "@babel/types" "^7.27.6" - -"@babel/highlight@^7.24.2": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" - integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7": - version "7.27.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.0.tgz#3d7d6ee268e41d2600091cbd4e145ffee85a44ec" - integrity sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg== - dependencies: - "@babel/types" "^7.27.0" - -"@babel/parser@^7.27.2", "@babel/parser@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.0.tgz#979829fbab51a29e13901e5a80713dbcb840825e" - integrity sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g== +"@babel/helpers@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.6.tgz#fca903a313ae675617936e8998b814c415cbf5d7" + integrity sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw== dependencies: - "@babel/types" "^7.28.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.28.6" -"@babel/parser@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" - integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.0.tgz#669ef345add7d057e92b7ed15f0bac07611831b6" + integrity sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww== dependencies: - "@babel/types" "^7.28.5" + "@babel/types" "^7.29.0" "@babel/plugin-syntax-jsx@^7.18.6": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" - integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz#f8ca28bbd84883b5fea0e447c635b81ba73997ee" + integrity sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w== dependencies: - "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-plugin-utils" "^7.28.6" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": - version "7.27.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6" - integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q== +"@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.6.tgz#d267a43cb1836dc4d182cce93ae75ba954ef6d2b" + integrity sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA== -"@babel/template@^7.27.2": - version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" - integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== +"@babel/template@^7.28.6": + version "7.28.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/parser" "^7.27.2" - "@babel/types" "^7.27.1" + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" -"@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.0.tgz#518aa113359b062042379e333db18380b537e34b" - integrity sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg== +"@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.0" + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.28.0" - "@babel/template" "^7.27.2" - "@babel/types" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.0": - version "7.27.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.0.tgz#ef9acb6b06c3173f6632d993ecb6d4ae470b4559" - integrity sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg== - dependencies: - "@babel/helper-string-parser" "^7.25.9" - "@babel/helper-validator-identifier" "^7.25.9" - -"@babel/types@^7.18.6", "@babel/types@^7.23.6", "@babel/types@^7.27.1", "@babel/types@^7.27.6", "@babel/types@^7.28.0": - version "7.28.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.1.tgz#2aaf3c10b31ba03a77ac84f52b3912a0edef4cf9" - integrity sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ== - dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - -"@babel/types@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" - integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@babel/types@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" - integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.20.7", "@babel/types@^7.23.6", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== dependencies: "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" @@ -962,20 +871,20 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz#bbe12dca5b4ef983a0d0af4b07b9bc90ea0ababa" integrity sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA== -"@blueprintjs/colors@^5.1.1": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@blueprintjs/colors/-/colors-5.1.1.tgz#b227d1ce8b95d9266d976441f34cd71d436735db" - integrity sha512-Mni/GgCYLaMf5U5zsCN42skOG49w3U0QmUFuJgFZ/1pv+3cHF/9xR4L4dXcj5DtgJoHkmUbK36PR5mdFB65WEA== +"@blueprintjs/colors@^5.1.8": + version "5.1.14" + resolved "https://registry.yarnpkg.com/@blueprintjs/colors/-/colors-5.1.14.tgz#7d1bdfabf99f8861c86535f4aaeb9a1c02f0e1bd" + integrity sha512-Ak6NpUBc0nFpWxucYe7GgMwdcrlARX7yfSPxt4va7z2IM05peNh8OOZ2jQij5+sIgU6IoIkgILAqlQ8nNRhWww== dependencies: tslib "~2.6.2" -"@blueprintjs/core@^5.10.0": - version "5.10.0" - resolved "https://registry.yarnpkg.com/@blueprintjs/core/-/core-5.10.0.tgz#3ad53fe624f6f7d9ed8b4ed27f5acee280b88123" - integrity sha512-jJNRw61ITWDJlrqSM+vx8kG6nBrFO55SmIQU2TepQ6iPIv3PQtv1gmLWc0TmUdtiROMy0ehhddMqEulOmOXGsQ== +"@blueprintjs/core@^5.10.0", "@blueprintjs/core@^5.19.1": + version "5.19.1" + resolved "https://registry.yarnpkg.com/@blueprintjs/core/-/core-5.19.1.tgz#d17ed32b4eee90c25c308262ff9975c0cbd34a59" + integrity sha512-vjLd9jnuHPunW6zsZtx0f03zb33aRa/k6nnwH+N16NEIs7/wHWX5f5ljtEguSt/M1jx4IT0oescMQMAuXWXAWQ== dependencies: - "@blueprintjs/colors" "^5.1.1" - "@blueprintjs/icons" "^5.8.0" + "@blueprintjs/colors" "^5.1.8" + "@blueprintjs/icons" "^5.23.0" "@popperjs/core" "^2.11.8" classnames "^2.3.1" normalize.css "^8.0.1" @@ -985,22 +894,22 @@ tslib "~2.6.2" use-sync-external-store "^1.2.0" -"@blueprintjs/icons@^5.8.0": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@blueprintjs/icons/-/icons-5.8.0.tgz#5c6b8ab32ba238a7bbc1fc4a0aec7fcd6cb0d6a2" - integrity sha512-QAl0eh1lzYR7CDkT6Uerci5x7jy0vtOj6+B+5cg0noEdjguHoRmhx7b3dDcj+Nmlz6rAvRZoU3cgzfk0NiD1zg== +"@blueprintjs/icons@^5.23.0": + version "5.23.0" + resolved "https://registry.yarnpkg.com/@blueprintjs/icons/-/icons-5.23.0.tgz#c01dc80fbadb4dfef20d34abdee14a23b6f5d00b" + integrity sha512-yxQ+A0V79/UsyIw4XYuEvaFqr3FIaRlp79rKh+ZdHLafedqPfp4LO6xtF6EziWFCvuHOTJdFCfSC8AoQeSENMw== dependencies: change-case "^4.1.2" classnames "^2.3.1" tslib "~2.6.2" "@blueprintjs/select@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@blueprintjs/select/-/select-5.1.2.tgz#9b9280b8c08efc4e516705ccced4f76f255beab7" - integrity sha512-9LgAzOXL/WKdh2o63dzE6oT8gPNgOzR5PWJcVZu4fHFPz4CZ/hD3scsMIhACE+K0DfHWNCPtPjWqZX6U24q/fQ== + version "5.3.21" + resolved "https://registry.yarnpkg.com/@blueprintjs/select/-/select-5.3.21.tgz#9a5e1fc94389f382aab63da184c8b634ae7bdcfa" + integrity sha512-1mNWnS2Vb0VUP/M3Z9VhrXzAkbsROYrmiE+uRn20O2w/8skxRwtBZ6WRSSY9GPqzVqBqz7+G0VC0CSLBjvRklw== dependencies: - "@blueprintjs/core" "^5.10.0" - "@blueprintjs/icons" "^5.8.0" + "@blueprintjs/core" "^5.19.1" + "@blueprintjs/icons" "^5.23.0" classnames "^2.3.1" tslib "~2.6.2" @@ -1009,11 +918,6 @@ resolved "https://registry.yarnpkg.com/@corex/deepmerge/-/deepmerge-4.0.43.tgz#9bd42559ebb41cc5a7fb7cfeea5f231c20977dca" integrity sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ== -"@darkroom.engineering/tempus@^0.0.46": - version "0.0.46" - resolved "https://registry.yarnpkg.com/@darkroom.engineering/tempus/-/tempus-0.0.46.tgz#3d958807503e4055fcc4a1aeeff83ca0546c62f0" - integrity sha512-s5vav3KMHYezvUCl4ee5epg0oimF6M8C9gAaKxFnFaTvX2q3ywFDryIv6XLd0mRFUt3S1uHDJqKaiEcs2ZVSvw== - "@develar/schema-utils@~2.6.5": version "2.6.5" resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz#3ece22c5838402419a6e0425f85742b961d9b6c6" @@ -1032,9 +936,9 @@ minimatch "^3.0.4" "@electron/asar@^3.2.7": - version "3.2.10" - resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.10.tgz#615cf346b734b23cafa4e0603551010bd0e50aa8" - integrity sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw== + version "3.4.1" + resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.4.1.tgz#4e9196a4b54fba18c56cd8d5cac67c5bdc588065" + integrity sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA== dependencies: commander "^5.0.0" glob "^7.1.6" @@ -1064,9 +968,9 @@ optionalDependencies: global-agent "^3.0.0" -"@electron/node-gyp@https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2": +"@electron/node-gyp@git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2": version "10.2.0-electron.1" - resolved "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2" + resolved "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2" dependencies: env-paths "^2.2.0" exponential-backoff "^3.1.1" @@ -1152,25 +1056,18 @@ minimatch "^9.0.3" plist "^3.1.0" -"@emnapi/core@^1.7.1": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.7.1.tgz#3a79a02dbc84f45884a1806ebb98e5746bdfaac4" - integrity sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg== +"@emnapi/core@^1.4.3", "@emnapi/core@^1.7.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.8.1.tgz#fd9efe721a616288345ffee17a1f26ac5dd01349" + integrity sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg== dependencies: "@emnapi/wasi-threads" "1.1.0" tslib "^2.4.0" -"@emnapi/runtime@^1.4.4": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.4.4.tgz#19a8f00719c51124e2d0fbf4aaad3fa7b0c92524" - integrity sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg== - dependencies: - tslib "^2.4.0" - -"@emnapi/runtime@^1.7.0", "@emnapi/runtime@^1.7.1": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.7.1.tgz#a73784e23f5d57287369c808197288b52276b791" - integrity sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA== +"@emnapi/runtime@^1.4.3", "@emnapi/runtime@^1.4.4", "@emnapi/runtime@^1.7.0", "@emnapi/runtime@^1.7.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.8.1.tgz#550fa7e3c0d49c5fb175a116e8cd70614f9a22a5" + integrity sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg== dependencies: tslib "^2.4.0" @@ -1181,16 +1078,16 @@ dependencies: tslib "^2.4.0" -"@emotion/babel-plugin@^11.12.0": - version "11.12.0" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz#7b43debb250c313101b3f885eba634f1d723fcc2" - integrity sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw== +"@emotion/babel-plugin@^11.13.5": + version "11.13.5" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz#eab8d65dbded74e0ecfd28dc218e75607c4e7bc0" + integrity sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/runtime" "^7.18.3" "@emotion/hash" "^0.9.2" "@emotion/memoize" "^0.9.0" - "@emotion/serialize" "^1.2.0" + "@emotion/serialize" "^1.3.3" babel-plugin-macros "^3.1.0" convert-source-map "^1.5.0" escape-string-regexp "^4.0.0" @@ -1198,14 +1095,14 @@ source-map "^0.5.7" stylis "4.2.0" -"@emotion/cache@^11.13.0": - version "11.13.1" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.13.1.tgz#fecfc54d51810beebf05bf2a161271a1a91895d7" - integrity sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw== +"@emotion/cache@^11.14.0": + version "11.14.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.14.0.tgz#ee44b26986eeb93c8be82bb92f1f7a9b21b2ed76" + integrity sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA== dependencies: "@emotion/memoize" "^0.9.0" "@emotion/sheet" "^1.4.0" - "@emotion/utils" "^1.4.0" + "@emotion/utils" "^1.4.2" "@emotion/weak-memoize" "^0.4.0" stylis "4.2.0" @@ -1214,17 +1111,12 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== -"@emotion/is-prop-valid@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" - integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== +"@emotion/is-prop-valid@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz#e9ad47adff0b5c94c72db3669ce46de33edf28c0" + integrity sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw== dependencies: - "@emotion/memoize" "^0.8.1" - -"@emotion/memoize@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" - integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + "@emotion/memoize" "^0.9.0" "@emotion/memoize@^0.9.0": version "0.9.0" @@ -1232,28 +1124,28 @@ integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== "@emotion/react@^11.13.3": - version "11.13.3" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.13.3.tgz#a69d0de2a23f5b48e0acf210416638010e4bd2e4" - integrity sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg== + version "11.14.0" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.14.0.tgz#cfaae35ebc67dd9ef4ea2e9acc6cd29e157dd05d" + integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.12.0" - "@emotion/cache" "^11.13.0" - "@emotion/serialize" "^1.3.1" - "@emotion/use-insertion-effect-with-fallbacks" "^1.1.0" - "@emotion/utils" "^1.4.0" + "@emotion/babel-plugin" "^11.13.5" + "@emotion/cache" "^11.14.0" + "@emotion/serialize" "^1.3.3" + "@emotion/use-insertion-effect-with-fallbacks" "^1.2.0" + "@emotion/utils" "^1.4.2" "@emotion/weak-memoize" "^0.4.0" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.2.0", "@emotion/serialize@^1.3.1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.2.tgz#e1c1a2e90708d5d85d81ccaee2dfeb3cc0cccf7a" - integrity sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA== +"@emotion/serialize@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.3.tgz#d291531005f17d704d0463a032fe679f376509e8" + integrity sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA== dependencies: "@emotion/hash" "^0.9.2" "@emotion/memoize" "^0.9.0" "@emotion/unitless" "^0.10.0" - "@emotion/utils" "^1.4.1" + "@emotion/utils" "^1.4.2" csstype "^3.0.2" "@emotion/sheet@^1.4.0": @@ -1261,25 +1153,20 @@ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== -"@emotion/unitless@0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db" - integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw== - -"@emotion/unitless@^0.10.0": +"@emotion/unitless@0.10.0", "@emotion/unitless@^0.10.0": version "0.10.0" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745" integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== -"@emotion/use-insertion-effect-with-fallbacks@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz#1a818a0b2c481efba0cf34e5ab1e0cb2dcb9dfaf" - integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw== +"@emotion/use-insertion-effect-with-fallbacks@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz#8a8cb77b590e09affb960f4ff1e9a89e532738bf" + integrity sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg== -"@emotion/utils@^1.4.0", "@emotion/utils@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.1.tgz#b3adbb43de12ee2149541c4f1337d2eb7774f0ad" - integrity sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA== +"@emotion/utils@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.2.tgz#6df6c45881fcb1c412d6688a311a98b7f59c1b52" + integrity sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA== "@emotion/weak-memoize@^0.4.0": version "0.4.0" @@ -1291,404 +1178,397 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18" integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA== -"@esbuild/aix-ppc64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz#a1414903bb38027382f85f03dda6065056757727" - integrity sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA== - "@esbuild/aix-ppc64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz#521cbd968dcf362094034947f76fa1b18d2d403c" integrity sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw== +"@esbuild/aix-ppc64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz#815b39267f9bffd3407ea6c376ac32946e24f8d2" + integrity sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg== + "@esbuild/android-arm64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f" integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg== -"@esbuild/android-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz#c859994089e9767224269884061f89dae6fb51c6" - integrity sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w== - "@esbuild/android-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz#61ea550962d8aa12a9b33194394e007657a6df57" integrity sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA== +"@esbuild/android-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz#19b882408829ad8e12b10aff2840711b2da361e8" + integrity sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg== + "@esbuild/android-arm@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26" integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA== -"@esbuild/android-arm@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.8.tgz#96a8f2ca91c6cd29ea90b1af79d83761c8ba0059" - integrity sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw== - "@esbuild/android-arm@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.2.tgz#554887821e009dd6d853f972fde6c5143f1de142" integrity sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA== +"@esbuild/android-arm@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.3.tgz#90be58de27915efa27b767fcbdb37a4470627d7b" + integrity sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA== + "@esbuild/android-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff" integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw== -"@esbuild/android-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.8.tgz#a3a626c4fec4a024a9fa8c7679c39996e92916f0" - integrity sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA== - "@esbuild/android-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.2.tgz#a7ce9d0721825fc578f9292a76d9e53334480ba2" integrity sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A== +"@esbuild/android-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.3.tgz#d7dcc976f16e01a9aaa2f9b938fbec7389f895ac" + integrity sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ== + "@esbuild/darwin-arm64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz#49d8bf8b1df95f759ac81eb1d0736018006d7e34" integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ== -"@esbuild/darwin-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz#a5e1252ca2983d566af1c0ea39aded65736fc66d" - integrity sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw== - "@esbuild/darwin-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz#2cb7659bd5d109803c593cfc414450d5430c8256" integrity sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg== +"@esbuild/darwin-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz#9f6cac72b3a8532298a6a4493ed639a8988e8abd" + integrity sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg== + "@esbuild/darwin-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418" integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ== -"@esbuild/darwin-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz#5271b0df2bb12ce8df886704bfdd1c7cc01385d2" - integrity sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg== - "@esbuild/darwin-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz#e741fa6b1abb0cd0364126ba34ca17fd5e7bf509" integrity sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA== +"@esbuild/darwin-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz#ac61d645faa37fd650340f1866b0812e1fb14d6a" + integrity sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg== + "@esbuild/freebsd-arm64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c" integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw== -"@esbuild/freebsd-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz#d0a0e7fdf19733b8bb1566b81df1aa0bb7e46ada" - integrity sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA== - "@esbuild/freebsd-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz#2b64e7116865ca172d4ce034114c21f3c93e397c" integrity sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g== +"@esbuild/freebsd-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz#b8625689d73cf1830fe58c39051acdc12474ea1b" + integrity sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w== + "@esbuild/freebsd-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f" integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw== -"@esbuild/freebsd-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz#2de8b2e0899d08f1cb1ef3128e159616e7e85343" - integrity sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw== - "@esbuild/freebsd-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz#e5252551e66f499e4934efb611812f3820e990bb" integrity sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA== +"@esbuild/freebsd-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz#07be7dd3c9d42fe0eccd2ab9f9ded780bc53bead" + integrity sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA== + "@esbuild/linux-arm64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8" integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg== -"@esbuild/linux-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz#a4209efadc0c2975716458484a4e90c237c48ae9" - integrity sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w== - "@esbuild/linux-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz#dc4acf235531cd6984f5d6c3b13dbfb7ddb303cb" integrity sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw== +"@esbuild/linux-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz#bf31918fe5c798586460d2b3d6c46ed2c01ca0b6" + integrity sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg== + "@esbuild/linux-arm@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911" integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw== -"@esbuild/linux-arm@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz#ccd9e291c24cd8d9142d819d463e2e7200d25b19" - integrity sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg== - "@esbuild/linux-arm@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz#56a900e39240d7d5d1d273bc053daa295c92e322" integrity sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw== +"@esbuild/linux-arm@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz#28493ee46abec1dc3f500223cd9f8d2df08f9d11" + integrity sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw== + "@esbuild/linux-ia32@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783" integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA== -"@esbuild/linux-ia32@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz#006ad1536d0c2b28fb3a1cf0b53bcb85aaf92c4d" - integrity sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg== - "@esbuild/linux-ia32@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz#d4a36d473360f6870efcd19d52bbfff59a2ed1cc" integrity sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w== +"@esbuild/linux-ia32@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz#750752a8b30b43647402561eea764d0a41d0ee29" + integrity sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg== + "@esbuild/linux-loong64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506" integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg== -"@esbuild/linux-loong64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz#127b3fbfb2c2e08b1397e985932f718f09a8f5c4" - integrity sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ== - "@esbuild/linux-loong64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz#fcf0ab8c3eaaf45891d0195d4961cb18b579716a" integrity sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg== +"@esbuild/linux-loong64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz#a5a92813a04e71198c50f05adfaf18fc1e95b9ed" + integrity sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA== + "@esbuild/linux-mips64el@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96" integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg== -"@esbuild/linux-mips64el@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz#837d1449517791e3fa7d82675a2d06d9f56cb340" - integrity sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw== - "@esbuild/linux-mips64el@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz#598b67d34048bb7ee1901cb12e2a0a434c381c10" integrity sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw== +"@esbuild/linux-mips64el@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz#deb45d7fd2d2161eadf1fbc593637ed766d50bb1" + integrity sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw== + "@esbuild/linux-ppc64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9" integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ== -"@esbuild/linux-ppc64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz#aa2e3bd93ab8df084212f1895ca4b03c42d9e0fe" - integrity sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ== - "@esbuild/linux-ppc64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz#3846c5df6b2016dab9bc95dde26c40f11e43b4c0" integrity sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ== +"@esbuild/linux-ppc64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz#6f39ae0b8c4d3d2d61a65b26df79f6e12a1c3d78" + integrity sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA== + "@esbuild/linux-riscv64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e" integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA== -"@esbuild/linux-riscv64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz#a340620e31093fef72767dd28ab04214b3442083" - integrity sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg== - "@esbuild/linux-riscv64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz#173d4475b37c8d2c3e1707e068c174bb3f53d07d" integrity sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA== +"@esbuild/linux-riscv64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz#4c5c19c3916612ec8e3915187030b9df0b955c1d" + integrity sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ== + "@esbuild/linux-s390x@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d" integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ== -"@esbuild/linux-s390x@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz#ddfed266c8c13f5efb3105a0cd47f6dcd0e79e71" - integrity sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg== - "@esbuild/linux-s390x@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz#f7a4790105edcab8a5a31df26fbfac1aa3dacfab" integrity sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w== +"@esbuild/linux-s390x@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz#9ed17b3198fa08ad5ccaa9e74f6c0aff7ad0156d" + integrity sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw== + "@esbuild/linux-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4" integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw== -"@esbuild/linux-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz#9a4f78c75c051e8c060183ebb39a269ba936a2ac" - integrity sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ== - "@esbuild/linux-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz#2ecc1284b1904aeb41e54c9ddc7fcd349b18f650" integrity sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA== +"@esbuild/linux-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz#12383dcbf71b7cf6513e58b4b08d95a710bf52a5" + integrity sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA== + "@esbuild/netbsd-arm64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d" integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw== -"@esbuild/netbsd-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz#902c80e1d678047926387230bc037e63e00697d0" - integrity sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw== - "@esbuild/netbsd-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz#e2863c2cd1501845995cb11adf26f7fe4be527b0" integrity sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw== +"@esbuild/netbsd-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz#dd0cb2fa543205fcd931df44f4786bfcce6df7d7" + integrity sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA== + "@esbuild/netbsd-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79" integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ== -"@esbuild/netbsd-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz#2d9eb4692add2681ff05a14ce99de54fbed7079c" - integrity sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg== - "@esbuild/netbsd-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz#93f7609e2885d1c0b5a1417885fba8d1fcc41272" integrity sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA== +"@esbuild/netbsd-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz#028ad1807a8e03e155153b2d025b506c3787354b" + integrity sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA== + "@esbuild/openbsd-arm64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd" integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw== -"@esbuild/openbsd-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz#89c3b998c6de739db38ab7fb71a8a76b3fa84a45" - integrity sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ== - "@esbuild/openbsd-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz#a1985604a203cdc325fd47542e106fafd698f02e" integrity sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA== +"@esbuild/openbsd-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz#e3c16ff3490c9b59b969fffca87f350ffc0e2af5" + integrity sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw== + "@esbuild/openbsd-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0" integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg== -"@esbuild/openbsd-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz#2f01615cf472b0e48c077045cfd96b5c149365cc" - integrity sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ== - "@esbuild/openbsd-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz#8209e46c42f1ffbe6e4ef77a32e1f47d404ad42a" integrity sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg== -"@esbuild/openharmony-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz#a201f720cd2c3ebf9a6033fcc3feb069a54b509a" - integrity sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg== +"@esbuild/openbsd-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz#c5a4693fcb03d1cbecbf8b422422468dfc0d2a8b" + integrity sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ== "@esbuild/openharmony-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz#8fade4441893d9cc44cbd7dcf3776f508ab6fb2f" integrity sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag== +"@esbuild/openharmony-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz#082082444f12db564a0775a41e1991c0e125055e" + integrity sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g== + "@esbuild/sunos-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5" integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA== -"@esbuild/sunos-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz#07046c977985a3334667f19e6ab3a01a80862afb" - integrity sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w== - "@esbuild/sunos-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz#980d4b9703a16f0f07016632424fc6d9a789dfc2" integrity sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg== +"@esbuild/sunos-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz#5ab036c53f929e8405c4e96e865a424160a1b537" + integrity sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA== + "@esbuild/win32-arm64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e" integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw== -"@esbuild/win32-arm64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz#4a5470caf0d16127c05d4833d4934213c69392d1" - integrity sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ== - "@esbuild/win32-arm64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz#1c09a3633c949ead3d808ba37276883e71f6111a" integrity sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg== +"@esbuild/win32-arm64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz#38de700ef4b960a0045370c171794526e589862e" + integrity sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA== + "@esbuild/win32-ia32@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d" integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ== -"@esbuild/win32-ia32@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz#3de3e8470b7b328d99dbc3e9ec1eace207e5bbc4" - integrity sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg== - "@esbuild/win32-ia32@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz#1b1e3a63ad4bef82200fef4e369e0fff7009eee5" integrity sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ== +"@esbuild/win32-ia32@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz#451b93dc03ec5d4f38619e6cd64d9f9eff06f55c" + integrity sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q== + "@esbuild/win32-x64@0.25.5": version "0.25.5" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1" integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g== -"@esbuild/win32-x64@0.25.8": - version "0.25.8" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz#610d7ea539d2fcdbe39237b5cc175eb2c4451f9c" - integrity sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw== - "@esbuild/win32-x64@0.27.2": version "0.27.2" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz#9e585ab6086bef994c6e8a5b3a0481219ada862b" integrity sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ== -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" +"@esbuild/win32-x64@0.27.3": + version "0.27.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz#0eaf705c941a218a43dba8e09f1df1d6cd2f1f17" + integrity sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA== -"@eslint-community/eslint-utils@^4.7.0": - version "4.7.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz#607084630c6c033992a082de6e6fbc1a8b52175a" - integrity sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw== +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.7.0": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" + integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== dependencies: eslint-visitor-keys "^3.4.3" "@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.12.1": - version "4.12.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" - integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + version "4.12.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== "@eslint/config-array@^0.20.1": version "0.20.1" @@ -1711,17 +1591,17 @@ dependencies: "@types/json-schema" "^7.0.15" -"@eslint/core@^0.15.1": - version "0.15.1" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.15.1.tgz#d530d44209cbfe2f82ef86d6ba08760196dd3b60" - integrity sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA== +"@eslint/core@^0.15.2": + version "0.15.2" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.15.2.tgz#59386327d7862cc3603ebc7c78159d2dcc4a868f" + integrity sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg== dependencies: "@types/json-schema" "^7.0.15" "@eslint/eslintrc@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.1.tgz#e55f7f1dd400600dd066dbba349c4c0bac916964" - integrity sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ== + version "3.3.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.3.tgz#26393a0806501b5e2b6a43aa588a4d8df67880ac" + integrity sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1729,7 +1609,7 @@ globals "^14.0.0" ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^4.1.0" + js-yaml "^4.1.1" minimatch "^3.1.2" strip-json-comments "^3.1.1" @@ -1739,44 +1619,44 @@ integrity sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ== "@eslint/object-schema@^2.1.6": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f" - integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== + version "2.1.7" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad" + integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== "@eslint/plugin-kit@^0.3.1": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz#32926b59bd407d58d817941e48b2a7049359b1fd" - integrity sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag== + version "0.3.5" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz#fd8764f0ee79c8ddab4da65460c641cefee017c5" + integrity sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w== dependencies: - "@eslint/core" "^0.15.1" + "@eslint/core" "^0.15.2" levn "^0.4.1" -"@floating-ui/core@^1.0.0": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.0.tgz#fa41b87812a16bf123122bf945946bae3fdf7fc1" - integrity sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g== +"@floating-ui/core@^1.7.4": + version "1.7.4" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.4.tgz#4a006a6e01565c0f87ba222c317b056a2cffd2f4" + integrity sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg== dependencies: - "@floating-ui/utils" "^0.2.1" + "@floating-ui/utils" "^0.2.10" -"@floating-ui/dom@^1.6.1": - version "1.6.3" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.3.tgz#954e46c1dd3ad48e49db9ada7218b0985cee75ef" - integrity sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw== +"@floating-ui/dom@^1.7.5": + version "1.7.5" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.5.tgz#60bfc83a4d1275b2a90db76bf42ca2a5f2c231c2" + integrity sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg== dependencies: - "@floating-ui/core" "^1.0.0" - "@floating-ui/utils" "^0.2.0" + "@floating-ui/core" "^1.7.4" + "@floating-ui/utils" "^0.2.10" "@floating-ui/react-dom@^2.0.0": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.8.tgz#afc24f9756d1b433e1fe0d047c24bd4d9cefaa5d" - integrity sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw== + version "2.1.7" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.7.tgz#529475cc16ee4976ba3387968117e773d9aa703e" + integrity sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg== dependencies: - "@floating-ui/dom" "^1.6.1" + "@floating-ui/dom" "^1.7.5" -"@floating-ui/utils@^0.2.0", "@floating-ui/utils@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" - integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== +"@floating-ui/utils@^0.2.10": + version "0.2.10" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.10.tgz#a2a1e3812d14525f725d011a73eceb41fef5bc1c" + integrity sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== "@gar/promisify@^1.1.3": version "1.1.3" @@ -1794,24 +1674,19 @@ integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== "@humanfs/node@^0.16.6": - version "0.16.6" - resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" - integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== + version "0.16.7" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.7.tgz#822cb7b3a12c5a240a24f621b5a2413e27a45f26" + integrity sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ== dependencies: "@humanfs/core" "^0.19.1" - "@humanwhocodes/retry" "^0.3.0" + "@humanwhocodes/retry" "^0.4.0" "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/retry@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" - integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== - -"@humanwhocodes/retry@^0.4.2": +"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.2": version "0.4.3" resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba" integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== @@ -2093,18 +1968,6 @@ resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz#a81ffb00e69267cd0a1d626eaedb8a8430b2b2f8" integrity sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw== -"@isaacs/balanced-match@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29" - integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ== - -"@isaacs/brace-expansion@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz#4b3dabab7d8e75a429414a96bd67bf4c1d13e0f3" - integrity sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA== - dependencies: - "@isaacs/balanced-match" "^4.0.1" - "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -2117,6 +1980,11 @@ wrap-ansi "^8.1.0" wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" +"@isaacs/cliui@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-9.0.0.tgz#4d0a3f127058043bf2e7ee169eaf30ed901302f3" + integrity sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg== + "@isaacs/fs-minipass@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz#2d59ae3ab4b38fb4270bfa23d30f8e2e86c7fe32" @@ -2129,33 +1997,15 @@ resolved "https://registry.yarnpkg.com/@jniac/color-xplr/-/color-xplr-1.0.15.tgz#1f6e090cd3660385bf98d8eff91755ec27d31a98" integrity sha512-72AJWq++BFJMjNx6aqRpOAU8CxeD2Z9gH9pgboOIXE8fVCIuPGP3zZd+k3bN9/b5CUAuBsZ0dV+FFXGMYwEdnQ== -"@jridgewell/gen-mapping@^0.3.12": - version "0.3.12" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz#2234ce26c62889f03db3d7fea43c1932ab3e927b" - integrity sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg== +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/gen-mapping@^0.3.5": - version "0.3.8" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" - integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== - dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/remapping@^2.3.4": +"@jridgewell/remapping@^2.3.4", "@jridgewell/remapping@^2.3.5": version "2.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== @@ -2164,52 +2014,16 @@ "@jridgewell/trace-mapping" "^0.3.24" "@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz#7358043433b2e5da569aa02cbc4c121da3af27d7" - integrity sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/sourcemap-codec@^1.5.5": +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5": version "1.5.5" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@^0.3.24": - version "0.3.25" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@jridgewell/trace-mapping@^0.3.28": - version "0.3.29" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz#a58d31eaadaf92c6695680b2e1d464a9b8fbf7fc" - integrity sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@jridgewell/trace-mapping@^0.3.31": +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28", "@jridgewell/trace-mapping@^0.3.31": version "0.3.31" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== @@ -2217,14 +2031,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.20" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" - integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - "@malept/cross-spawn-promise@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz#d0772de1aa680a0bfb9ba2f32b4c828c7857cb9d" @@ -2242,10 +2048,19 @@ lodash "^4.17.15" tmp-promise "^3.0.2" +"@napi-rs/wasm-runtime@^0.2.11": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" + integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== + dependencies: + "@emnapi/core" "^1.4.3" + "@emnapi/runtime" "^1.4.3" + "@tybys/wasm-util" "^0.10.0" + "@napi-rs/wasm-runtime@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.0.tgz#c0180393d7862cff0d412e3e1a7c3bd5ea6d9b2f" - integrity sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA== + version "1.1.1" + resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz#c3705ab549d176b8dc5172723d6156c3dc426af2" + integrity sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A== dependencies: "@emnapi/core" "^1.7.1" "@emnapi/runtime" "^1.7.1" @@ -2257,9 +2072,9 @@ integrity sha512-CRSCPJiSZoi4Pn69RYBDI9R7YK2g59vLexPQFXY0eyw+ILevIenCywzg+DqmlBik9zszEnw2HLFOUlLAcJbL7g== "@next/env@^13.4.3": - version "13.5.6" - resolved "https://registry.yarnpkg.com/@next/env/-/env-13.5.6.tgz#c1148e2e1aa166614f05161ee8f77ded467062bc" - integrity sha512-Yac/bV5sBGkkEXmAX5FWPS9Mmo2rthrOPRQQNfycJPkjUAUclomCPH7QFVCDQ4Mp2k2K1SSM6m0zrxYrOwtFQw== + version "13.5.11" + resolved "https://registry.yarnpkg.com/@next/env/-/env-13.5.11.tgz#6712d907e2682199aa1e8229b5ce028ee5a8001b" + integrity sha512-fbb2C7HChgM7CemdCY+y3N1n8pcTKdqtQLbC7/EQtPdLvlMUT9JX/dBYl8MMZAtYG4uVMyPFHXckb68q/NRwqg== "@next/eslint-plugin-next@14.0.4": version "14.0.4" @@ -2329,6 +2144,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@nolyfill/is-core-module@1.0.39": + version "1.0.39" + resolved "https://registry.yarnpkg.com/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz#3dc35ba0f1e66b403c00b39344f870298ebb1c8e" + integrity sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA== + "@npmcli/agent@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-3.0.0.tgz#1685b1fbd4a1b7bb4f930cbb68ce801edfe7aa44" @@ -2373,34 +2193,10 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@radix-ui/number@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.0.1.tgz#644161a3557f46ed38a042acf4a770e826021674" - integrity sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/number@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.1.0.tgz#1e95610461a09cdf8bb05c152e76ca1278d5da46" - integrity sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ== - -"@radix-ui/primitive@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" - integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/primitive@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2" - integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== - -"@radix-ui/primitive@1.1.1": +"@radix-ui/number@1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.1.tgz#fc169732d755c7fbad33ba8d0cd7fd10c90dc8e3" - integrity sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA== + resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.1.1.tgz#7b2c9225fbf1b126539551f5985769d0048d9090" + integrity sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g== "@radix-ui/primitive@1.1.2": version "1.1.2" @@ -2413,25 +2209,16 @@ integrity sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg== "@radix-ui/react-alert-dialog@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.0.5.tgz#70dd529cbf1e4bff386814d3776901fcaa131b8c" - integrity sha512-OrVIOcZL0tl6xibeuGt5/+UxoT2N27KCFOPjFyfXMnchxSHZ/OW7cCX2nGlIYJrbHK/fczPcFzAwvNBB6XBNMA== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-dialog" "1.0.5" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - -"@radix-ui/react-arrow@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d" - integrity sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA== + version "1.1.15" + resolved "https://registry.yarnpkg.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.15.tgz#fa751d0fdd9aa2a90961c9901dba18e638dd4b41" + integrity sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dialog" "1.1.15" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" "@radix-ui/react-arrow@1.1.7": version "1.1.7" @@ -2441,39 +2228,18 @@ "@radix-ui/react-primitive" "2.1.3" "@radix-ui/react-checkbox@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.1.2.tgz#6465b800420923ecc39cbeaa8f357b5f09dbfd52" - integrity sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.1" - "@radix-ui/react-presence" "1.1.1" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-controllable-state" "1.1.0" - "@radix-ui/react-use-previous" "1.1.0" - "@radix-ui/react-use-size" "1.1.0" - -"@radix-ui/react-collection@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159" - integrity sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA== + version "1.3.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz#db45ca8a6d5c056a92f74edbb564acee05318b79" + integrity sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - -"@radix-ui/react-collection@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.1.0.tgz#f18af78e46454a2360d103c2251773028b7724ed" - integrity sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw== - dependencies: - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-slot" "1.1.0" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" "@radix-ui/react-collection@1.1.7": version "1.1.7" @@ -2485,113 +2251,58 @@ "@radix-ui/react-primitive" "2.1.3" "@radix-ui/react-slot" "1.2.3" -"@radix-ui/react-compose-refs@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" - integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-compose-refs@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74" - integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== - -"@radix-ui/react-compose-refs@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz#6f766faa975f8738269ebb8a23bad4f5a8d2faec" - integrity sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw== - -"@radix-ui/react-compose-refs@1.1.2": +"@radix-ui/react-compose-refs@1.1.2", "@radix-ui/react-compose-refs@^1.1.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz#a2c4c47af6337048ee78ff6dc0d090b390d2bb30" integrity sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg== "@radix-ui/react-context-menu@^2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context-menu/-/react-context-menu-2.1.5.tgz#1bdbd72761439f9166f75dc4598f276265785c83" - integrity sha512-R5XaDj06Xul1KGb+WP8qiOh7tKJNz2durpLBXAGZjSVtctcRFCuEvy2gtMwRJGePwQQE5nV77gs4FwRi8T+r2g== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-menu" "2.0.6" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-controllable-state" "1.0.1" - -"@radix-ui/react-context@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" - integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== + version "2.2.16" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context-menu/-/react-context-menu-2.2.16.tgz#e7bf94a457b68af08f24ad696949144530faab50" + integrity sha512-O8morBEW+HsVG28gYDZPTrT9UUovQUlJue5YO836tiTJhuIWBm/zQHc7j388sHWtdH/xUZurK9olD2+pcqx5ww== dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-context@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.0.tgz#6df8d983546cfd1999c8512f3a8ad85a6e7fcee8" - integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A== - -"@radix-ui/react-context@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a" - integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q== + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-menu" "2.1.16" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.2.2" "@radix-ui/react-context@1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.2.tgz#61628ef269a433382c364f6f1e3788a6dc213a36" integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA== -"@radix-ui/react-dialog@1.0.5", "@radix-ui/react-dialog@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz#71657b1b116de6c7a0b03242d7d43e01062c7300" - integrity sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-dismissable-layer" "1.0.5" - "@radix-ui/react-focus-guards" "1.0.1" - "@radix-ui/react-focus-scope" "1.0.4" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-portal" "1.0.4" - "@radix-ui/react-presence" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - "@radix-ui/react-use-controllable-state" "1.0.1" - aria-hidden "^1.1.1" - react-remove-scroll "2.5.5" - -"@radix-ui/react-direction@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b" - integrity sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA== - dependencies: - "@babel/runtime" "^7.13.10" +"@radix-ui/react-context@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.3.tgz#81286f643b310d040eaac13b18e223130861d839" + integrity sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw== -"@radix-ui/react-direction@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc" - integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg== +"@radix-ui/react-dialog@1.1.15", "@radix-ui/react-dialog@^1.0.5", "@radix-ui/react-dialog@^1.1.6": + version "1.1.15" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz#1de3d7a7e9a17a9874d29c07f5940a18a119b632" + integrity sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.11" + "@radix-ui/react-focus-guards" "1.1.3" + "@radix-ui/react-focus-scope" "1.1.7" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" "@radix-ui/react-direction@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.1.tgz#39e5a5769e676c753204b792fbe6cf508e550a14" integrity sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw== -"@radix-ui/react-dismissable-layer@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" - integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-escape-keydown" "1.0.3" - "@radix-ui/react-dismissable-layer@1.1.10": version "1.1.10" resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz#429b9bada3672c6895a5d6a642aca6ecaf4f18c3" @@ -2603,36 +2314,43 @@ "@radix-ui/react-use-callback-ref" "1.1.1" "@radix-ui/react-use-escape-keydown" "1.1.1" +"@radix-ui/react-dismissable-layer@1.1.11": + version "1.1.11" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz#e33ab6f6bdaa00f8f7327c408d9f631376b88b37" + integrity sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-escape-keydown" "1.1.1" + "@radix-ui/react-dropdown-menu@^2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz#cdf13c956c5e263afe4e5f3587b3071a25755b63" - integrity sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-menu" "2.0.6" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-controllable-state" "1.0.1" - -"@radix-ui/react-focus-guards@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" - integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA== + version "2.1.16" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz#5ee045c62bad8122347981c479d92b1ff24c7254" + integrity sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw== dependencies: - "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-menu" "2.1.16" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-controllable-state" "1.2.2" -"@radix-ui/react-focus-scope@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525" - integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA== +"@radix-ui/react-focus-guards@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz#2a5669e464ad5fde9f86d22f7fdc17781a4dfa7f" + integrity sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw== + +"@radix-ui/react-focus-scope@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz#dfe76fc103537d80bf42723a183773fd07bfb58d" + integrity sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" "@radix-ui/react-hover-card@1.1.14": version "1.1.14" @@ -2650,19 +2368,11 @@ "@radix-ui/react-use-controllable-state" "1.2.2" "@radix-ui/react-icons@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.0.tgz#c61af8f323d87682c5ca76b856d60c2312dbcb69" - integrity sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw== - -"@radix-ui/react-id@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" - integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-layout-effect" "1.0.1" + version "1.3.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-icons/-/react-icons-1.3.2.tgz#09be63d178262181aeca5fb7f7bc944b10a7f441" + integrity sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g== -"@radix-ui/react-id@1.1.1": +"@radix-ui/react-id@1.1.1", "@radix-ui/react-id@^1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.1.tgz#1404002e79a03fe062b7e3864aa01e24bd1471f7" integrity sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg== @@ -2670,93 +2380,72 @@ "@radix-ui/react-use-layout-effect" "1.1.1" "@radix-ui/react-label@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-2.0.2.tgz#9c72f1d334aac996fdc27b48a8bdddd82108fb6d" - integrity sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ== + version "2.1.8" + resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-2.1.8.tgz#d93b7c063ef2ea034df143a2464bfc0548e4b7e5" + integrity sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-primitive" "2.1.4" -"@radix-ui/react-menu@2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.0.6.tgz#2c9e093c1a5d5daa87304b2a2f884e32288ae79e" - integrity sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-collection" "1.0.3" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-direction" "1.0.1" - "@radix-ui/react-dismissable-layer" "1.0.5" - "@radix-ui/react-focus-guards" "1.0.1" - "@radix-ui/react-focus-scope" "1.0.4" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-popper" "1.1.3" - "@radix-ui/react-portal" "1.0.4" - "@radix-ui/react-presence" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-roving-focus" "1.0.4" - "@radix-ui/react-slot" "1.0.2" - "@radix-ui/react-use-callback-ref" "1.0.1" - aria-hidden "^1.1.1" - react-remove-scroll "2.5.5" +"@radix-ui/react-menu@2.1.16": + version "2.1.16" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.1.16.tgz#528a5a973c3a7413d3d49eb9ccd229aa52402911" + integrity sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-collection" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-dismissable-layer" "1.1.11" + "@radix-ui/react-focus-guards" "1.1.3" + "@radix-ui/react-focus-scope" "1.1.7" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.8" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-roving-focus" "1.1.11" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" "@radix-ui/react-menubar@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-menubar/-/react-menubar-1.0.4.tgz#7d46ababfec63db3868d9ed79366686634c1201a" - integrity sha512-bHgUo9gayKZfaQcWSSLr++LyS0rgh+MvD89DE4fJ6TkGHvjHgPaBZf44hdka7ogOxIOdj9163J+5xL2Dn4qzzg== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-collection" "1.0.3" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-direction" "1.0.1" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-menu" "2.0.6" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-roving-focus" "1.0.4" - "@radix-ui/react-use-controllable-state" "1.0.1" + version "1.1.16" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menubar/-/react-menubar-1.1.16.tgz#5edf7ea2ff7aa7e3ba896b35cf577f122160121c" + integrity sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-collection" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-menu" "2.1.16" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-roving-focus" "1.1.11" + "@radix-ui/react-use-controllable-state" "1.2.2" "@radix-ui/react-popover@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.0.7.tgz#23eb7e3327330cb75ec7b4092d685398c1654e3c" - integrity sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-dismissable-layer" "1.0.5" - "@radix-ui/react-focus-guards" "1.0.1" - "@radix-ui/react-focus-scope" "1.0.4" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-popper" "1.1.3" - "@radix-ui/react-portal" "1.0.4" - "@radix-ui/react-presence" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - "@radix-ui/react-use-controllable-state" "1.0.1" - aria-hidden "^1.1.1" - react-remove-scroll "2.5.5" - -"@radix-ui/react-popper@1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42" - integrity sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w== + version "1.1.15" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.15.tgz#9c852f93990a687ebdc949b2c3de1f37cdc4c5d5" + integrity sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA== dependencies: - "@babel/runtime" "^7.13.10" - "@floating-ui/react-dom" "^2.0.0" - "@radix-ui/react-arrow" "1.0.3" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-layout-effect" "1.0.1" - "@radix-ui/react-use-rect" "1.0.1" - "@radix-ui/react-use-size" "1.0.1" - "@radix-ui/rect" "1.0.1" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.11" + "@radix-ui/react-focus-guards" "1.1.3" + "@radix-ui/react-focus-scope" "1.1.7" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.8" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" "@radix-ui/react-popper@1.2.7": version "1.2.7" @@ -2774,13 +2463,21 @@ "@radix-ui/react-use-size" "1.1.1" "@radix-ui/rect" "1.1.1" -"@radix-ui/react-portal@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" - integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q== +"@radix-ui/react-popper@1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.8.tgz#a79f39cdd2b09ab9fb50bf95250918422c4d9602" + integrity sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.3" + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-rect" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + "@radix-ui/rect" "1.1.1" "@radix-ui/react-portal@1.1.9": version "1.1.9" @@ -2790,23 +2487,6 @@ "@radix-ui/react-primitive" "2.1.3" "@radix-ui/react-use-layout-effect" "1.1.1" -"@radix-ui/react-presence@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" - integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-use-layout-effect" "1.0.1" - -"@radix-ui/react-presence@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.1.tgz#98aba423dba5e0c687a782c0669dcd99de17f9b1" - integrity sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A== - dependencies: - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-use-layout-effect" "1.1.0" - "@radix-ui/react-presence@1.1.4": version "1.1.4" resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.4.tgz#253ac0ad4946c5b4a9c66878335f5cf07c967ced" @@ -2823,35 +2503,6 @@ "@radix-ui/react-compose-refs" "1.1.2" "@radix-ui/react-use-layout-effect" "1.1.1" -"@radix-ui/react-primitive@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" - integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-slot" "1.0.2" - -"@radix-ui/react-primitive@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz#fe05715faa9203a223ccc0be15dc44b9f9822884" - integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw== - dependencies: - "@radix-ui/react-slot" "1.1.0" - -"@radix-ui/react-primitive@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz#6d9efc550f7520135366f333d1e820cf225fad9e" - integrity sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg== - dependencies: - "@radix-ui/react-slot" "1.1.1" - -"@radix-ui/react-primitive@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz#ac8b7854d87b0d7af388d058268d9a7eb64ca8ef" - integrity sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w== - dependencies: - "@radix-ui/react-slot" "1.1.2" - "@radix-ui/react-primitive@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz#db9b8bcff49e01be510ad79893fb0e4cda50f1bc" @@ -2859,22 +2510,20 @@ dependencies: "@radix-ui/react-slot" "1.2.3" -"@radix-ui/react-progress@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-progress/-/react-progress-1.0.3.tgz#8380272fdc64f15cbf263a294dea70a7d5d9b4fa" - integrity sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag== +"@radix-ui/react-primitive@2.1.4", "@radix-ui/react-primitive@^2.0.2": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz#2626ea309ebd63bf5767d3e7fc4081f81b993df0" + integrity sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.2.4" -"@radix-ui/react-progress@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-progress/-/react-progress-1.1.2.tgz#3584c346d47f2a6f86076ce5af56ab00c66ded2b" - integrity sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA== +"@radix-ui/react-progress@^1.0.3", "@radix-ui/react-progress@^1.1.2": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@radix-ui/react-progress/-/react-progress-1.1.8.tgz#9f9a68d75bf763f9c64808724a83d2de804bd061" + integrity sha512-+gISHcSPUJ7ktBy9RnTqbdKW78bcGke3t6taawyZ71pio1JewwGSJizycs7rLhGTvMJYCQB1DBK4KQsxs7U8dA== dependencies: - "@radix-ui/react-context" "1.1.1" - "@radix-ui/react-primitive" "2.0.2" + "@radix-ui/react-context" "1.1.3" + "@radix-ui/react-primitive" "2.1.4" "@radix-ui/react-radio-group@^1.1.3": version "1.3.8" @@ -2892,22 +2541,6 @@ "@radix-ui/react-use-previous" "1.1.1" "@radix-ui/react-use-size" "1.1.1" -"@radix-ui/react-roving-focus@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz#e90c4a6a5f6ac09d3b8c1f5b5e81aab2f0db1974" - integrity sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-collection" "1.0.3" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-direction" "1.0.1" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-controllable-state" "1.0.1" - "@radix-ui/react-roving-focus@1.1.11": version "1.1.11" resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz#ef54384b7361afc6480dcf9907ef2fedb5080fd9" @@ -2923,87 +2556,71 @@ "@radix-ui/react-use-callback-ref" "1.1.1" "@radix-ui/react-use-controllable-state" "1.2.2" -"@radix-ui/react-select@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-2.0.0.tgz#a3511792a51a7018d6559357323a7f52e0e38887" - integrity sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/number" "1.0.1" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-collection" "1.0.3" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-direction" "1.0.1" - "@radix-ui/react-dismissable-layer" "1.0.5" - "@radix-ui/react-focus-guards" "1.0.1" - "@radix-ui/react-focus-scope" "1.0.4" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-popper" "1.1.3" - "@radix-ui/react-portal" "1.0.4" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-controllable-state" "1.0.1" - "@radix-ui/react-use-layout-effect" "1.0.1" - "@radix-ui/react-use-previous" "1.0.1" - "@radix-ui/react-visually-hidden" "1.0.3" - aria-hidden "^1.1.1" - react-remove-scroll "2.5.5" - -"@radix-ui/react-separator@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.0.3.tgz#be5a931a543d5726336b112f465f58585c04c8aa" - integrity sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw== +"@radix-ui/react-scroll-area@^1.2.10": + version "1.2.10" + resolved "https://registry.yarnpkg.com/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz#e4fd3b4a79bb77bec1a52f0c8f26d8f3f1ca4b22" + integrity sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A== dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.3" - -"@radix-ui/react-slider@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-1.2.0.tgz#7a4c817d24386b420631a3fdc75563706d743472" - integrity sha512-dAHCDA4/ySXROEPaRtaMV5WHL8+JB/DbtyTbJjYkY0RXmKMO2Ln8DFZhywG5/mVQ4WqHDBc8smc14yPXPqZHYA== - dependencies: - "@radix-ui/number" "1.1.0" - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-collection" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-direction" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-controllable-state" "1.1.0" - "@radix-ui/react-use-layout-effect" "1.1.0" - "@radix-ui/react-use-previous" "1.1.0" - "@radix-ui/react-use-size" "1.1.0" - -"@radix-ui/react-slot@1.0.2", "@radix-ui/react-slot@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" - integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/number" "1.1.1" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" -"@radix-ui/react-slot@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.0.tgz#7c5e48c36ef5496d97b08f1357bb26ed7c714b84" - integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw== +"@radix-ui/react-select@^2.0.0": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-2.2.6.tgz#022cf8dab16bf05d0d1b4df9e53e4bea1b744fd9" + integrity sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ== dependencies: - "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/number" "1.1.1" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-collection" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-dismissable-layer" "1.1.11" + "@radix-ui/react-focus-guards" "1.1.3" + "@radix-ui/react-focus-scope" "1.1.7" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.8" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-visually-hidden" "1.2.3" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" -"@radix-ui/react-slot@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.1.tgz#ab9a0ffae4027db7dc2af503c223c978706affc3" - integrity sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g== +"@radix-ui/react-separator@^1.0.3": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.1.8.tgz#24f871fbf9630af316d0c14cbc7519a6e33aa11e" + integrity sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g== dependencies: - "@radix-ui/react-compose-refs" "1.1.1" + "@radix-ui/react-primitive" "2.1.4" -"@radix-ui/react-slot@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.2.tgz#daffff7b2bfe99ade63b5168407680b93c00e1c6" - integrity sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ== +"@radix-ui/react-slider@^1.2.0": + version "1.3.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-1.3.6.tgz#409453110b8f34ca00972750b80cd792f0b23a8c" + integrity sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw== dependencies: - "@radix-ui/react-compose-refs" "1.1.1" + "@radix-ui/number" "1.1.1" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-collection" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" "@radix-ui/react-slot@1.2.3": version "1.2.3" @@ -3012,7 +2629,7 @@ dependencies: "@radix-ui/react-compose-refs" "1.1.2" -"@radix-ui/react-slot@1.2.4": +"@radix-ui/react-slot@1.2.4", "@radix-ui/react-slot@^1.0.2": version "1.2.4" resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.2.4.tgz#63c0ba05fdf90cc49076b94029c852d7bac1fb83" integrity sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA== @@ -3020,33 +2637,31 @@ "@radix-ui/react-compose-refs" "1.1.2" "@radix-ui/react-switch@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.0.3.tgz#6119f16656a9eafb4424c600fdb36efa5ec5837e" - integrity sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-use-controllable-state" "1.0.1" - "@radix-ui/react-use-previous" "1.0.1" - "@radix-ui/react-use-size" "1.0.1" + version "1.2.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.2.6.tgz#ff79acb831f0d5ea9216cfcc5b939912571358e3" + integrity sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" "@radix-ui/react-tabs@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz#993608eec55a5d1deddd446fa9978d2bc1053da2" - integrity sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-direction" "1.0.1" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-presence" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-roving-focus" "1.0.4" - "@radix-ui/react-use-controllable-state" "1.0.1" + version "1.1.13" + resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz#3537ce379d7e7ff4eeb6b67a0973e139c2ac1f15" + integrity sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-roving-focus" "1.1.11" + "@radix-ui/react-use-controllable-state" "1.2.2" "@radix-ui/react-toggle-group@1.1.11": version "1.1.11" @@ -3061,7 +2676,7 @@ "@radix-ui/react-toggle" "1.1.10" "@radix-ui/react-use-controllable-state" "1.2.2" -"@radix-ui/react-toggle@1.1.10": +"@radix-ui/react-toggle@1.1.10", "@radix-ui/react-toggle@^1.1.1": version "1.1.10" resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz#b04ba0f9609599df666fce5b2f38109a197f08cf" integrity sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ== @@ -3070,66 +2685,29 @@ "@radix-ui/react-primitive" "2.1.3" "@radix-ui/react-use-controllable-state" "1.2.2" -"@radix-ui/react-toggle@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.1.1.tgz#939162f87d2c6cfba912a9908ed5ee651bd1ce8f" - integrity sha512-i77tcgObYr743IonC1hrsnnPmszDRn8p+EGUsUt+5a/JFn28fxaM88Py6V2mc8J5kELMWishI0rLnuGLFD/nnQ== - dependencies: - "@radix-ui/primitive" "1.1.1" - "@radix-ui/react-primitive" "2.0.1" - "@radix-ui/react-use-controllable-state" "1.1.0" - "@radix-ui/react-tooltip@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz#8f55070f852e7e7450cc1d9210b793d2e5a7686e" - integrity sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.1" - "@radix-ui/react-compose-refs" "1.0.1" - "@radix-ui/react-context" "1.0.1" - "@radix-ui/react-dismissable-layer" "1.0.5" - "@radix-ui/react-id" "1.0.1" - "@radix-ui/react-popper" "1.1.3" - "@radix-ui/react-portal" "1.0.4" - "@radix-ui/react-presence" "1.0.1" - "@radix-ui/react-primitive" "1.0.3" - "@radix-ui/react-slot" "1.0.2" - "@radix-ui/react-use-controllable-state" "1.0.1" - "@radix-ui/react-visually-hidden" "1.0.3" - -"@radix-ui/react-use-callback-ref@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" - integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz#3f50267e25bccfc9e20bb3036bfd9ab4c2c30c2c" + integrity sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg== dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-use-callback-ref@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" - integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.11" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.8" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-visually-hidden" "1.2.3" "@radix-ui/react-use-callback-ref@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz#62a4dba8b3255fdc5cc7787faeac1c6e4cc58d40" integrity sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg== -"@radix-ui/react-use-controllable-state@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" - integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.1" - -"@radix-ui/react-use-controllable-state@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0" - integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw== - dependencies: - "@radix-ui/react-use-callback-ref" "1.1.0" - "@radix-ui/react-use-controllable-state@1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz#905793405de57d61a439f4afebbb17d0645f3190" @@ -3145,14 +2723,6 @@ dependencies: "@radix-ui/react-use-layout-effect" "1.1.1" -"@radix-ui/react-use-escape-keydown@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" - integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.1" - "@radix-ui/react-use-escape-keydown@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz#b3fed9bbea366a118f40427ac40500aa1423cc29" @@ -3160,48 +2730,16 @@ dependencies: "@radix-ui/react-use-callback-ref" "1.1.1" -"@radix-ui/react-use-layout-effect@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" - integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-use-layout-effect@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27" - integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== - "@radix-ui/react-use-layout-effect@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz#0c4230a9eed49d4589c967e2d9c0d9d60a23971e" integrity sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ== -"@radix-ui/react-use-previous@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz#b595c087b07317a4f143696c6a01de43b0d0ec66" - integrity sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw== - dependencies: - "@babel/runtime" "^7.13.10" - -"@radix-ui/react-use-previous@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz#d4dd37b05520f1d996a384eb469320c2ada8377c" - integrity sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og== - "@radix-ui/react-use-previous@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz#1a1ad5568973d24051ed0af687766f6c7cb9b5b5" integrity sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ== -"@radix-ui/react-use-rect@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2" - integrity sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/rect" "1.0.1" - "@radix-ui/react-use-rect@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz#01443ca8ed071d33023c1113e5173b5ed8769152" @@ -3209,21 +2747,6 @@ dependencies: "@radix-ui/rect" "1.1.1" -"@radix-ui/react-use-size@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2" - integrity sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-layout-effect" "1.0.1" - -"@radix-ui/react-use-size@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz#b4dba7fbd3882ee09e8d2a44a3eed3a7e555246b" - integrity sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw== - dependencies: - "@radix-ui/react-use-layout-effect" "1.1.0" - "@radix-ui/react-use-size@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz#6de276ffbc389a537ffe4316f5b0f24129405b37" @@ -3231,20 +2754,12 @@ dependencies: "@radix-ui/react-use-layout-effect" "1.1.1" -"@radix-ui/react-visually-hidden@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac" - integrity sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA== - dependencies: - "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.3" - -"@radix-ui/rect@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.1.tgz#bf8e7d947671996da2e30f4904ece343bc4a883f" - integrity sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ== +"@radix-ui/react-visually-hidden@1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz#a8c38c8607735dc9f05c32f87ab0f9c2b109efbf" + integrity sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug== dependencies: - "@babel/runtime" "^7.13.10" + "@radix-ui/react-primitive" "2.1.3" "@radix-ui/rect@1.1.1": version "1.1.1" @@ -3271,166 +2786,186 @@ resolved "https://registry.yarnpkg.com/@recast-navigation/wasm/-/wasm-0.43.0.tgz#e811263fa73344fc0905d5e41b7845d88757516c" integrity sha512-0zEPbCacIpU1nWeErPuo6KK2o+yCKEWimbhtHqIfvulLAZPoq/2ErWH87RddlEwksDBUuXu/DV4+EUNr6LjVvg== -"@rollup/rollup-android-arm-eabi@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz#7e478b66180c5330429dd161bf84dad66b59c8eb" - integrity sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w== - -"@rollup/rollup-android-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz#2b025510c53a5e3962d3edade91fba9368c9d71c" - integrity sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w== - -"@rollup/rollup-darwin-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz#3577c38af68ccf34c03e84f476bfd526abca10a0" - integrity sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA== - -"@rollup/rollup-darwin-x64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz#2bf5f2520a1f3b551723d274b9669ba5b75ed69c" - integrity sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ== - -"@rollup/rollup-freebsd-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz#4bb9cc80252564c158efc0710153c71633f1927c" - integrity sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w== - -"@rollup/rollup-freebsd-x64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz#2301289094d49415a380cf942219ae9d8b127440" - integrity sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q== - -"@rollup/rollup-linux-arm-gnueabihf@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz#1d03d776f2065e09fc141df7d143476e94acca88" - integrity sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw== - -"@rollup/rollup-linux-arm-musleabihf@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz#8623de0e040b2fd52a541c602688228f51f96701" - integrity sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg== - -"@rollup/rollup-linux-arm64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz#ce2d1999bc166277935dde0301cde3dd0417fb6e" - integrity sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w== - -"@rollup/rollup-linux-arm64-musl@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz#88c2523778444da952651a2219026416564a4899" - integrity sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A== - -"@rollup/rollup-linux-loong64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz#578ca2220a200ac4226c536c10c8cc6e4f276714" - integrity sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g== - -"@rollup/rollup-linux-ppc64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz#aa338d3effd4168a20a5023834a74ba2c3081293" - integrity sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw== - -"@rollup/rollup-linux-riscv64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz#16ba582f9f6cff58119aa242782209b1557a1508" - integrity sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g== - -"@rollup/rollup-linux-riscv64-musl@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz#e404a77ebd6378483888b8064c703adb011340ab" - integrity sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A== - -"@rollup/rollup-linux-s390x-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz#92ad52d306227c56bec43d96ad2164495437ffe6" - integrity sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg== - -"@rollup/rollup-linux-x64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz#fd0dea3bb9aa07e7083579f25e1c2285a46cb9fa" - integrity sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w== - -"@rollup/rollup-linux-x64-musl@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz#37a3efb09f18d555f8afc490e1f0444885de8951" - integrity sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q== - -"@rollup/rollup-openharmony-arm64@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz#c489bec9f4f8320d42c9b324cca220c90091c1f7" - integrity sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw== - -"@rollup/rollup-win32-arm64-msvc@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz#152832b5f79dc22d1606fac3db946283601b7080" - integrity sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw== - -"@rollup/rollup-win32-ia32-msvc@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz#54d91b2bb3bf3e9f30d32b72065a4e52b3a172a5" - integrity sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA== - -"@rollup/rollup-win32-x64-gnu@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz#df9df03e61a003873efec8decd2034e7f135c71e" - integrity sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg== - -"@rollup/rollup-win32-x64-msvc@4.53.3": - version "4.53.3" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz#38ae84f4c04226c1d56a3b17296ef1e0460ecdfe" - integrity sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ== +"@rollup/rollup-android-arm-eabi@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz#add5e608d4e7be55bc3ca3d962490b8b1890e088" + integrity sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg== + +"@rollup/rollup-android-arm64@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz#10bd0382b73592beee6e9800a69401a29da625c4" + integrity sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w== + +"@rollup/rollup-darwin-arm64@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz#1e99ab04c0b8c619dd7bbde725ba2b87b55bfd81" + integrity sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg== + +"@rollup/rollup-darwin-x64@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz#69e741aeb2839d2e8f0da2ce7a33d8bd23632423" + integrity sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w== + +"@rollup/rollup-freebsd-arm64@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz#3736c232a999c7bef7131355d83ebdf9651a0839" + integrity sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug== + +"@rollup/rollup-freebsd-x64@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz#227dcb8f466684070169942bd3998901c9bfc065" + integrity sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q== + +"@rollup/rollup-linux-arm-gnueabihf@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz#ba004b30df31b724f99ce66e7128248bea17cb0c" + integrity sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw== + +"@rollup/rollup-linux-arm-musleabihf@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz#6929f3e07be6b6da5991f63c6b68b3e473d0a65a" + integrity sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw== + +"@rollup/rollup-linux-arm64-gnu@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz#06e89fd4a25d21fe5575d60b6f913c0e65297bfa" + integrity sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g== + +"@rollup/rollup-linux-arm64-musl@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz#fddabf395b90990d5194038e6cd8c00156ed8ac0" + integrity sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q== + +"@rollup/rollup-linux-loong64-gnu@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz#04c10bb764bbf09a3c1bd90432e92f58d6603c36" + integrity sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA== + +"@rollup/rollup-linux-loong64-musl@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz#f2450361790de80581d8687ea19142d8a4de5c0f" + integrity sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw== + +"@rollup/rollup-linux-ppc64-gnu@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz#0474f4667259e407eee1a6d38e29041b708f6a30" + integrity sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w== + +"@rollup/rollup-linux-ppc64-musl@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz#9f32074819eeb1ddbe51f50ea9dcd61a6745ec33" + integrity sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw== + +"@rollup/rollup-linux-riscv64-gnu@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz#3fdb9d4b1e29fb6b6a6da9f15654d42eb77b99b2" + integrity sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A== + +"@rollup/rollup-linux-riscv64-musl@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz#1de780d64e6be0e3e8762035c22e0d8ea68df8ed" + integrity sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw== + +"@rollup/rollup-linux-s390x-gnu@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz#1da022ffd2d9e9f0fd8344ea49e113001fbcac64" + integrity sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg== + +"@rollup/rollup-linux-x64-gnu@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz#78c16eef9520bd10e1ea7a112593bb58e2842622" + integrity sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg== + +"@rollup/rollup-linux-x64-musl@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz#a7598591b4d9af96cb3167b50a5bf1e02dfea06c" + integrity sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw== + +"@rollup/rollup-openbsd-x64@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz#c51d48c07cd6c466560e5bed934aec688ce02614" + integrity sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw== + +"@rollup/rollup-openharmony-arm64@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz#f09921d0b2a0b60afbf3586d2a7a7f208ba6df17" + integrity sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ== + +"@rollup/rollup-win32-arm64-msvc@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz#08d491717135376e4a99529821c94ecd433d5b36" + integrity sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ== + +"@rollup/rollup-win32-ia32-msvc@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz#b0c12aac1104a8b8f26a5e0098e5facbb3e3964a" + integrity sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew== + +"@rollup/rollup-win32-x64-gnu@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz#b9cccef26f5e6fdc013bf3c0911a3c77428509d0" + integrity sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ== + +"@rollup/rollup-win32-x64-msvc@4.57.1": + version "4.57.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz#a03348e7b559c792b6277cc58874b89ef46e1e72" + integrity sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA== + +"@rtsao/scc@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" + integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== "@rushstack/eslint-patch@^1.3.3": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.6.1.tgz#9ab8f811930d7af3e3d549183a50884f9eb83f36" - integrity sha512-UY+FGM/2jjMkzQLn8pxcHGMaVLh9aEitG3zY2CiY7XHdLiz3bZOwa6oDxNqEMv7zZkV+cj5DOdz0cQ1BP5Hjgw== + version "1.15.0" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.15.0.tgz#8184bcb37791e6d3c3c13a9bfbe4af263f66665f" + integrity sha512-ojSshQPKwVvSMR8yT2L/QtUkV5SXi/IfDiJ4/8d6UbTPjiHVmxZzUAzGD8Tzks1b9+qQkZa0isUOvYObedITaw== -"@shikijs/core@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-3.7.0.tgz#5300db80449f3c2d2fad825f3ec8095ea38355af" - integrity sha512-yilc0S9HvTPyahHpcum8eonYrQtmGTU0lbtwxhA6jHv4Bm1cAdlPFRCJX4AHebkCm75aKTjjRAW+DezqD1b/cg== +"@shikijs/core@3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-3.22.0.tgz#9e9e8bd6d65b61fa74205a30491b921079996cdd" + integrity sha512-iAlTtSDDbJiRpvgL5ugKEATDtHdUVkqgHDm/gbD2ZS9c88mx7G1zSYjjOxp5Qa0eaW0MAQosFRmJSk354PRoQA== dependencies: - "@shikijs/types" "3.7.0" + "@shikijs/types" "3.22.0" "@shikijs/vscode-textmate" "^10.0.2" "@types/hast" "^3.0.4" hast-util-to-html "^9.0.5" -"@shikijs/engine-javascript@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-3.7.0.tgz#e37c9568ce1b6694db6cd33927243e897159ab2e" - integrity sha512-0t17s03Cbv+ZcUvv+y33GtX75WBLQELgNdVghnsdhTgU3hVcWcMsoP6Lb0nDTl95ZJfbP1mVMO0p3byVh3uuzA== +"@shikijs/engine-javascript@3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/engine-javascript/-/engine-javascript-3.22.0.tgz#507f5cbb3e565268a35ee8aed42ff73016899e6d" + integrity sha512-jdKhfgW9CRtj3Tor0L7+yPwdG3CgP7W+ZEqSsojrMzCjD1e0IxIbwUMDDpYlVBlC08TACg4puwFGkZfLS+56Tw== dependencies: - "@shikijs/types" "3.7.0" + "@shikijs/types" "3.22.0" "@shikijs/vscode-textmate" "^10.0.2" - oniguruma-to-es "^4.3.3" + oniguruma-to-es "^4.3.4" -"@shikijs/engine-oniguruma@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-3.7.0.tgz#77afe066ed245ae9c3e790ca22344195e974ed54" - integrity sha512-5BxcD6LjVWsGu4xyaBC5bu8LdNgPCVBnAkWTtOCs/CZxcB22L8rcoWfv7Hh/3WooVjBZmFtyxhgvkQFedPGnFw== +"@shikijs/engine-oniguruma@3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/engine-oniguruma/-/engine-oniguruma-3.22.0.tgz#d16b66ed18470bc99f5026ec9f635695a10cb7f5" + integrity sha512-DyXsOG0vGtNtl7ygvabHd7Mt5EY8gCNqR9Y7Lpbbd/PbJvgWrqaKzH1JW6H6qFkuUa8aCxoiYVv8/YfFljiQxA== dependencies: - "@shikijs/types" "3.7.0" + "@shikijs/types" "3.22.0" "@shikijs/vscode-textmate" "^10.0.2" -"@shikijs/langs@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-3.7.0.tgz#c201d0218e9f3a74d92bd3f53167f0fb897c5b6e" - integrity sha512-1zYtdfXLr9xDKLTGy5kb7O0zDQsxXiIsw1iIBcNOO8Yi5/Y1qDbJ+0VsFoqTlzdmneO8Ij35g7QKF8kcLyznCQ== +"@shikijs/langs@3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/langs/-/langs-3.22.0.tgz#949338647714b89314efbd333070b0c0263b232a" + integrity sha512-x/42TfhWmp6H00T6uwVrdTJGKgNdFbrEdhaDwSR5fd5zhQ1Q46bHq9EO61SCEWJR0HY7z2HNDMaBZp8JRmKiIA== dependencies: - "@shikijs/types" "3.7.0" + "@shikijs/types" "3.22.0" -"@shikijs/themes@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-3.7.0.tgz#e4fb08ca56826dd3b0a48a555140cb090ce0a639" - integrity sha512-VJx8497iZPy5zLiiCTSIaOChIcKQwR0FebwE9S3rcN0+J/GTWwQ1v/bqhTbpbY3zybPKeO8wdammqkpXc4NVjQ== +"@shikijs/themes@3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/themes/-/themes-3.22.0.tgz#0a316f0b1bda2dea378dd0c9d7e0a703f36af2c3" + integrity sha512-o+tlOKqsr6FE4+mYJG08tfCFDS+3CG20HbldXeVoyP+cYSUxDhrFf3GPjE60U55iOkkjbpY2uC3It/eeja35/g== dependencies: - "@shikijs/types" "3.7.0" + "@shikijs/types" "3.22.0" -"@shikijs/types@3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-3.7.0.tgz#265641647708663ec8a18a9fab29449076da5a17" - integrity sha512-MGaLeaRlSWpnP0XSAum3kP3a8vtcTsITqoEPYdt3lQG3YCdQH4DnEhodkYcNMcU0uW0RffhoD1O3e0vG5eSBBg== +"@shikijs/types@3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@shikijs/types/-/types-3.22.0.tgz#43fe92d163742424e794894cb27ce6ce1b4ca8a8" + integrity sha512-491iAekgKDBFE67z70Ok5a8KBMsQ2IJwOWw3us/7ffQkIBCyOQfm/aNwVMBUriP02QshIfgHCBSIYAl3u2eWjg== dependencies: "@shikijs/vscode-textmate" "^10.0.2" "@types/hast" "^3.0.4" @@ -3480,10 +3015,10 @@ "@smithy/util-middleware" "^4.2.8" tslib "^2.6.2" -"@smithy/core@^3.20.6", "@smithy/core@^3.21.1", "@smithy/core@^3.22.0": - version "3.22.0" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.22.0.tgz#bf5ea9233e2be1d8681d06c8ed3c31966711dc83" - integrity sha512-6vjCHD6vaY8KubeNw2Fg3EK0KLGQYdldG4fYgQmA0xSW0dJ8G2xFhSOdrlUakWVoP5JuWHtFODg3PNd/DN3FDA== +"@smithy/core@^3.20.6", "@smithy/core@^3.21.1", "@smithy/core@^3.23.0": + version "3.23.0" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.23.0.tgz#64dca2825753316ace7b8342cb96c9dfc5de4e2a" + integrity sha512-Yq4UPVoQICM9zHnByLmG8632t2M0+yap4T7ANVw482J0W7HW0pOuxwVmeOwzJqX2Q89fkXz0Vybz55Wj2Xzrsg== dependencies: "@smithy/middleware-serde" "^4.2.9" "@smithy/protocol-http" "^5.3.8" @@ -3491,7 +3026,7 @@ "@smithy/util-base64" "^4.3.0" "@smithy/util-body-length-browser" "^4.2.0" "@smithy/util-middleware" "^4.2.8" - "@smithy/util-stream" "^4.5.10" + "@smithy/util-stream" "^4.5.12" "@smithy/util-utf8" "^4.2.0" "@smithy/uuid" "^1.1.0" tslib "^2.6.2" @@ -3632,12 +3167,12 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@smithy/middleware-endpoint@^4.4.11", "@smithy/middleware-endpoint@^4.4.12": - version "4.4.12" - resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.12.tgz#910c9f1cc738d104225d69f702bd28cd2a976eb0" - integrity sha512-9JMKHVJtW9RysTNjcBZQHDwB0p3iTP6B1IfQV4m+uCevkVd/VuLgwfqk5cnI4RHcp4cPwoIvxQqN4B1sxeHo8Q== +"@smithy/middleware-endpoint@^4.4.11", "@smithy/middleware-endpoint@^4.4.14": + version "4.4.14" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.14.tgz#df8aca71af70366f39305eeaf18ffd650f764219" + integrity sha512-FUFNE5KVeaY6U/GL0nzAAHkaCHzXLZcY1EhtQnsAqhD8Du13oPKtMB9/0WK4/LK6a/T5OZ24wPoSShff5iI6Ag== dependencies: - "@smithy/core" "^3.22.0" + "@smithy/core" "^3.23.0" "@smithy/middleware-serde" "^4.2.9" "@smithy/node-config-provider" "^4.3.8" "@smithy/shared-ini-file-loader" "^4.4.3" @@ -3646,15 +3181,15 @@ "@smithy/util-middleware" "^4.2.8" tslib "^2.6.2" -"@smithy/middleware-retry@^4.4.27": - version "4.4.29" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.4.29.tgz#b8f3d6e46924e7496cd107e14b238df5ef9e80b4" - integrity sha512-bmTn75a4tmKRkC5w61yYQLb3DmxNzB8qSVu9SbTYqW6GAL0WXO2bDZuMAn/GJSbOdHEdjZvWxe+9Kk015bw6Cg== +"@smithy/middleware-retry@^4.4.27", "@smithy/middleware-retry@^4.4.31": + version "4.4.31" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.4.31.tgz#1dbdbaedbd62f4900e3520f65599810123c0c461" + integrity sha512-RXBzLpMkIrxBPe4C8OmEOHvS8aH9RUuCOH++Acb5jZDEblxDjyg6un72X9IcbrGTJoiUwmI7hLypNfuDACypbg== dependencies: "@smithy/node-config-provider" "^4.3.8" "@smithy/protocol-http" "^5.3.8" "@smithy/service-error-classification" "^4.2.8" - "@smithy/smithy-client" "^4.11.1" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" "@smithy/util-middleware" "^4.2.8" "@smithy/util-retry" "^4.2.8" @@ -3688,10 +3223,10 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@smithy/node-http-handler@^4.4.8": - version "4.4.8" - resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-4.4.8.tgz#298cc148c812b9a79f0ebd75e82bdab9e6d0bbcd" - integrity sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg== +"@smithy/node-http-handler@^4.4.10", "@smithy/node-http-handler@^4.4.8": + version "4.4.10" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-4.4.10.tgz#4945e2c2e61174ec1471337e3ddd50b8e4921204" + integrity sha512-u4YeUwOWRZaHbWaebvrs3UhwQwj+2VNmcVCwXcYTvPIuVyM7Ex1ftAj+fdbG/P4AkBwLq/+SKn+ydOI4ZJE9PA== dependencies: "@smithy/abort-controller" "^4.2.8" "@smithy/protocol-http" "^5.3.8" @@ -3761,17 +3296,17 @@ "@smithy/util-utf8" "^4.2.0" tslib "^2.6.2" -"@smithy/smithy-client@^4.10.12", "@smithy/smithy-client@^4.10.8", "@smithy/smithy-client@^4.11.1": - version "4.11.1" - resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.11.1.tgz#8203e620da22e7f7218597a60193ef5a53325c41" - integrity sha512-SERgNg5Z1U+jfR6/2xPYjSEHY1t3pyTHC/Ma3YQl6qWtmiL42bvNId3W/oMUWIwu7ekL2FMPdqAmwbQegM7HeQ== +"@smithy/smithy-client@^4.10.12", "@smithy/smithy-client@^4.10.8", "@smithy/smithy-client@^4.11.3": + version "4.11.3" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.11.3.tgz#94d1083d5bc3b09e510f680ad7f82395765badf3" + integrity sha512-Q7kY5sDau8OoE6Y9zJoRGgje8P4/UY0WzH8R2ok0PDh+iJ+ZnEKowhjEqYafVcubkbYxQVaqwm3iufktzhprGg== dependencies: - "@smithy/core" "^3.22.0" - "@smithy/middleware-endpoint" "^4.4.12" + "@smithy/core" "^3.23.0" + "@smithy/middleware-endpoint" "^4.4.14" "@smithy/middleware-stack" "^4.2.8" "@smithy/protocol-http" "^5.3.8" "@smithy/types" "^4.12.0" - "@smithy/util-stream" "^4.5.10" + "@smithy/util-stream" "^4.5.12" tslib "^2.6.2" "@smithy/types@^4.12.0": @@ -3836,26 +3371,26 @@ dependencies: tslib "^2.6.2" -"@smithy/util-defaults-mode-browser@^4.3.26": - version "4.3.28" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.28.tgz#36903b2c5ae11d41b1bb3e1f899a062389feb8ff" - integrity sha512-/9zcatsCao9h6g18p/9vH9NIi5PSqhCkxQ/tb7pMgRFnqYp9XUOyOlGPDMHzr8n5ih6yYgwJEY2MLEobUgi47w== +"@smithy/util-defaults-mode-browser@^4.3.26", "@smithy/util-defaults-mode-browser@^4.3.30": + version "4.3.30" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.30.tgz#0494c467897ddf5b09b6f87712992b7b0ebe1cc1" + integrity sha512-cMni0uVU27zxOiU8TuC8pQLC1pYeZ/xEMxvchSK/ILwleRd1ugobOcIRr5vXtcRqKd4aBLWlpeBoDPJJ91LQng== dependencies: "@smithy/property-provider" "^4.2.8" - "@smithy/smithy-client" "^4.11.1" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@smithy/util-defaults-mode-node@^4.2.29": - version "4.2.31" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.31.tgz#edb1297274e334af44783f4a3c78d2e890b328bb" - integrity sha512-JTvoApUXA5kbpceI2vuqQzRjeTbLpx1eoa5R/YEZbTgtxvIB7AQZxFJ0SEyfCpgPCyVV9IT7we+ytSeIB3CyWA== +"@smithy/util-defaults-mode-node@^4.2.29", "@smithy/util-defaults-mode-node@^4.2.33": + version "4.2.33" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.33.tgz#b5d8b88d398d4556fe3e6299d7a14eac2b892750" + integrity sha512-LEb2aq5F4oZUSzWBG7S53d4UytZSkOEJPXcBq/xbG2/TmK9EW5naUZ8lKu1BEyWMzdHIzEVN16M3k8oxDq+DJA== dependencies: "@smithy/config-resolver" "^4.4.6" "@smithy/credential-provider-imds" "^4.2.8" "@smithy/node-config-provider" "^4.3.8" "@smithy/property-provider" "^4.2.8" - "@smithy/smithy-client" "^4.11.1" + "@smithy/smithy-client" "^4.11.3" "@smithy/types" "^4.12.0" tslib "^2.6.2" @@ -3892,13 +3427,13 @@ "@smithy/types" "^4.12.0" tslib "^2.6.2" -"@smithy/util-stream@^4.5.10": - version "4.5.10" - resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-4.5.10.tgz#3a7b56f0bdc3833205f80fea67d8e76756ea055b" - integrity sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g== +"@smithy/util-stream@^4.5.10", "@smithy/util-stream@^4.5.12": + version "4.5.12" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-4.5.12.tgz#f8734a01dce2e51530231e6afc8910397d3e300a" + integrity sha512-D8tgkrmhAX/UNeCZbqbEO3uqyghUnEmmoO9YEvRuwxjlkKKUE7FOgCJnqpTlQPe9MApdWPky58mNQQHbnCzoNg== dependencies: "@smithy/fetch-http-handler" "^5.3.9" - "@smithy/node-http-handler" "^4.4.8" + "@smithy/node-http-handler" "^4.4.10" "@smithy/types" "^4.12.0" "@smithy/util-base64" "^4.3.0" "@smithy/util-buffer-from" "^4.2.0" @@ -3946,14 +3481,14 @@ tslib "^2.6.2" "@solidjs/router@^0.15.3": - version "0.15.3" - resolved "https://registry.yarnpkg.com/@solidjs/router/-/router-0.15.3.tgz#2c5e7aa637980ab7fce956aedc8cd20614163f2a" - integrity sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw== + version "0.15.4" + resolved "https://registry.yarnpkg.com/@solidjs/router/-/router-0.15.4.tgz#e2b2d797541dcbdc36641e5f610f93ab4fa11c8a" + integrity sha512-WOpgg9a9T638cR+5FGbFi/IV4l2FpmBs1GpIMSPa0Ce9vyJN7Wts+X2PqMf9IYn0zUj2MlSJtm1gp7/HI/n5TQ== "@standard-schema/spec@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" - integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.1.0.tgz#a79b55dbaf8604812f52d140b2c9ab41bc150bb8" + integrity sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w== "@swc/helpers@0.5.15": version "0.5.15" @@ -4081,13 +3616,20 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@tybys/wasm-util@^0.10.1": +"@tybys/wasm-util@^0.10.0", "@tybys/wasm-util@^0.10.1": version "0.10.1" resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414" integrity sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg== dependencies: tslib "^2.4.0" +"@types/adm-zip@^0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@types/adm-zip/-/adm-zip-0.5.7.tgz#eec10b6f717d3948beb64aca0abebc4b344ac7e9" + integrity sha512-DNEs/QvmyRLurdQPChqq0Md4zGvPwHerAJYWk9l2jCbD1VPpnzRJorOdiq4zsw09NFbYnhfsoEhWtxIzXpn2yw== + dependencies: + "@types/node" "*" + "@types/babel__core@^7.20.4": version "7.20.5" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" @@ -4100,9 +3642,9 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.8" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" - integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + version "7.27.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" + integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== dependencies: "@babel/types" "^7.0.0" @@ -4115,11 +3657,11 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.7.tgz#968cdc2366ec3da159f61166428ee40f370e56c2" - integrity sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng== + version "7.28.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74" + integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== dependencies: - "@babel/types" "^7.20.7" + "@babel/types" "^7.28.2" "@types/cacheable-request@^6.0.1": version "6.0.3" @@ -4159,14 +3701,14 @@ integrity sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw== "@types/dom-webcodecs@^0.1.4": - version "0.1.13" - resolved "https://registry.yarnpkg.com/@types/dom-webcodecs/-/dom-webcodecs-0.1.13.tgz#d8be5da4f01b20721307b08ad2cca903ccf4f47f" - integrity sha512-O5hkiFIcjjszPIYyUSyvScyvrBoV3NOEEZx/pMlsu44TKzWNkLVBBxnxJz42in5n3QIolYOcBYFCPZZ0h8SkwQ== + version "0.1.18" + resolved "https://registry.yarnpkg.com/@types/dom-webcodecs/-/dom-webcodecs-0.1.18.tgz#0a4a26ffef72e584976ca8bdaefc3119b533a5c4" + integrity sha512-vAvE8C9DGWR+tkb19xyjk1TSUlJ7RUzzp4a9Anu7mwBT+fpyePWK1UxmH14tMO5zHmrnrRIMg5NutnnDztLxgg== "@types/emscripten@^1.39.6": - version "1.39.13" - resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.13.tgz#afeb1648648dc096efe57983e20387627306e2aa" - integrity sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw== + version "1.41.5" + resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.41.5.tgz#5670e4b52b098691cb844b84ee48c9176699b68d" + integrity sha512-cMQm7pxu6BxtHyqJ7mQZ2kXWV5SLmugybFdHCBbJ5eHzOo6VhBckEgAT3//rP5FwPHNPeEiq4SmQ5ucBwsOo4Q== "@types/estree@1.0.8", "@types/estree@^1.0.0", "@types/estree@^1.0.6": version "1.0.8" @@ -4174,9 +3716,9 @@ integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/fluent-ffmpeg@^2.1.27": - version "2.1.27" - resolved "https://registry.yarnpkg.com/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.27.tgz#c4eac6fbda30bb6316d2220c8faf54f48db0812d" - integrity sha512-QiDWjihpUhriISNoBi2hJBRUUmoj/BMTYcfz+F+ZM9hHWBYABFAE6hjP/TbCZC0GWwlpa3FzvHH9RzFeRusZ7A== + version "2.1.28" + resolved "https://registry.yarnpkg.com/@types/fluent-ffmpeg/-/fluent-ffmpeg-2.1.28.tgz#d8039bafc06aa8770c75aeb818d8248c39b977c1" + integrity sha512-5ovxsDwBcPfJ+eYs1I/ZpcYCnkce7pvH9AHSvrZllAp1ZPpTRDZAFjF3TRFbukxSgIYTTNYePbS0rKUmaxVbXw== dependencies: "@types/node" "*" @@ -4195,9 +3737,9 @@ "@types/unist" "*" "@types/http-cache-semantics@*": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" - integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + version "4.2.0" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#f6a7788f438cbfde15f29acad46512b4c01913b3" + integrity sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q== "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.8": version "7.0.15" @@ -4224,14 +3766,21 @@ "@types/unist" "*" "@types/ms@*": - version "0.7.34" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" - integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== + +"@types/node@*": + version "25.2.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-25.2.3.tgz#9c18245be768bdb4ce631566c7da303a5c99a7f8" + integrity sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ== + dependencies: + undici-types "~7.16.0" -"@types/node@*", "@types/node@^22", "@types/node@^22.7.7": - version "22.15.32" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.32.tgz#c301cc2275b535a5e54bb81d516b1d2e9afe06e5" - integrity sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA== +"@types/node@^22", "@types/node@^22.7.7": + version "22.19.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.11.tgz#7e1feaad24e4e36c52fa5558d5864bb4b272603e" + integrity sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w== dependencies: undici-types "~6.21.0" @@ -4256,18 +3805,30 @@ "@types/node" "*" "@types/prop-types@*": - version "15.7.11" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" - integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== + version "15.7.15" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" + integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== -"@types/react-dom@18.2.18", "@types/react-dom@^18": +"@types/react-dom@18.2.18": version "18.2.18" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.18.tgz#16946e6cd43971256d874bc3d0a72074bb8571dd" integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@18.2.47", "@types/react@^18": +"@types/react-dom@^18": + version "18.3.7" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.7.tgz#b89ddf2cd83b4feafcc4e2ea41afdfb95a0d194f" + integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== + +"@types/react@*": + version "19.2.14" + resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.14.tgz#39604929b5e3957e3a6fa0001dafb17c7af70bad" + integrity sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w== + dependencies: + csstype "^3.2.2" + +"@types/react@18.2.47": version "18.2.47" resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.47.tgz#85074b27ab563df01fbc3f68dc64bf7050b0af40" integrity sha512-xquNkkOirwyCgoClNk85BjP+aqnIS+ckAJ8i37gAbDs14jfW/J23f2GItAf33oiUPQnqNMALiFeoM9Y5mbjpVQ== @@ -4276,6 +3837,14 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@^18": + version "18.3.28" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.28.tgz#0a85b1a7243b4258d9f626f43797ba18eb5f8781" + integrity sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw== + dependencies: + "@types/prop-types" "*" + csstype "^3.2.2" + "@types/responselike@^1.0.0": version "1.0.3" resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" @@ -4284,14 +3853,14 @@ "@types/node" "*" "@types/scheduler@*": - version "0.16.8" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" - integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + version "0.26.0" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.26.0.tgz#2b7183b9bbb622d130b23bedf06899b7fec7eed5" + integrity sha512-WFHp9YUJQ6CKshqoC37iOlHnQSmxNc795UhB26CyBBttrN9svdIrUjl/NjnNmfcwtncN0h/0PPAFWv9ovP8mLA== -"@types/stylis@4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.0.tgz#199a3f473f0c3a6f6e4e1b17cdbc967f274bdc6b" - integrity sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw== +"@types/stylis@4.2.7": + version "4.2.7" + resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.7.tgz#1813190525da9d2a2b6976583bdd4af5301d9fd4" + integrity sha512-VgDNokpBoKF+wrdvhAAfS55OMQpL6QRglwTwNC3kIgBrzZxA4WsFj+2eLfEA/uMUDzBcEhYmjSbwQakn/i3ajA== "@types/unist@*", "@types/unist@^3.0.0": version "3.0.3" @@ -4299,9 +3868,9 @@ integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== "@types/verror@^1.10.3": - version "1.10.9" - resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.9.tgz#420c32adb9a2dd50b3db4c8f96501e05a0e72941" - integrity sha512-MLx9Z+9lGzwEuW16ubGeNkpBDE84RpB/NyGgg6z2BTpWzKkGU451cAY3UkUzZEp72RHF585oJ3V8JVNqIplcAQ== + version "1.10.11" + resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.11.tgz#d3d6b418978c8aa202d41e5bb3483227b6ecc1bb" + integrity sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg== "@types/wicg-file-system-access@^2020.9.5": version "2020.9.8" @@ -4342,14 +3911,14 @@ debug "^4.3.4" "@typescript-eslint/parser@^5.4.2 || ^6.0.0": - version "6.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.18.0.tgz#d494161d64832e869f0a6acc6000a2cdff858383" - integrity sha512-v6uR68SFvqhNQT41frCMCQpsP+5vySy6IdgjlzUWoo7ALCnpaWYcz/Ij2k4L8cEsL0wkvOviCMpjmtRtHNOKzA== - dependencies: - "@typescript-eslint/scope-manager" "6.18.0" - "@typescript-eslint/types" "6.18.0" - "@typescript-eslint/typescript-estree" "6.18.0" - "@typescript-eslint/visitor-keys" "6.18.0" + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" + integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== + dependencies: + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" "@typescript-eslint/project-service@8.35.1": @@ -4361,13 +3930,13 @@ "@typescript-eslint/types" "^8.35.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.18.0": - version "6.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.18.0.tgz#24ca6fc1f4a2afa71122dcfca9282878687d9997" - integrity sha512-o/UoDT2NgOJ2VfHpfr+KBY2ErWvCySNUIX/X7O9g8Zzt/tXdpfEU43qbNk8LVuWUT2E0ptzTWXh79i74PP0twA== +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== dependencies: - "@typescript-eslint/types" "6.18.0" - "@typescript-eslint/visitor-keys" "6.18.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" "@typescript-eslint/scope-manager@8.35.1": version "8.35.1" @@ -4377,11 +3946,16 @@ "@typescript-eslint/types" "8.35.1" "@typescript-eslint/visitor-keys" "8.35.1" -"@typescript-eslint/tsconfig-utils@8.35.1", "@typescript-eslint/tsconfig-utils@^8.35.1": +"@typescript-eslint/tsconfig-utils@8.35.1": version "8.35.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.1.tgz#c2db8714c181cc0700216c1a2e3cf55719c58006" integrity sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ== +"@typescript-eslint/tsconfig-utils@^8.35.1": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz#62f1d005419985e09d37a040b2f1450e4e805afa" + integrity sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q== + "@typescript-eslint/type-utils@8.35.1": version "8.35.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.35.1.tgz#4f9a07d6efa0e617a67e1890d28117e68ce154bd" @@ -4392,23 +3966,28 @@ debug "^4.3.4" ts-api-utils "^2.1.0" -"@typescript-eslint/types@6.18.0": - version "6.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.18.0.tgz#ffce610a1540c17cf7d8ecf2bb34b8b0e2e77101" - integrity sha512-/RFVIccwkwSdW/1zeMx3hADShWbgBxBnV/qSrex6607isYjj05t36P6LyONgqdUrNLl5TYU8NIKdHUYpFvExkA== +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== -"@typescript-eslint/types@8.35.1", "@typescript-eslint/types@^8.35.1": +"@typescript-eslint/types@8.35.1": version "8.35.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.35.1.tgz#4344dcf934495bbf25a9f83a06dd9fe2acf15780" integrity sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ== -"@typescript-eslint/typescript-estree@6.18.0": - version "6.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.18.0.tgz#1c357c3ca435c3cfa2af6b9daf45ca0bc2bb059a" - integrity sha512-klNvl+Ql4NsBNGB4W9TZ2Od03lm7aGvTbs0wYaFYsplVPhr+oeXjlPZCDI4U9jgJIDK38W1FKhacCFzCC+nbIg== +"@typescript-eslint/types@^8.35.1": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.55.0.tgz#8449c5a7adac61184cac92dbf6315733569708c2" + integrity sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w== + +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== dependencies: - "@typescript-eslint/types" "6.18.0" - "@typescript-eslint/visitor-keys" "6.18.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -4442,12 +4021,12 @@ "@typescript-eslint/types" "8.35.1" "@typescript-eslint/typescript-estree" "8.35.1" -"@typescript-eslint/visitor-keys@6.18.0": - version "6.18.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.18.0.tgz#3c8733737786fa6c78a347b4fa306ae7155b560f" - integrity sha512-1wetAlSZpewRDb2h9p/Q8kRjdGuqdTAQbkJIOUMLug2LBLG+QOjiWoSj6/3B/hA9/tVTFFdtiKvAYoYnSRW/RA== +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== dependencies: - "@typescript-eslint/types" "6.18.0" + "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" "@typescript-eslint/visitor-keys@8.35.1": @@ -4463,6 +4042,103 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== +"@unrs/resolver-binding-android-arm-eabi@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz#9f5b04503088e6a354295e8ea8fe3cb99e43af81" + integrity sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw== + +"@unrs/resolver-binding-android-arm64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz#7414885431bd7178b989aedc4d25cccb3865bc9f" + integrity sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g== + +"@unrs/resolver-binding-darwin-arm64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz#b4a8556f42171fb9c9f7bac8235045e82aa0cbdf" + integrity sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g== + +"@unrs/resolver-binding-darwin-x64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz#fd4d81257b13f4d1a083890a6a17c00de571f0dc" + integrity sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ== + +"@unrs/resolver-binding-freebsd-x64@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz#d2513084d0f37c407757e22f32bd924a78cfd99b" + integrity sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw== + +"@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz#844d2605d057488d77fab09705f2866b86164e0a" + integrity sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw== + +"@unrs/resolver-binding-linux-arm-musleabihf@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz#204892995cefb6bd1d017d52d097193bc61ddad3" + integrity sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw== + +"@unrs/resolver-binding-linux-arm64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz#023eb0c3aac46066a10be7a3f362e7b34f3bdf9d" + integrity sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ== + +"@unrs/resolver-binding-linux-arm64-musl@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz#9e6f9abb06424e3140a60ac996139786f5d99be0" + integrity sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w== + +"@unrs/resolver-binding-linux-ppc64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz#b111417f17c9d1b02efbec8e08398f0c5527bb44" + integrity sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA== + +"@unrs/resolver-binding-linux-riscv64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz#92ffbf02748af3e99873945c9a8a5ead01d508a9" + integrity sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ== + +"@unrs/resolver-binding-linux-riscv64-musl@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz#0bec6f1258fc390e6b305e9ff44256cb207de165" + integrity sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew== + +"@unrs/resolver-binding-linux-s390x-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz#577843a084c5952f5906770633ccfb89dac9bc94" + integrity sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg== + +"@unrs/resolver-binding-linux-x64-gnu@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz#36fb318eebdd690f6da32ac5e0499a76fa881935" + integrity sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w== + +"@unrs/resolver-binding-linux-x64-musl@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz#bfb9af75f783f98f6a22c4244214efe4df1853d6" + integrity sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA== + +"@unrs/resolver-binding-wasm32-wasi@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz#752c359dd875684b27429500d88226d7cc72f71d" + integrity sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ== + dependencies: + "@napi-rs/wasm-runtime" "^0.2.11" + +"@unrs/resolver-binding-win32-arm64-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz#ce5735e600e4c2fbb409cd051b3b7da4a399af35" + integrity sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw== + +"@unrs/resolver-binding-win32-ia32-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz#72fc57bc7c64ec5c3de0d64ee0d1810317bc60a6" + integrity sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ== + +"@unrs/resolver-binding-win32-x64-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" + integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== + "@vitest/coverage-v8@4.0.17": version "4.0.17" resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-4.0.17.tgz#3bb100e9a6766de282049fba28e21a010a73509a" @@ -4538,9 +4214,9 @@ tinyrainbow "^3.0.3" "@xmldom/xmldom@^0.8.8": - version "0.8.10" - resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz#a1337ca426aa61cef9fe15b5b28e340a72f6fa99" - integrity sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw== + version "0.8.11" + resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz#b79de2d67389734c57c52595f7a7305e30c2d608" + integrity sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw== "@xterm/addon-fit@0.11.0": version "0.11.0" @@ -4558,9 +4234,9 @@ integrity sha512-sGdGi8o60vrBsYSQDBy+nk+my+XO66wIqH6ZabVgKyP+SgxoRoytxis4BMbOUQqAFW1e8Fzm7i9QQEIjUE5KNA== "@xterm/xterm@^5.6.0-beta.119": - version "5.6.0-beta.129" - resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.129.tgz#b8d8133396b4ce763e8bc27d312957eca210c1cb" - integrity sha512-KXbEh9a/K83G0Kk77Ol6hisa39oigaqwi3ZrQY5FK5X7mqaNvmMstS/yDmYUG6URz0PMXjEuZ1Y5DWl0JuIxlQ== + version "5.6.0-beta.143" + resolved "https://registry.yarnpkg.com/@xterm/xterm/-/xterm-5.6.0-beta.143.tgz#ce455d86ddb14b8cc995bb945c65b27774d71783" + integrity sha512-zOxRKnxlwTAAlprUv9j8MVly4UyKJYQm2QzkRvZGJd9hMnjS3bQS9mRLmt91jwLleSzHdtUMe2jKjtQnFmho3Q== abbrev@^1.0.0: version "1.1.1" @@ -4582,6 +4258,11 @@ acorn@^8.15.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== +adm-zip@^0.5.16: + version "0.5.16" + resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.16.tgz#0b5e4c779f07dedea5805cdccb1147071d94a909" + integrity sha512-TGw5yVi4saajsSEgz25grObGHEUaDrniwvA2qwSC060KfqGPdglhvPMA2lPIoxs3PQIItj2iag35fONcQqgUaQ== + agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -4589,22 +4270,15 @@ agent-base@6, agent-base@^6.0.2: dependencies: debug "4" -agent-base@^7.0.2, agent-base@^7.1.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" - integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== - dependencies: - debug "^4.3.4" - -agent-base@^7.1.2: +agent-base@^7.1.0, agent-base@^7.1.2: version "7.1.4" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== agentkeepalive@^4.2.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + version "4.6.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" + integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== dependencies: humanize-ms "^1.2.1" @@ -4637,16 +4311,9 @@ ansi-regex@^5.0.1: integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" + version "6.2.2" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" + integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" @@ -4722,98 +4389,113 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-hidden@^1.1.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" - integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== +aria-hidden@^1.2.4: + version "1.2.6" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.6.tgz#73051c9b088114c795b1ea414e9c0fff874ffc1a" + integrity sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA== dependencies: tslib "^2.0.0" -aria-query@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" +aria-query@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" + integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== +array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz#384d12a37295aec3769ab022ad323a18a51ccf8b" + integrity sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw== dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" + call-bound "^1.0.3" + is-array-buffer "^3.0.5" -array-includes@^3.1.6, array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== +array-includes@^3.1.6, array-includes@^3.1.8, array-includes@^3.1.9: + version "3.1.9" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.9.tgz#1f0ccaa08e90cdbc3eb433210f903ad0f17c3f3a" + integrity sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.4" + define-properties "^1.2.1" + es-abstract "^1.24.0" + es-object-atoms "^1.1.1" + get-intrinsic "^1.3.0" + is-string "^1.1.1" + math-intrinsics "^1.1.0" array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.findlastindex@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== +array.prototype.findlast@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904" + integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" + 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" -array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== +array.prototype.findlastindex@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz#cfa1065c81dcb64e34557c9b81d012f6a421c564" + integrity sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" + call-bind "^1.0.8" + call-bound "^1.0.4" + define-properties "^1.2.1" + es-abstract "^1.23.9" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + es-shim-unscopables "^1.1.0" -array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== +array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5" + integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" + call-bind "^1.0.8" + define-properties "^1.2.1" + es-abstract "^1.23.5" + es-shim-unscopables "^1.0.2" -array.prototype.tosorted@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz#620eff7442503d66c799d95503f82b475745cefd" - integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== +array.prototype.flatmap@^1.3.2, array.prototype.flatmap@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz#712cc792ae70370ae40586264629e33aab5dd38b" + integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" + call-bind "^1.0.8" + define-properties "^1.2.1" + es-abstract "^1.23.5" + es-shim-unscopables "^1.0.2" -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== +array.prototype.tosorted@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz#fe954678ff53034e717ea3352a03f0b0b86f7ffc" + integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-shim-unscopables "^1.0.2" + +arraybuffer.prototype.slice@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz#9d760d84dbdd06d0cbf92c8849615a1a7ab3183c" + integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ== dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.8" + define-properties "^1.2.1" + es-abstract "^1.23.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + is-array-buffer "^3.0.4" assert-plus@^1.0.0: version "1.0.0" @@ -4836,13 +4518,13 @@ ast-types-flow@^0.0.8: integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== ast-v8-to-istanbul@^0.3.10: - version "0.3.10" - resolved "https://registry.yarnpkg.com/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz#ceff0094c8c64b9e04393c2377fd61857429ec04" - integrity sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ== + version "0.3.11" + resolved "https://registry.yarnpkg.com/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.11.tgz#725b1f5e2ffdc8d71620cb5e78d6dc976d65e97a" + integrity sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw== dependencies: "@jridgewell/trace-mapping" "^0.3.31" estree-walker "^3.0.3" - js-tokens "^9.0.1" + js-tokens "^10.0.0" astral-regex@^2.0.0: version "2.0.0" @@ -4854,22 +4536,20 @@ async-exit-hook@^2.0.1: resolved "https://registry.yarnpkg.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz#8bd8b024b0ec9b1c01cccb9af9db29bd717dfaf3" integrity sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw== +async-function@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b" + integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA== + async@^0.2.9: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" integrity sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ== -async@^3.2.3: - version "3.2.5" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" - integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== - -asynciterator.prototype@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" - integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== - dependencies: - has-symbols "^1.0.3" +async@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== asynckit@^0.4.0: version "0.4.0" @@ -4882,26 +4562,27 @@ at-least-node@^1.0.0: integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== autoprefixer@^10.0.1: - version "10.4.16" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.16.tgz#fad1411024d8670880bdece3970aa72e3572feb8" - integrity sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ== - dependencies: - browserslist "^4.21.10" - caniuse-lite "^1.0.30001538" - fraction.js "^4.3.6" - normalize-range "^0.1.2" - picocolors "^1.0.0" + version "10.4.24" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.24.tgz#2c29595f3abd820a79976a609d0bf40eecf212fb" + integrity sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw== + dependencies: + browserslist "^4.28.1" + caniuse-lite "^1.0.30001766" + fraction.js "^5.3.4" + picocolors "^1.1.1" postcss-value-parser "^4.2.0" -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" -axe-core@=4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" - integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== +axe-core@^4.10.0: + version "4.11.1" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.11.1.tgz#052ff9b2cbf543f5595028b583e4763b40c78ea7" + integrity sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A== axios@1.12.0: version "1.12.0" @@ -4912,24 +4593,21 @@ axios@1.12.0: form-data "^4.0.4" proxy-from-env "^1.1.0" -axobject-query@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" - integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== - dependencies: - dequal "^2.0.3" +axobject-query@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee" + integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== -babel-plugin-jsx-dom-expressions@^0.39.8: - version "0.39.8" - resolved "https://registry.yarnpkg.com/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.39.8.tgz#e4baa0e6af6b53ecb7d34e9ca7f5ddfc8eafd63d" - integrity sha512-/MVOIIjonylDXnrWmG23ZX82m9mtKATsVHB7zYlPfDR9Vdd/NBE48if+wv27bSkBtyO7EPMUlcUc4J63QwuACQ== +babel-plugin-jsx-dom-expressions@^0.40.3: + version "0.40.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.40.3.tgz#b8d9c005296a907e3cf8074b84d88193b4ab9009" + integrity sha512-5HOwwt0BYiv/zxl7j8Pf2bGL6rDXfV6nUhLs8ygBX+EFJXzBPHM/euj9j/6deMZ6wa52Wb2PBaAV5U/jKwIY1w== dependencies: "@babel/helper-module-imports" "7.18.6" "@babel/plugin-syntax-jsx" "^7.18.6" "@babel/types" "^7.20.7" html-entities "2.3.3" parse5 "^7.1.2" - validate-html-nesting "^1.2.1" babel-plugin-macros@^3.1.0: version "3.1.0" @@ -4941,11 +4619,11 @@ babel-plugin-macros@^3.1.0: resolve "^1.19.0" babel-preset-solid@^1.8.4: - version "1.9.6" - resolved "https://registry.yarnpkg.com/babel-preset-solid/-/babel-preset-solid-1.9.6.tgz#3dd54db9bfc7a85dc1d31c1e88b49fefa0dce8fc" - integrity sha512-HXTK9f93QxoH8dYn1M2mJdOlWgMsR88Lg/ul6QCZGkNTktjTE5HAf93YxQumHoCudLEtZrU1cFCMFOVho6GqFg== + version "1.9.10" + resolved "https://registry.yarnpkg.com/babel-preset-solid/-/babel-preset-solid-1.9.10.tgz#23f7fbc3331547b10be5b939e3e368a009be8e31" + integrity sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ== dependencies: - babel-plugin-jsx-dom-expressions "^0.39.8" + babel-plugin-jsx-dom-expressions "^0.40.3" babylonjs-addons@8.41.0: version "8.41.0" @@ -4955,28 +4633,26 @@ babylonjs-addons@8.41.0: babylonjs "^8.41.0" babylonjs-editor-cli@latest: - version "5.0.0" - resolved "https://registry.yarnpkg.com/babylonjs-editor-cli/-/babylonjs-editor-cli-5.0.0.tgz#860ec093d8a4eea71b405adf8a984320d2f893de" - integrity sha512-9fNSNr6oXg11Cgj24+2uDc9XtmkelaBx13rMWIWh8mon6gnD9OiHfO+XgQWasVwKGs1wni0UlWO5edjmN0MDzw== + version "5.3.0" + resolved "https://registry.yarnpkg.com/babylonjs-editor-cli/-/babylonjs-editor-cli-5.3.0.tgz#ec7519596838b9146ba05d1ad7a97dbcc81ebe3d" + integrity sha512-mA0Jia8mboAgV33jCzDS13DBzDOyLhCe/r9vun681F+gP2wpgud2cB5o/D8HVTStYSAeW+0n+NFBxtJ9kfFWww== dependencies: + "@aws-sdk/client-s3" "3.975.0" chalk "5.6.2" cli-spinners "3.4.0" commander "14.0.2" dotenv "17.2.3" fs-extra "11.2.0" glob "11.1.0" + md5 "2.3.0" ora "9.1.0" pngjs "7.0.0" sharp "0.34.3" babylonjs-editor-tools@latest: - version "5.0.0" - resolved "https://registry.yarnpkg.com/babylonjs-editor-tools/-/babylonjs-editor-tools-5.0.0.tgz#d2e1919cc5d4defbcbcf60259a1eb73a589cf643" - integrity sha512-AREjL0WjtjyOvud0EMG/II3zH73KlSif/u0HV965tPWmUZHrxr+g/4iX6eU0mIYlIjOuepfRAopaF04IYJOaHA== - -"babylonjs-editor-tools@link:../../../Library/Caches/Yarn/v6/npm-babylonjs-editor-5.2.4-3cce3a704dc0c4572a85041a993264060376230a-integrity/node_modules/tools": - version "0.0.0" - uid "" + version "5.3.0" + resolved "https://registry.yarnpkg.com/babylonjs-editor-tools/-/babylonjs-editor-tools-5.3.0.tgz#76ff1b1008f2c3c4970423484a45c3e6fe7a0592" + integrity sha512-eMSVSDp73FONJzCU4rVjNpJ30XCZJz/473XDaQJ69vvQvZxozRn8lZVaqnYqVUsjzUTTE/TmgxxxaSUk3T23rA== "babylonjs-editor-tools@link:tools": version "5.3.0" @@ -5023,7 +4699,7 @@ babylonjs-editor@latest: axios "1.12.0" babylonjs "8.41.0" babylonjs-addons "8.41.0" - babylonjs-editor-tools "link:../../../Library/Caches/Yarn/v6/npm-babylonjs-editor-5.2.4-3cce3a704dc0c4572a85041a993264060376230a-integrity/node_modules/tools" + babylonjs-editor-tools "link:C:/Users/soull/AppData/Local/Yarn/Cache/v6/npm-babylonjs-editor-5.2.4-3cce3a704dc0c4572a85041a993264060376230a-integrity/node_modules/tools" babylonjs-gui "8.41.0" babylonjs-gui-editor "8.41.0" babylonjs-loaders "8.41.0" @@ -5069,9 +4745,9 @@ babylonjs-editor@latest: webm-muxer "^5.0.2" babylonjs-gltf2interface@^8.41.0: - version "8.41.1" - resolved "https://registry.yarnpkg.com/babylonjs-gltf2interface/-/babylonjs-gltf2interface-8.41.1.tgz#e8019573cc1510878e06444f7ed86dd7d8f19d27" - integrity sha512-Bo2HTs75H8XNrNrWHNrGRqL2c/58K1qVhrzfTSWyuKtDU9uIZtmYsIc6K0gQeZ62aPJSjll3NRws3eaUDDIXyQ== + version "8.51.1" + resolved "https://registry.yarnpkg.com/babylonjs-gltf2interface/-/babylonjs-gltf2interface-8.51.1.tgz#3fae74357e182892edbc5d7669bfbfbcbf29fc04" + integrity sha512-ScN7NfFn88YuAaHD46QoK/MbTaYpr7A0JvJRK4X9mWrAqjutTnreGANDvtRgvGu/Qf5aV0XyeRXrNfnileZTKQ== babylonjs-gui-editor@8.41.0: version "8.41.0" @@ -5141,15 +4817,22 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +balanced-match@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.2.tgz#241591ea634702bef9c482696f2469406e16d233" + integrity sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg== + dependencies: + jackspeak "^4.2.3" + base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -baseline-browser-mapping@^2.8.3: - version "2.9.11" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz#53724708c8db5f97206517ecfe362dbe5181deea" - integrity sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ== +baseline-browser-mapping@^2.8.3, baseline-browser-mapping@^2.9.0: + version "2.9.19" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" + integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== big.js@^5.2.2: version "5.2.2" @@ -5157,9 +4840,9 @@ big.js@^5.2.2: integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== bl@^1.0.0: version "1.2.3" @@ -5184,51 +4867,49 @@ boolean@^3.0.1: integrity sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw== bowser@^2.11.0: - version "2.13.1" - resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.13.1.tgz#5a4c652de1d002f847dd011819f5fc729f308a7e" - integrity sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw== + version "2.14.1" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.14.1.tgz#4ea39bf31e305184522d7ad7bfd91389e4f0cb79" + integrity sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg== brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + version "2.0.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" + integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== dependencies: balanced-match "^1.0.0" -braces@3.0.3, braces@^3.0.2, braces@^3.0.3, braces@~3.0.2: +brace-expansion@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.2.tgz#b6c16d0791087af6c2bc463f52a8142046c06b6f" + integrity sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw== + dependencies: + balanced-match "^4.0.2" + +braces@3.0.3, braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" -browserslist@^4.21.10: - version "4.22.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" - integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== - dependencies: - caniuse-lite "^1.0.30001565" - electron-to-chromium "^1.4.601" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" - -browserslist@^4.24.0: - version "4.24.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b" - integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A== +browserslist@^4.24.0, browserslist@^4.28.1: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== dependencies: - caniuse-lite "^1.0.30001688" - electron-to-chromium "^1.5.73" - node-releases "^2.0.19" - update-browserslist-db "^1.1.1" + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" buffer-alloc-unsafe@^1.1.0: version "1.1.0" @@ -5274,6 +4955,14 @@ builder-util-runtime@9.3.1: debug "^4.3.4" sax "^1.2.4" +builder-util-runtime@9.5.1: + version "9.5.1" + resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-9.5.1.tgz#74125fb374d1ecbf472ae1787485485ff7619702" + integrity sha512-qt41tMfgHTllhResqM5DcnHyDIWNgzHvuY2jDcYP9iaGpkWxTUzV6GQjDeLnlR1/DtdlcsWQbA7sByMpmJFTLQ== + dependencies: + debug "^4.3.4" + sax "^1.2.4" + builder-util@26.0.11: version "26.0.11" resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-26.0.11.tgz#ad85b92c93f2b976b973e1d87337e0c6813fcb8f" @@ -5357,7 +5046,7 @@ cacheable-request@^7.0.2: normalize-url "^6.0.1" responselike "^2.0.0" -call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: +call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== @@ -5365,14 +5054,23 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== +call-bind@^1.0.7, call-bind@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" + integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== dependencies: - function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" + call-bind-apply-helpers "^1.0.0" + es-define-property "^1.0.0" + get-intrinsic "^1.2.4" + set-function-length "^1.2.2" + +call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" callsites@^3.0.0: version "3.1.0" @@ -5397,10 +5095,10 @@ camelize@^1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== -caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001565, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001688: - version "1.0.30001761" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz" - integrity sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g== +caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001759, caniuse-lite@^1.0.30001766: + version "1.0.30001769" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" + integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== capital-case@^1.0.4: version "1.0.4" @@ -5417,25 +5115,16 @@ ccount@^2.0.0: integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== chai@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/chai/-/chai-6.2.1.tgz#d1e64bc42433fbee6175ad5346799682060b5b6a" - integrity sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg== + version "6.2.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-6.2.2.tgz#ae41b52c9aca87734505362717f3255facda360e" + integrity sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg== chalk@5.6.2, chalk@^5.6.2: version "5.6.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -5477,9 +5166,9 @@ charenc@0.0.2: integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== chokidar@^3.5.0, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -5518,14 +5207,7 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -class-variance-authority@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz#1c3134d634d80271b1837452b06d821915954522" - integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A== - dependencies: - clsx "2.0.0" - -class-variance-authority@^0.7.1: +class-variance-authority@^0.7.0, class-variance-authority@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz#4008a798a0e4553a781a57ac5177c9fb5d043787" integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg== @@ -5600,35 +5282,20 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== -clsx@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" - integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== - -clsx@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb" - integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== - -clsx@^2.1.1: +clsx@^2.1.0, clsx@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== cmdk@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cmdk/-/cmdk-1.0.0.tgz#0a095fdafca3dfabed82d1db78a6262fb163ded9" - integrity sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q== - dependencies: - "@radix-ui/react-dialog" "1.0.5" - "@radix-ui/react-primitive" "1.0.3" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/cmdk/-/cmdk-1.1.1.tgz#b8524272699ccaa37aaf07f36850b376bf3d58e5" + integrity sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg== dependencies: - color-name "1.1.3" + "@radix-ui/react-compose-refs" "^1.1.1" + "@radix-ui/react-dialog" "^1.1.6" + "@radix-ui/react-id" "^1.1.0" + "@radix-ui/react-primitive" "^2.0.2" color-convert@^2.0.1: version "2.0.1" @@ -5637,11 +5304,6 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" @@ -5780,16 +5442,7 @@ cross-env@7.0.3: dependencies: cross-spawn "^7.0.1" -cross-spawn@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -cross-spawn@^7.0.6: +cross-spawn@^7.0.1, cross-spawn@^7.0.6: version "7.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== @@ -5822,21 +5475,43 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - -csstype@^3.0.2, csstype@^3.1.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" - integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +csstype@3.2.3, csstype@^3.0.2, csstype@^3.1.0, csstype@^3.2.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== damerau-levenshtein@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +data-view-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz#211a03ba95ecaf7798a8c7198d79536211f88570" + integrity sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ== + dependencies: + call-bound "^1.0.3" + es-errors "^1.3.0" + is-data-view "^1.0.2" + +data-view-byte-length@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz#9e80f7ca52453ce3e93d25a35318767ea7704735" + integrity sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ== + dependencies: + call-bound "^1.0.3" + es-errors "^1.3.0" + is-data-view "^1.0.2" + +data-view-byte-offset@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz#068307f9b71ab76dbbe10291389e020856606191" + integrity sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + is-data-view "^1.0.1" + date-time@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/date-time/-/date-time-3.1.0.tgz#0d1e934d170579f481ed8df1e2b8ff70ee845e1e" @@ -5844,12 +5519,12 @@ date-time@^3.1.0: dependencies: time-zone "^1.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.4.0: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: - ms "2.1.2" + ms "^2.1.3" debug@^3.2.7: version "3.2.7" @@ -5935,16 +5610,16 @@ defer-to-connect@^2.0.0: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== dependencies: - get-intrinsic "^1.2.1" + es-define-property "^1.0.0" + es-errors "^1.3.0" gopd "^1.0.1" - has-property-descriptors "^1.0.0" -define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.1.3, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -5958,22 +5633,12 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -dequal@^2.0.0, dequal@^2.0.3: +dequal@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== -detect-libc@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== - -detect-libc@^2.0.3, detect-libc@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.4.tgz#f04715b8ba815e53b4d8109655b6508a6865a7e8" - integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== - -detect-libc@^2.1.2: +detect-libc@^2.0.1, detect-libc@^2.0.3, detect-libc@^2.0.4, detect-libc@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== @@ -6072,23 +5737,23 @@ dot-case@^3.0.4: tslib "^2.0.3" dotenv-expand@^11.0.6: - version "11.0.6" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-11.0.6.tgz#f2c840fd924d7c77a94eff98f153331d876882d3" - integrity sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g== + version "11.0.7" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-11.0.7.tgz#af695aea007d6fdc84c86cd8d0ad7beb40a0bd08" + integrity sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA== dependencies: - dotenv "^16.4.4" + dotenv "^16.4.5" dotenv@17.2.3: version "17.2.3" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-17.2.3.tgz#ad995d6997f639b11065f419a22fabf567cdb9a2" integrity sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w== -dotenv@^16.4.4, dotenv@^16.4.5: - version "16.4.5" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" - integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +dotenv@^16.4.5: + version "16.6.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.6.1.tgz#773f0e69527a8315c7285d5ee73c4459d20a8020" + integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow== -dunder-proto@1.0.1, dunder-proto@^1.0.1: +dunder-proto@1.0.1, dunder-proto@^1.0.0, dunder-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== @@ -6108,9 +5773,9 @@ eastasianwidth@^0.2.0: integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ejs@^3.1.8: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" @@ -6160,17 +5825,12 @@ electron-reloader@1.2.3: electron-is-dev "^1.2.0" find-up "^5.0.0" -electron-to-chromium@^1.4.601: - version "1.4.623" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz#0f7400114ac3425500e9244d2b0e9c3107c331cb" - integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== +electron-to-chromium@^1.5.263: + version "1.5.286" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" + integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== -electron-to-chromium@^1.5.73: - version "1.5.128" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.128.tgz#8ea537b369c32527b3cc47df7973bffe5d3c2980" - integrity sha512-bo1A4HH/NS522Ws0QNFIzyPcyUUNV/yyy70Ho1xqfGYzPUme2F/xr4tlEOuM6/A538U1vDA7a4XfCd1CKRegKQ== - -electron-updater@6.6.2, electron-updater@^6.6.2: +electron-updater@6.6.2: version "6.6.2" resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.6.2.tgz#3e65e044f1a99b00d61e200e24de8e709c69ce99" integrity sha512-Cr4GDOkbAUqRHP5/oeOmH/L2Bn6+FQPxVLZtPbcmKZC63a1F3uu5EefYOssgZXG3u/zBlubbJ5PJdITdMVggbw== @@ -6184,6 +5844,20 @@ electron-updater@6.6.2, electron-updater@^6.6.2: semver "^7.6.3" tiny-typed-emitter "^2.1.0" +electron-updater@^6.6.2: + version "6.7.3" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-6.7.3.tgz#c710b00cbce72f5fd2cc88f8c5f7535cae3097a3" + integrity sha512-EgkT8Z9noqXKbwc3u5FkJA+r48jwZ5DTUiOkJMOTEEH//n5Am6wfQGz7nvSFEA2oIAMv9jRzn5JKTyWeSKOPgg== + dependencies: + builder-util-runtime "9.5.1" + fs-extra "^10.1.0" + js-yaml "^4.1.0" + lazy-val "^1.0.5" + lodash.escaperegexp "^4.1.2" + lodash.isequal "^4.5.0" + semver "~7.7.3" + tiny-typed-emitter "^2.1.0" + electron@39.2.7: version "39.2.7" resolved "https://registry.yarnpkg.com/electron/-/electron-39.2.7.tgz#1cf2371304994fe26c564764bd50878fe405fb4b" @@ -6234,27 +5908,19 @@ encoding@^0.1.13: iconv-lite "^0.6.2" end-of-stream@^1.0.0, end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + version "1.4.5" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" + integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== dependencies: once "^1.4.0" -enhanced-resolve@^5.12.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - enhanced-resolve@^5.18.3: - version "5.18.4" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz#c22d33055f3952035ce6a144ce092447c525f828" - integrity sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q== + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== dependencies: graceful-fs "^4.2.4" - tapable "^2.2.0" + tapable "^2.3.0" entities@^6.0.0: version "6.0.1" @@ -6272,58 +5938,73 @@ err-code@^2.0.2: integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + version "1.3.4" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414" + integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ== dependencies: is-arrayish "^0.2.1" -es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" +es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0, es-abstract@^1.24.1: + version "1.24.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.1.tgz#f0c131ed5ea1bb2411134a8dd94def09c46c7899" + integrity sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw== + dependencies: + array-buffer-byte-length "^1.0.2" + arraybuffer.prototype.slice "^1.0.4" + available-typed-arrays "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.4" + data-view-buffer "^1.0.2" + data-view-byte-length "^1.0.2" + data-view-byte-offset "^1.0.1" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + es-set-tostringtag "^2.1.0" + es-to-primitive "^1.3.0" + function.prototype.name "^1.1.8" + get-intrinsic "^1.3.0" + get-proto "^1.0.1" + get-symbol-description "^1.1.0" + globalthis "^1.0.4" + gopd "^1.2.0" + has-property-descriptors "^1.0.2" + has-proto "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + internal-slot "^1.1.0" + is-array-buffer "^3.0.5" is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.12" - is-weakref "^1.0.2" - object-inspect "^1.13.1" + is-data-view "^1.0.2" + is-negative-zero "^2.0.3" + is-regex "^1.2.1" + is-set "^2.0.3" + is-shared-array-buffer "^1.0.4" + is-string "^1.1.1" + is-typed-array "^1.1.15" + is-weakref "^1.1.1" + math-intrinsics "^1.1.0" + object-inspect "^1.13.4" object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" - -es-define-property@^1.0.1: + object.assign "^4.1.7" + own-keys "^1.0.1" + regexp.prototype.flags "^1.5.4" + safe-array-concat "^1.1.3" + safe-push-apply "^1.0.0" + safe-regex-test "^1.1.0" + set-proto "^1.0.0" + stop-iteration-iterator "^1.1.0" + string.prototype.trim "^1.2.10" + string.prototype.trimend "^1.0.9" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.3" + typed-array-byte-length "^1.0.3" + typed-array-byte-offset "^1.0.4" + typed-array-length "^1.0.7" + unbox-primitive "^1.1.0" + which-typed-array "^1.1.19" + +es-define-property@^1.0.0, es-define-property@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== @@ -6333,25 +6014,27 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" - integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== +es-iterator-helpers@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz#d979a9f686e2b0b72f88dbead7229924544720bc" + integrity sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w== dependencies: - asynciterator.prototype "^1.0.0" - call-bind "^1.0.2" + call-bind "^1.0.8" + call-bound "^1.0.4" define-properties "^1.2.1" - es-abstract "^1.22.1" - es-set-tostringtag "^2.0.1" - function-bind "^1.1.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - iterator.prototype "^1.1.2" - safe-array-concat "^1.0.1" + es-abstract "^1.24.1" + es-errors "^1.3.0" + es-set-tostringtag "^2.1.0" + function-bind "^1.1.2" + get-intrinsic "^1.3.0" + globalthis "^1.0.4" + gopd "^1.2.0" + has-property-descriptors "^1.0.2" + has-proto "^1.2.0" + has-symbols "^1.1.0" + internal-slot "^1.1.0" + iterator.prototype "^1.1.5" + safe-array-concat "^1.1.3" es-module-lexer@^1.7.0: version "1.7.0" @@ -6365,15 +6048,6 @@ es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: dependencies: es-errors "^1.3.0" -es-set-tostringtag@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" - integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== - dependencies: - get-intrinsic "^1.2.2" - has-tostringtag "^1.0.0" - hasown "^2.0.0" - es-set-tostringtag@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" @@ -6384,21 +6058,21 @@ es-set-tostringtag@^2.1.0: has-tostringtag "^1.0.2" hasown "^2.0.2" -es-shim-unscopables@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" - integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== +es-shim-unscopables@^1.0.2, es-shim-unscopables@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz#438df35520dac5d105f3943d927549ea3b00f4b5" + integrity sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw== dependencies: - hasown "^2.0.0" + hasown "^2.0.2" -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== +es-to-primitive@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz#96c89c82cc49fd8794a24835ba3e1ff87f214e18" + integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g== dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" + is-callable "^1.2.7" + is-date-object "^1.0.5" + is-symbol "^1.0.4" es6-error@^4.1.1: version "4.1.1" @@ -6436,7 +6110,7 @@ esbuild@0.25.5: "@esbuild/win32-ia32" "0.25.5" "@esbuild/win32-x64" "0.25.5" -esbuild@0.27.2, esbuild@^0.27.0: +esbuild@0.27.2: version "0.27.2" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.27.2.tgz#d83ed2154d5813a5367376bb2292a9296fc83717" integrity sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw== @@ -6468,49 +6142,44 @@ esbuild@0.27.2, esbuild@^0.27.0: "@esbuild/win32-ia32" "0.27.2" "@esbuild/win32-x64" "0.27.2" -esbuild@^0.25.0: - version "0.25.8" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.8.tgz#482d42198b427c9c2f3a81b63d7663aecb1dda07" - integrity sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q== +esbuild@^0.27.0: + version "0.27.3" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.27.3.tgz#5859ca8e70a3af956b26895ce4954d7e73bd27a8" + integrity sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg== optionalDependencies: - "@esbuild/aix-ppc64" "0.25.8" - "@esbuild/android-arm" "0.25.8" - "@esbuild/android-arm64" "0.25.8" - "@esbuild/android-x64" "0.25.8" - "@esbuild/darwin-arm64" "0.25.8" - "@esbuild/darwin-x64" "0.25.8" - "@esbuild/freebsd-arm64" "0.25.8" - "@esbuild/freebsd-x64" "0.25.8" - "@esbuild/linux-arm" "0.25.8" - "@esbuild/linux-arm64" "0.25.8" - "@esbuild/linux-ia32" "0.25.8" - "@esbuild/linux-loong64" "0.25.8" - "@esbuild/linux-mips64el" "0.25.8" - "@esbuild/linux-ppc64" "0.25.8" - "@esbuild/linux-riscv64" "0.25.8" - "@esbuild/linux-s390x" "0.25.8" - "@esbuild/linux-x64" "0.25.8" - "@esbuild/netbsd-arm64" "0.25.8" - "@esbuild/netbsd-x64" "0.25.8" - "@esbuild/openbsd-arm64" "0.25.8" - "@esbuild/openbsd-x64" "0.25.8" - "@esbuild/openharmony-arm64" "0.25.8" - "@esbuild/sunos-x64" "0.25.8" - "@esbuild/win32-arm64" "0.25.8" - "@esbuild/win32-ia32" "0.25.8" - "@esbuild/win32-x64" "0.25.8" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escalade@^3.2.0: + "@esbuild/aix-ppc64" "0.27.3" + "@esbuild/android-arm" "0.27.3" + "@esbuild/android-arm64" "0.27.3" + "@esbuild/android-x64" "0.27.3" + "@esbuild/darwin-arm64" "0.27.3" + "@esbuild/darwin-x64" "0.27.3" + "@esbuild/freebsd-arm64" "0.27.3" + "@esbuild/freebsd-x64" "0.27.3" + "@esbuild/linux-arm" "0.27.3" + "@esbuild/linux-arm64" "0.27.3" + "@esbuild/linux-ia32" "0.27.3" + "@esbuild/linux-loong64" "0.27.3" + "@esbuild/linux-mips64el" "0.27.3" + "@esbuild/linux-ppc64" "0.27.3" + "@esbuild/linux-riscv64" "0.27.3" + "@esbuild/linux-s390x" "0.27.3" + "@esbuild/linux-x64" "0.27.3" + "@esbuild/netbsd-arm64" "0.27.3" + "@esbuild/netbsd-x64" "0.27.3" + "@esbuild/openbsd-arm64" "0.27.3" + "@esbuild/openbsd-x64" "0.27.3" + "@esbuild/openharmony-arm64" "0.27.3" + "@esbuild/sunos-x64" "0.27.3" + "@esbuild/win32-arm64" "0.27.3" + "@esbuild/win32-ia32" "0.27.3" + "@esbuild/win32-x64" "0.27.3" + +escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== @@ -6545,96 +6214,99 @@ eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.9: resolve "^1.22.4" eslint-import-resolver-typescript@^3.5.2: - version "3.6.1" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz#7b983680edd3f1c5bce1a5829ae0bc2d57fe9efa" - integrity sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg== - dependencies: - debug "^4.3.4" - enhanced-resolve "^5.12.0" - eslint-module-utils "^2.7.4" - fast-glob "^3.3.1" - get-tsconfig "^4.5.0" - is-core-module "^2.11.0" - is-glob "^4.0.3" - -eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + version "3.10.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz#23dac32efa86a88e2b8232eb244ac499ad636db2" + integrity sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ== + dependencies: + "@nolyfill/is-core-module" "1.0.39" + debug "^4.4.0" + get-tsconfig "^4.10.0" + is-bun-module "^2.0.0" + stable-hash "^0.0.5" + tinyglobby "^0.2.13" + unrs-resolver "^1.6.2" + +eslint-module-utils@^2.12.1: + version "2.12.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz#f76d3220bfb83c057651359295ab5854eaad75ff" + integrity sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw== dependencies: debug "^3.2.7" eslint-plugin-import@^2.28.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" + version "2.32.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz#602b55faa6e4caeaa5e970c198b5c00a37708980" + integrity sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA== + dependencies: + "@rtsao/scc" "^1.1.0" + array-includes "^3.1.9" + array.prototype.findlastindex "^1.2.6" + array.prototype.flat "^1.3.3" + array.prototype.flatmap "^1.3.3" 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" + eslint-module-utils "^2.12.1" + hasown "^2.0.2" + is-core-module "^2.16.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" + object.fromentries "^2.0.8" + object.groupby "^1.0.3" + object.values "^1.2.1" semver "^6.3.1" + string.prototype.trimend "^1.0.9" tsconfig-paths "^3.15.0" eslint-plugin-jsx-a11y@^6.7.1: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" - integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== + version "6.10.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz#d2812bb23bf1ab4665f1718ea442e8372e638483" + integrity sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q== dependencies: - "@babel/runtime" "^7.23.2" - aria-query "^5.3.0" - array-includes "^3.1.7" + aria-query "^5.3.2" + array-includes "^3.1.8" array.prototype.flatmap "^1.3.2" ast-types-flow "^0.0.8" - axe-core "=4.7.0" - axobject-query "^3.2.1" + axe-core "^4.10.0" + axobject-query "^4.1.0" damerau-levenshtein "^1.0.8" emoji-regex "^9.2.2" - es-iterator-helpers "^1.0.15" - hasown "^2.0.0" + hasown "^2.0.2" jsx-ast-utils "^3.3.5" language-tags "^1.0.9" minimatch "^3.1.2" - object.entries "^1.1.7" - object.fromentries "^2.0.7" + object.fromentries "^2.0.8" + safe-regex-test "^1.0.3" + string.prototype.includes "^2.0.1" "eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": - version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + version "5.0.0-canary-7118f5dd7-20230705" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz#4d55c50e186f1a2b0636433d2b0b2f592ddbccfd" + integrity sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw== eslint-plugin-react@^7.33.2: - version "7.33.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" - integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== - dependencies: - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - array.prototype.tosorted "^1.1.1" + version "7.37.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065" + integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA== + dependencies: + array-includes "^3.1.8" + array.prototype.findlast "^1.2.5" + array.prototype.flatmap "^1.3.3" + array.prototype.tosorted "^1.1.4" doctrine "^2.1.0" - es-iterator-helpers "^1.0.12" + es-iterator-helpers "^1.2.1" estraverse "^5.3.0" + hasown "^2.0.2" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - object.hasown "^1.1.2" - object.values "^1.1.6" + object.entries "^1.1.9" + object.fromentries "^2.0.8" + object.values "^1.2.1" prop-types "^15.8.1" - resolve "^2.0.0-next.4" + resolve "^2.0.0-next.5" semver "^6.3.1" - string.prototype.matchall "^4.0.8" + string.prototype.matchall "^4.0.12" + string.prototype.repeat "^1.0.0" eslint-scope@^8.4.0: version "8.4.0" @@ -6644,7 +6316,7 @@ eslint-scope@^8.4.0: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== @@ -6705,9 +6377,9 @@ espree@^10.0.1, espree@^10.4.0: eslint-visitor-keys "^4.2.1" esquery@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" - integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + version "1.7.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d" + integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g== dependencies: estraverse "^5.1.0" @@ -6749,14 +6421,14 @@ event-stream@=3.3.4: through "~2.3.1" expect-type@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.2.2.tgz#c030a329fb61184126c8447585bc75a7ec6fbff3" - integrity sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.3.0.tgz#0d58ed361877a31bbc4dd6cf71bbfef7faf6bd68" + integrity sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA== exponential-backoff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" - integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + version "3.1.3" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6" + integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA== extract-zip@^2.0.1: version "2.0.1" @@ -6779,18 +6451,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" - integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== - 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" - -fast-glob@^3.3.2: +fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.0, fast-glob@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== @@ -6818,10 +6479,17 @@ fast-xml-parser@5.2.5: dependencies: strnum "^2.1.0" +fast-xml-parser@5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.3.4.tgz#06f39aafffdbc97bef0321e626c7ddd06a043ecf" + integrity sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA== + dependencies: + strnum "^2.1.0" + fastq@^1.6.0: - version "1.16.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.16.0.tgz#83b9a9375692db77a822df081edb6a9cf6839320" - integrity sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA== + version "1.20.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.1.tgz#ca750a10dc925bc8b18839fd203e3ef4b3ced675" + integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== dependencies: reusify "^1.0.4" @@ -6909,9 +6577,9 @@ flat-cache@^4.0.0: keyv "^4.5.4" flatted@^3.2.9: - version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" - integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + version "3.3.3" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" + integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== flexlayout-react@0.7.15: version "0.7.15" @@ -6927,16 +6595,16 @@ fluent-ffmpeg@^2.1.3: which "^1.1.1" follow-redirects@^1.15.6: - version "1.15.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" - integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== + version "1.15.11" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340" + integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== +for-each@^0.3.3, for-each@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" + integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== dependencies: - is-callable "^1.1.3" + is-callable "^1.2.7" foreground-child@^3.1.0, foreground-child@^3.3.1: version "3.3.1" @@ -6947,9 +6615,9 @@ foreground-child@^3.1.0, foreground-child@^3.3.1: signal-exit "^4.0.1" form-data@^4.0.0, form-data@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4" - integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow== + version "4.0.5" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.5.tgz#b49e48858045ff4cbf6b03e1805cebcad3679053" + integrity sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" @@ -6957,12 +6625,12 @@ form-data@^4.0.0, form-data@^4.0.4: hasown "^2.0.2" mime-types "^2.1.12" -fraction.js@^4.3.6: - version "4.3.7" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" - integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== +fraction.js@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-5.3.4.tgz#8c0fcc6a9908262df4ed197427bdeef563e0699a" + integrity sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== -framer-motion@12.23.24, framer-motion@^12.23.24: +framer-motion@12.23.24: version "12.23.24" resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-12.23.24.tgz#4895b67e880bd2b1089e61fbaa32ae802fc24b8c" integrity sha512-HMi5HRoRCTou+3fb3h9oTLyJGBxHfW+HnNE25tAXOvVx/IvwMHK0cx7IR4a2ZU6sh3IX1Z+4ts32PcYBOqka8w== @@ -6971,6 +6639,15 @@ framer-motion@12.23.24, framer-motion@^12.23.24: motion-utils "^12.23.6" tslib "^2.4.0" +framer-motion@^12.23.24: + version "12.34.0" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-12.34.0.tgz#0cecdf015cc4cbee55bd53130d043137642a5ced" + integrity sha512-+/H49owhzkzQyxtn7nZeF4kdH++I2FWrESQ184Zbcw5cEqNHYkE5yxWxcTLSj5lNx3NWdbIRy5FHqUvetD8FWg== + dependencies: + motion-dom "^12.34.0" + motion-utils "^12.29.2" + tslib "^2.4.0" + from@~0: version "0.1.7" resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" @@ -6981,7 +6658,7 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@11.2.0, fs-extra@^11.1.1: +fs-extra@11.2.0: version "11.2.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== @@ -6999,6 +6676,15 @@ fs-extra@^10.0.0, fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^11.1.1: + version "11.3.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.3.tgz#a27da23b72524e81ac6c3815cc0179b8c74c59ee" + integrity sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -7042,26 +6728,33 @@ fsevents@~2.3.2, fsevents@~2.3.3: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1, function-bind@^1.1.2: +function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== +function.prototype.name@^1.1.6, function.prototype.name@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz#e68e1df7b259a5c949eeef95cdbde53edffabb78" + integrity sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.8" + call-bound "^1.0.3" + define-properties "^1.2.1" functions-have-names "^1.2.3" + hasown "^2.0.2" + is-callable "^1.2.7" functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +generator-function@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/generator-function/-/generator-function-2.0.1.tgz#0e75dd410d1243687a0ba2e951b94eedb8f737a2" + integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -7077,17 +6770,7 @@ get-east-asian-width@^1.3.0: resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz#9bc4caa131702b4b61729cb7e42735bc550c9ee6" integrity sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== - dependencies: - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-intrinsic@^1.2.6: +get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== @@ -7108,7 +6791,7 @@ get-nonce@^1.0.0: resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== -get-proto@^1.0.1: +get-proto@^1.0.0, get-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== @@ -7131,18 +6814,19 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== +get-symbol-description@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee" + integrity sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bound "^1.0.3" + es-errors "^1.3.0" + get-intrinsic "^1.2.6" -get-tsconfig@^4.5.0: - version "4.7.2" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.2.tgz#0dcd6fb330391d46332f4c6c1bf89a6514c2ddce" - integrity sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A== +get-tsconfig@^4.10.0: + version "4.13.6" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.13.6.tgz#2fbfda558a98a691a798f123afd95915badce876" + integrity sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw== dependencies: resolve-pkg-maps "^1.0.0" @@ -7184,7 +6868,7 @@ glob@7.1.7: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^10.2.2: +glob@^10.2.2, glob@^10.3.12: version "10.5.0" resolved "https://registry.yarnpkg.com/glob/-/glob-10.5.0.tgz#8ec0355919cd3338c28428a23d4f24ecc5fe738c" integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== @@ -7196,18 +6880,6 @@ glob@^10.2.2: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^10.3.10, glob@^10.3.12: - version "10.4.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== - 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" - glob@^7.1.3, glob@^7.1.6: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -7248,12 +6920,13 @@ globals@^14.0.0: resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== -globalthis@^1.0.1, globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== +globalthis@^1.0.1, globalthis@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== dependencies: - define-properties "^1.1.3" + define-properties "^1.2.1" + gopd "^1.0.1" globby@^11.1.0: version "11.1.0" @@ -7267,14 +6940,7 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -gopd@^1.2.0: +gopd@^1.0.1, gopd@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== @@ -7306,50 +6972,35 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== +has-bigints@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.1.0.tgz#28607e965ac967e03cd2a2c70a2636a1edad49fe" + integrity sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg== has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: - get-intrinsic "^1.2.2" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + es-define-property "^1.0.0" -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-proto@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.2.0.tgz#5de5a6eabd95fdffd9818b43055e8065e39fe9d5" + integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ== + dependencies: + dunder-proto "^1.0.0" -has-symbols@^1.1.0: +has-symbols@^1.0.3, has-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - has-tostringtag@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" @@ -7357,13 +7008,6 @@ has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== - dependencies: - function-bind "^1.1.2" - hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" @@ -7432,12 +7076,7 @@ html-void-elements@^3.0.0: resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== -http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http-cache-semantics@^4.1.1: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== @@ -7475,15 +7114,7 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" -https-proxy-agent@^7.0.0: - version "7.0.5" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz#9e8b5013873299e11fab6fd548405da2d6c602b2" - integrity sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw== - dependencies: - agent-base "^7.0.2" - debug "4" - -https-proxy-agent@^7.0.1: +https-proxy-agent@^7.0.0, https-proxy-agent@^7.0.1: version "7.0.6" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== @@ -7519,9 +7150,9 @@ ieee754@^1.1.13: integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" - integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== ignore@^7.0.0: version "7.0.5" @@ -7529,9 +7160,9 @@ ignore@^7.0.0: integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + version "3.3.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" + integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -7564,40 +7195,28 @@ inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -internal-slot@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== - dependencies: - get-intrinsic "^1.2.2" - hasown "^2.0.0" - side-channel "^1.0.4" - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== +internal-slot@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.1.0.tgz#1eac91762947d2f7056bc838d93e13b2e9604961" + integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw== dependencies: - loose-envify "^1.0.0" + es-errors "^1.3.0" + hasown "^2.0.2" + side-channel "^1.1.0" ip-address@^10.0.1: version "10.1.0" resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4" integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== +is-array-buffer@^3.0.4, is-array-buffer@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280" + integrity sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" + call-bind "^1.0.8" + call-bound "^1.0.3" + get-intrinsic "^1.2.6" is-arrayish@^0.2.1: version "0.2.1" @@ -7605,23 +7224,27 @@ is-arrayish@^0.2.1: integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + version "0.3.4" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.4.tgz#1ee5553818511915685d33bb13d31bf854e5059d" + integrity sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA== is-async-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" - integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.1.1.tgz#3e69018c8e04e73b738793d020bfe884b9fd3523" + integrity sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ== dependencies: - has-tostringtag "^1.0.0" + async-function "^1.0.0" + call-bound "^1.0.3" + get-proto "^1.0.1" + has-tostringtag "^1.0.2" + safe-regex-test "^1.1.0" -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== +is-bigint@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.1.0.tgz#dda7a3445df57a42583db4228682eba7c4170672" + integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ== dependencies: - has-bigints "^1.0.1" + has-bigints "^1.0.2" is-binary-path@~2.1.0: version "2.1.0" @@ -7630,20 +7253,27 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== +is-boolean-object@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz#7067f47709809a393c71ff5bb3e135d8a9215d9e" + integrity sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A== dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" + call-bound "^1.0.3" + has-tostringtag "^1.0.2" is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: +is-bun-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-bun-module/-/is-bun-module-2.0.0.tgz#4d7859a87c0fcac950c95e666730e745eae8bddd" + integrity sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ== + dependencies: + semver "^7.7.1" + +is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== @@ -7655,31 +7285,41 @@ is-ci@^3.0.0: dependencies: ci-info "^3.2.0" -is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== +is-core-module@^2.13.0, is-core-module@^2.16.1: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== dependencies: - hasown "^2.0.0" + hasown "^2.0.2" -is-date-object@^1.0.1, is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== +is-data-view@^1.0.1, is-data-view@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.2.tgz#bae0a41b9688986c2188dda6657e56b8f9e63b8e" + integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw== dependencies: - has-tostringtag "^1.0.0" + call-bound "^1.0.2" + get-intrinsic "^1.2.6" + is-typed-array "^1.1.13" + +is-date-object@^1.0.5, is-date-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.1.0.tgz#ad85541996fc7aa8b2729701d27b7319f95d82f7" + integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg== + dependencies: + call-bound "^1.0.2" + has-tostringtag "^1.0.2" is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-finalizationregistry@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" - integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== +is-finalizationregistry@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz#eefdcdc6c94ddd0674d9c85887bf93f944a97c90" + integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg== dependencies: - call-bind "^1.0.2" + call-bound "^1.0.3" is-fullwidth-code-point@^3.0.0: version "3.0.0" @@ -7687,11 +7327,15 @@ is-fullwidth-code-point@^3.0.0: integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-function@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.2.tgz#ae3b61e3d5ea4e4839b90bad22b02335051a17d5" + integrity sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA== dependencies: - has-tostringtag "^1.0.0" + call-bound "^1.0.4" + generator-function "^2.0.0" + get-proto "^1.0.1" + has-tostringtag "^1.0.2" + safe-regex-test "^1.1.0" is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" @@ -7715,10 +7359,10 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== -is-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== +is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== is-mobile@^4.0.0: version "4.0.0" @@ -7730,68 +7374,74 @@ is-natural-number@^4.0.1: resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" integrity sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ== -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== +is-number-object@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.1.1.tgz#144b21e95a1bc148205dcc2814a9134ec41b2541" + integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw== dependencies: - has-tostringtag "^1.0.0" + call-bound "^1.0.3" + has-tostringtag "^1.0.2" is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== +is-regex@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" + integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" + call-bound "^1.0.2" + gopd "^1.2.0" + has-tostringtag "^1.0.2" + hasown "^2.0.2" -is-set@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== +is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== +is-shared-array-buffer@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz#9b67844bd9b7f246ba0708c3a93e34269c774f6f" + integrity sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A== dependencies: - call-bind "^1.0.2" + call-bound "^1.0.3" is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== +is-string@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9" + integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA== dependencies: - has-tostringtag "^1.0.0" + call-bound "^1.0.3" + has-tostringtag "^1.0.2" -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== +is-symbol@^1.0.4, is-symbol@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634" + integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w== dependencies: - has-symbols "^1.0.2" + call-bound "^1.0.2" + has-symbols "^1.1.0" + safe-regex-test "^1.1.0" -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== +is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15: + version "1.1.15" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" + integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== dependencies: - which-typed-array "^1.1.11" + which-typed-array "^1.1.16" is-unicode-supported@^0.1.0: version "0.1.0" @@ -7803,25 +7453,25 @@ is-unicode-supported@^2.0.0, is-unicode-supported@^2.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz#09f0ab0de6d3744d48d265ebb98f65d11f2a9b3a" integrity sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== +is-weakref@^1.0.2, is-weakref@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.1.1.tgz#eea430182be8d64174bd96bffbc46f21bf3f9293" + integrity sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew== dependencies: - call-bind "^1.0.2" + call-bound "^1.0.3" -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== +is-weakset@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.4.tgz#c9f5deb0bc1906c6d6f1027f284ddf459249daca" + integrity sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bound "^1.0.3" + get-intrinsic "^1.2.6" is-what@^4.1.8: version "4.1.16" @@ -7844,9 +7494,9 @@ isbinaryfile@^4.0.8: integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== isbinaryfile@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.0.tgz#034b7e54989dab8986598cbcea41f66663c65234" - integrity sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg== + version "5.0.7" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-5.0.7.tgz#19a73f2281b7368dca9d3b3ac8a0434074670979" + integrity sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ== isexe@^2.0.0: version "2.0.0" @@ -7854,9 +7504,9 @@ isexe@^2.0.0: integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isexe@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" - integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== + version "3.1.5" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.5.tgz#42e368f68d5e10dadfee4fda7b550bc2d8892dc9" + integrity sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.2: version "3.2.2" @@ -7880,16 +7530,17 @@ istanbul-reports@^3.2.0: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterator.prototype@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" - integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== +iterator.prototype@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.5.tgz#12c959a29de32de0aa3bbbb801f4d777066dae39" + integrity sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g== dependencies: - define-properties "^1.2.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - reflect.getprototypeof "^1.0.4" - set-function-name "^2.0.1" + define-data-property "^1.1.4" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.6" + get-proto "^1.0.0" + has-symbols "^1.1.0" + set-function-name "^2.0.2" jackspeak@^3.1.2: version "3.4.3" @@ -7900,44 +7551,43 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" -jackspeak@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.1.tgz#96876030f450502047fc7e8c7fcf8ce8124e43ae" - integrity sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ== +jackspeak@^4.1.1, jackspeak@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.2.3.tgz#27ef80f33b93412037c3bea4f8eddf80e1931483" + integrity sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg== dependencies: - "@isaacs/cliui" "^8.0.2" + "@isaacs/cliui" "^9.0.0" jake@^10.8.5: - version "10.8.7" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" - integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + version "10.9.4" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.4.tgz#d626da108c63d5cfb00ab5c25fadc7e0084af8e6" + integrity sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA== dependencies: - async "^3.2.3" - chalk "^4.0.2" + async "^3.2.6" filelist "^1.0.4" - minimatch "^3.1.2" + picocolors "^1.1.1" jiti@^1.21.0: - version "1.21.3" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.3.tgz#b2adb07489d7629b344d59082bbedb8c21c5f755" - integrity sha512-uy2bNX5zQ+tESe+TiC7ilGRz8AtRGmnJH55NC5S0nSUjvvvM2hJHmefHErugGXN4pNv4Qx7vLsnNw9qJ9mtIsw== + version "1.21.7" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.7.tgz#9dd81043424a3d28458b193d965f0d18a2300ba9" + integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== jiti@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.6.1.tgz#178ef2fc9a1a594248c20627cd820187a4d78d92" integrity sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ== +js-tokens@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-10.0.0.tgz#dffe7599b4a8bb7fe30aff8d0235234dffb79831" + integrity sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-tokens@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-9.0.1.tgz#2ec43964658435296f6761b34e10671c2d9527f4" - integrity sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ== - -js-yaml@^4.1.0: +js-yaml@^4.1.0, js-yaml@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== @@ -7994,9 +7644,9 @@ jsonfile@^4.0.0: graceful-fs "^4.1.6" jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + version "6.2.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62" + integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg== dependencies: universalify "^2.0.0" optionalDependencies: @@ -8020,9 +7670,9 @@ keyv@^4.0.0, keyv@^4.5.4: json-buffer "3.0.1" language-subtag-registry@^0.3.20: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + version "0.3.23" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7" + integrity sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ== language-tags@^1.0.9: version "1.0.9" @@ -8037,12 +7687,9 @@ lazy-val@^1.0.5: integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q== lenis@^1.0.45: - version "1.0.45" - resolved "https://registry.yarnpkg.com/lenis/-/lenis-1.0.45.tgz#5e34437527f30e10c87ada3c3c756c7c0caf8475" - integrity sha512-wiaYRxr7rK1rY+dhGdMLowV0rkjg+1B2nI50Igyu5USkjDY6lkBNCJi0mVaSL/X3ECyAm/oA0nsihq8ic3p9wg== - dependencies: - "@darkroom.engineering/tempus" "^0.0.46" - clsx "^2.1.0" + version "1.3.17" + resolved "https://registry.yarnpkg.com/lenis/-/lenis-1.3.17.tgz#5a8c486e6001703b7d50d412fff3348102f302e9" + integrity sha512-k9T9rgcxne49ggJOvXCraWn5dt7u2mO+BNkhyu6yxuEnm9c092kAW5Bus5SO211zUvx7aCCEtzy9UWr0RB+oJw== levn@^0.4.1: version "0.4.1" @@ -8132,9 +7779,9 @@ lilconfig@^2.1.0: integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== lilconfig@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc" - integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g== + version "3.1.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" + integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== lines-and-columns@^1.1.6: version "1.2.4" @@ -8223,9 +7870,9 @@ lru-cache@^10.0.1, lru-cache@^10.2.0: integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== lru-cache@^11.0.0: - version "11.0.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.2.tgz#fbd8e7cf8211f5e7e5d91905c415a3f55755ca39" - integrity sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA== + version "11.2.6" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.6.tgz#356bf8a29e88a7a2945507b31f6429a65a192c58" + integrity sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ== lru-cache@^5.1.1: version "5.1.1" @@ -8259,12 +7906,12 @@ magic-string@^0.30.21: "@jridgewell/sourcemap-codec" "^1.5.5" magicast@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.5.1.tgz#518959aea78851cd35d4bb0da92f780db3f606d3" - integrity sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw== + version "0.5.2" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.5.2.tgz#70cea9df729c164485049ea5df85a390281dfb9d" + integrity sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ== dependencies: - "@babel/parser" "^7.28.5" - "@babel/types" "^7.28.5" + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" source-map-js "^1.2.1" make-dir@^1.0.0: @@ -8338,9 +7985,9 @@ matcher@^3.0.0: escape-string-regexp "^4.0.0" math-expression-evaluator@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-2.0.6.tgz#a33028e4d55e7dcfcca17a696738e1a25b8e2c22" - integrity sha512-DRung1qNcKbgkhFeQ0fBPUFB6voRUMY7KyRyp1TRQ2v95Rp2egC823xLRooM1mDx1rmbkY7ym6ZWmpaE/VimOA== + version "2.0.7" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-2.0.7.tgz#dc99a80ce2bf7f9b7df878126feb5c506c1fdf5f" + integrity sha512-uwliJZ6BPHRq4eiqNWxZBDzKUiS5RIynFFcgchqhBOloVLVBpZpNG8jRYkedLcBvhph8TnRyWEuxPqiQcwIdog== math-intrinsics@^1.1.0: version "1.1.0" @@ -8415,15 +8062,7 @@ micromark-util-types@^2.0.0: resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz#f00225f5f5a0ebc3254f96c36b6605c4b393908e" integrity sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA== -micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -micromatch@^4.0.8: +micromatch@^4.0.5, micromatch@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== @@ -8476,11 +8115,11 @@ minimatch@9.0.3: brace-expansion "^2.0.1" minimatch@^10.0.0, minimatch@^10.1.1: - version "10.1.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.1.1.tgz#e6e61b9b0c1dcab116b5a7d1458e8b6ae9e73a55" - integrity sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ== + version "10.2.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.0.tgz#e710473e66e3e1aaf376d0aa82438375cac86e9e" + integrity sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w== dependencies: - "@isaacs/brace-expansion" "^5.0.0" + brace-expansion "^5.0.2" minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" @@ -8602,17 +8241,17 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -motion-dom@^12.23.23: - version "12.23.23" - resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-12.23.23.tgz#8f874333ea1a04ee3a89eb928f518b463d589e0e" - integrity sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA== +motion-dom@^12.23.23, motion-dom@^12.34.0: + version "12.34.0" + resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-12.34.0.tgz#d1776aaff750e09db66237c66daec31232a4cba8" + integrity sha512-Lql3NuEcScRDxTAO6GgUsRHBZOWI/3fnMlkMcH5NftzcN37zJta+bpbMAV9px4Nj057TuvRooMK7QrzMCgtz6Q== dependencies: - motion-utils "^12.23.6" + motion-utils "^12.29.2" -motion-utils@^12.23.6: - version "12.23.6" - resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.23.6.tgz#fafef80b4ea85122dd0d6c599a0c63d72881f312" - integrity sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ== +motion-utils@^12.23.6, motion-utils@^12.29.2: + version "12.29.2" + resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.29.2.tgz#8fdd28babe042c2456b078ab33b32daa3bf5938b" + integrity sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A== motion@12.23.24: version "12.23.24" @@ -8622,12 +8261,7 @@ motion@12.23.24: framer-motion "^12.23.24" tslib "^2.4.0" -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.0.0, ms@^2.1.1: +ms@^2.0.0, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -8641,15 +8275,15 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nanoid@^3.3.11: +nanoid@^3.3.11, nanoid@^3.3.6, nanoid@^3.3.7: version "3.3.11" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== -nanoid@^3.3.6: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +napi-postinstall@^0.3.0: + version "0.3.4" + resolved "https://registry.yarnpkg.com/napi-postinstall/-/napi-postinstall-0.3.4.tgz#7af256d6588b5f8e952b9190965d6b019653bbb9" + integrity sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ== natural-compare@^1.4.0: version "1.4.0" @@ -8657,9 +8291,9 @@ natural-compare@^1.4.0: integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== negotiator@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + version "0.6.4" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" + integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== negotiator@^1.0.0: version "1.0.0" @@ -8733,14 +8367,7 @@ node-addon-api@^7.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558" integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ== -node-api-version@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.0.tgz#5177441da2b1046a4d4547ab9e0972eed7b1ac1d" - integrity sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg== - dependencies: - semver "^7.3.5" - -node-api-version@^0.2.1: +node-api-version@^0.2.0, node-api-version@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/node-api-version/-/node-api-version-0.2.1.tgz#19bad54f6d65628cbee4e607a325e4488ace2de9" integrity sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q== @@ -8782,15 +8409,10 @@ node-pty@1.1.0-beta43: dependencies: node-addon-api "^7.1.0" -node-releases@^2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" - integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== - -node-releases@^2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" - integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== nopt@^6.0.0: version "6.0.0" @@ -8811,11 +8433,6 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - normalize-url@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" @@ -8836,70 +8453,66 @@ object-hash@^3.0.0: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-inspect@^1.13.1, object-inspect@^1.9.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== +object-inspect@^1.13.3, object-inspect@^1.13.4: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.4: - version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" - integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== +object.assign@^4.1.4, object.assign@^4.1.7: + version "4.1.7" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d" + integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== dependencies: - call-bind "^1.0.5" + call-bind "^1.0.8" + call-bound "^1.0.3" define-properties "^1.2.1" - has-symbols "^1.0.3" + es-object-atoms "^1.0.0" + has-symbols "^1.1.0" object-keys "^1.1.1" -object.entries@^1.1.6, object.entries@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" - integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.fromentries@^2.0.6, object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== +object.entries@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.9.tgz#e4770a6a1444afb61bd39f984018b5bede25f8b3" + integrity sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.8" + call-bound "^1.0.4" + define-properties "^1.2.1" + es-object-atoms "^1.1.1" -object.groupby@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== +object.fromentries@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" -object.hasown@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" - integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== +object.groupby@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== dependencies: - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" -object.values@^1.1.6, object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== +object.values@^1.1.6, object.values@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216" + integrity sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.8" + call-bound "^1.0.3" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" obug@^2.1.1: version "2.1.1" @@ -8932,26 +8545,26 @@ oniguruma-parser@^0.12.1: resolved "https://registry.yarnpkg.com/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz#82ba2208d7a2b69ee344b7efe0ae930c627dcc4a" integrity sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w== -oniguruma-to-es@^4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz#50db2c1e28ec365e102c1863dfd3d1d1ad18613e" - integrity sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg== +oniguruma-to-es@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/oniguruma-to-es/-/oniguruma-to-es-4.3.4.tgz#0b909d960faeb84511c979b1f2af64e9bc37ce34" + integrity sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA== dependencies: oniguruma-parser "^0.12.1" regex "^6.0.1" regex-recursion "^6.0.2" optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" 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" ora@9.1.0: version "9.1.0" @@ -8982,6 +8595,15 @@ ora@^5.1.0: strip-ansi "^6.0.0" wcwidth "^1.0.1" +own-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358" + integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg== + dependencies: + get-intrinsic "^1.2.6" + object-keys "^1.1.1" + safe-push-apply "^1.0.0" + p-cancelable@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" @@ -9014,9 +8636,9 @@ p-map@^7.0.2: integrity sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ== package-json-from-dist@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" - integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== param-case@^3.0.4: version "3.0.4" @@ -9095,9 +8717,9 @@ path-scurry@^1.11.1: minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-scurry@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" - integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.1.tgz#4b6572376cfd8b811fca9cd1f5c24b3cbac0fe10" + integrity sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA== dependencies: lru-cache "^11.0.0" minipass "^7.1.2" @@ -9129,12 +8751,7 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picocolors@^1.1.1: +picocolors@^1.0.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== @@ -9172,9 +8789,9 @@ pinkie@^2.0.0: integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== pirates@^4.0.1: - version "4.0.6" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" - integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + version "4.0.7" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" + integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== plist@3.1.0, plist@^3.0.4, plist@^3.0.5, plist@^3.1.0: version "3.1.0" @@ -9190,6 +8807,11 @@ pngjs@7.0.0, pngjs@^7.0.0: resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26" integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow== +possible-typed-array-names@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" + integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== + postcss-import@16.1.0: version "16.1.0" resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-16.1.0.tgz#258732175518129667fe1e2e2a05b19b5654b96a" @@ -9209,9 +8831,9 @@ postcss-import@^15.1.0: resolve "^1.1.7" postcss-js@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" - integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.1.0.tgz#003b63c6edde948766e40f3daf7e997ae43a5ce6" + integrity sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw== dependencies: camelcase-css "^2.0.1" @@ -9224,16 +8846,16 @@ postcss-load-config@^4.0.1: yaml "^2.3.4" postcss-nested@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" - integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== + version "6.2.0" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131" + integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ== dependencies: - postcss-selector-parser "^6.0.11" + postcss-selector-parser "^6.1.1" -postcss-selector-parser@^6.0.11: - version "6.0.15" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz#11cc2b21eebc0b99ea374ffb9887174855a01535" - integrity sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw== +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.1.1: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -9252,6 +8874,15 @@ postcss@8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@8.4.49: + version "8.4.49" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19" + integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.1" + source-map-js "^1.2.1" + postcss@^8, postcss@^8.4.23, postcss@^8.5.6: version "8.5.6" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" @@ -9331,9 +8962,9 @@ ps-tree@^1.2.0: event-stream "=3.3.4" pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + version "3.0.3" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d" + integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA== dependencies: end-of-stream "^1.1.0" once "^1.3.1" @@ -9370,11 +9001,11 @@ react-awesome-reveal@4.2.14: react-is "^18.3.1" react-awesome-reveal@^4.2.11: - version "4.2.11" - resolved "https://registry.yarnpkg.com/react-awesome-reveal/-/react-awesome-reveal-4.2.11.tgz#c76755cacdcf163b62fa041f3051073f0f11f6e8" - integrity sha512-BXdU3nzZkRYf6h2lIx4SCMEERhIQd7wKheHKRH8U9601m1U2W4LrwEpKbpUxIPWSjcUwci4w7EotdfF+9ZQHhQ== + version "4.3.1" + resolved "https://registry.yarnpkg.com/react-awesome-reveal/-/react-awesome-reveal-4.3.1.tgz#ffbd474b346e9581657ab335f74f995d251361a0" + integrity sha512-eMQqjNbk979ltKK/VUjw6+pGNa0Zg08ikCo7xCsi3BBX9sQSc2eVJMHXspEA/dS/1UiqFiZwgz19wlCL19+/qA== dependencies: - react-intersection-observer "^9.10.2" + react-intersection-observer "^9.13.0" react-is "^18.3.1" react-dom@18.2.0: @@ -9390,37 +9021,22 @@ react-fast-compare@^3.0.1: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== -react-icons@5.5.0: +react-icons@5.5.0, react-icons@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.5.0.tgz#8aa25d3543ff84231685d3331164c00299cdfaf2" integrity sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw== -react-icons@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.3.0.tgz#ccad07a30aebd40a89f8cfa7d82e466019203f1c" - integrity sha512-DnUk8aFbTyQPSkCfF8dbX6kQjXA9DktMeJqfjrg6cK9vwQVMxmcA3BfP4QoiztVmEHtwlTgLFsPuH2NskKT6eg== - -react-intersection-observer@^9.10.2: - version "9.10.2" - resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.10.2.tgz#d5b14f80c9a6bed525becc228db7dccac5d0ec1c" - integrity sha512-j2hGADK2hCbAlfaq6L3tVLb4iqngoN7B1fT16MwJ4J16YW/vWLcmAIinLsw0lgpZeMi4UDUWtHC9QDde0/P1yQ== - react-intersection-observer@^9.13.0: - version "9.13.1" - resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.13.1.tgz#6c61a75801162491c6348bad09967f2caf445584" - integrity sha512-tSzDaTy0qwNPLJHg8XZhlyHTgGW6drFKTtvjdL+p6um12rcnp8Z5XstE+QNBJ7c64n5o0Lj4ilUleA41bmDoMw== + version "9.16.0" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz#7376d54edc47293300961010844d53b273ee0fb9" + integrity sha512-w9nJSEp+DrW9KmQmeWHQyfaP6b03v+TdXynaoA964Wxt7mdR3An11z4NNCQgL4gKSK7y1ver2Fq+JKH6CWEzUA== react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -react-is@^18.3.1: +react-is@^18.2.0, react-is@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== @@ -9441,42 +9057,41 @@ react-popper@^2.3.0: react-fast-compare "^3.0.1" warning "^4.0.2" -react-remove-scroll-bar@^2.3.3: - version "2.3.5" - resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.5.tgz#cd2543b3ed7716c7c5b446342d21b0e0b303f47c" - integrity sha512-3cqjOqg6s0XbOjWvmasmqHch+RLxIEk2r/70rzGXuz3iIGQsQheEQyqYCBb5EECoD01Vo2SIbDqW4paLeLTASw== +react-remove-scroll-bar@^2.3.7: + version "2.3.8" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223" + integrity sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q== dependencies: - react-style-singleton "^2.2.1" + react-style-singleton "^2.2.2" tslib "^2.0.0" -react-remove-scroll@2.5.5: - version "2.5.5" - resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" - integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== +react-remove-scroll@^2.6.3: + version "2.7.2" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz#6442da56791117661978ae99cd29be9026fecca0" + integrity sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q== dependencies: - react-remove-scroll-bar "^2.3.3" - react-style-singleton "^2.2.1" + react-remove-scroll-bar "^2.3.7" + react-style-singleton "^2.2.3" tslib "^2.1.0" - use-callback-ref "^1.3.0" - use-sidecar "^1.1.2" + use-callback-ref "^1.3.3" + use-sidecar "^1.1.3" react-resizable-panels@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/react-resizable-panels/-/react-resizable-panels-2.1.2.tgz#42945db30d9677d42e12b2c0dc39870f7729e6b0" - integrity sha512-Ku2Bo7JvE8RpHhl4X1uhkdeT9auPBoxAOlGTqomDUUrBAX2mVGuHYZTcWvlnJSgx0QyHIxHECgGB5XVPUbUOkQ== + version "2.1.9" + resolved "https://registry.yarnpkg.com/react-resizable-panels/-/react-resizable-panels-2.1.9.tgz#874847710f4f122df749b5f08ebe9c72a1e338ca" + integrity sha512-z77+X08YDIrgAes4jl8xhnUu1LNIRp4+E7cv4xHmLOxxUPO/ML7PSrE813b90vj7xvQ1lcf7g2uA9GeMZonjhQ== react-selectable@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/react-selectable/-/react-selectable-2.1.1.tgz#21272e613929991e248570cc98a9266aa10eeecb" integrity sha512-5W7WrC+TCchIwE8wDQhV5F1iJXNZJN09RsIa7kgl8P8tcG7UOYSkK6M3Jundec90mB7iN+KOLeLivSRdf9WrxQ== -react-style-singleton@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" - integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== +react-style-singleton@^2.2.2, react-style-singleton@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388" + integrity sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ== dependencies: get-nonce "^1.0.0" - invariant "^2.2.4" tslib "^2.0.0" react-transition-group@^4.4.5: @@ -9490,9 +9105,9 @@ react-transition-group@^4.4.5: prop-types "^15.6.2" react-uid@^2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/react-uid/-/react-uid-2.3.3.tgz#6a485ccc868555997f3506c6db97a3e735d97adf" - integrity sha512-iNpDovcb9qBpBTo8iUgqRSQOS8GV3bWoNaTaUptHkXtAooXSo0OWe7vN6TqqB8x3x0bNBbQx96kkmSltQ5h9kQ== + version "2.4.0" + resolved "https://registry.yarnpkg.com/react-uid/-/react-uid-2.4.0.tgz#ce48a3e2a044964900f3ad5181a0d377702c56c5" + integrity sha512-+MVs/25NrcZuGrmlVRWPOSsbS8y72GJOBsR7d68j3/wqOrRBF52U29XAw4+XSelw0Vm6s5VmGH5mCbTCPGVCVg== dependencies: tslib "^2.0.0" @@ -9551,17 +9166,19 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -reflect.getprototypeof@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" - integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== +reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz#c629219e78a3316d8b604c765ef68996964e7bf9" + integrity sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - which-builtin-type "^1.1.3" + call-bind "^1.0.8" + define-properties "^1.2.1" + es-abstract "^1.23.9" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.7" + get-proto "^1.0.1" + which-builtin-type "^1.2.1" regex-recursion@^6.0.2: version "6.0.2" @@ -9576,20 +9193,23 @@ regex-utilities@^2.3.0: integrity sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng== regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/regex/-/regex-6.0.1.tgz#282fa4435d0c700b09c0eb0982b602e05ab6a34f" - integrity sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA== + version "6.1.0" + resolved "https://registry.yarnpkg.com/regex/-/regex-6.1.0.tgz#d7ce98f8ee32da7497c13f6601fca2bc4a6a7803" + integrity sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg== dependencies: regex-utilities "^2.3.0" -regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== +regexp.prototype.flags@^1.5.3, regexp.prototype.flags@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz#1ad6c62d44a259007e55b3970e00f746efbcaa19" + integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" + call-bind "^1.0.8" + define-properties "^1.2.1" + es-errors "^1.3.0" + get-proto "^1.0.1" + gopd "^1.2.0" + set-function-name "^2.0.2" require-directory@^2.1.1: version "2.1.1" @@ -9597,9 +9217,9 @@ require-directory@^2.1.1: integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== resedit@^1.7.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/resedit/-/resedit-1.7.1.tgz#150c101000210968730141ae2eb504ca0aead165" - integrity sha512-/FJ6/gKAXbcHtivannhecWsa43kGVFK3aHHv9Jm3x0eFiM31MoGihkAOWbm3UsvjYLRVw0zTkfARy2dI96JL1Q== + version "1.7.2" + resolved "https://registry.yarnpkg.com/resedit/-/resedit-1.7.2.tgz#b1041170b99811710c13f949c7d225871de4cc78" + integrity sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA== dependencies: pe-library "^0.4.1" @@ -9619,15 +9239,15 @@ resolve-pkg-maps@^1.0.0: integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== resolve@^1.1.7, resolve@^1.19.0, resolve@^1.22.2, resolve@^1.22.4: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== dependencies: - is-core-module "^2.13.0" + is-core-module "^2.16.1" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.4: +resolve@^2.0.0-next.5: version "2.0.0-next.5" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== @@ -9665,9 +9285,9 @@ retry@^0.12.0: integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" + integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== rimraf@6.0.1: version "6.0.1" @@ -9697,34 +9317,37 @@ roarr@^2.15.3: sprintf-js "^1.1.2" rollup@^4.43.0: - version "4.53.3" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.53.3.tgz#dbc8cd8743b38710019fb8297e8d7a76e3faa406" - integrity sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA== + version "4.57.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.57.1.tgz#947f70baca32db2b9c594267fe9150aa316e5a88" + integrity sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A== dependencies: "@types/estree" "1.0.8" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.53.3" - "@rollup/rollup-android-arm64" "4.53.3" - "@rollup/rollup-darwin-arm64" "4.53.3" - "@rollup/rollup-darwin-x64" "4.53.3" - "@rollup/rollup-freebsd-arm64" "4.53.3" - "@rollup/rollup-freebsd-x64" "4.53.3" - "@rollup/rollup-linux-arm-gnueabihf" "4.53.3" - "@rollup/rollup-linux-arm-musleabihf" "4.53.3" - "@rollup/rollup-linux-arm64-gnu" "4.53.3" - "@rollup/rollup-linux-arm64-musl" "4.53.3" - "@rollup/rollup-linux-loong64-gnu" "4.53.3" - "@rollup/rollup-linux-ppc64-gnu" "4.53.3" - "@rollup/rollup-linux-riscv64-gnu" "4.53.3" - "@rollup/rollup-linux-riscv64-musl" "4.53.3" - "@rollup/rollup-linux-s390x-gnu" "4.53.3" - "@rollup/rollup-linux-x64-gnu" "4.53.3" - "@rollup/rollup-linux-x64-musl" "4.53.3" - "@rollup/rollup-openharmony-arm64" "4.53.3" - "@rollup/rollup-win32-arm64-msvc" "4.53.3" - "@rollup/rollup-win32-ia32-msvc" "4.53.3" - "@rollup/rollup-win32-x64-gnu" "4.53.3" - "@rollup/rollup-win32-x64-msvc" "4.53.3" + "@rollup/rollup-android-arm-eabi" "4.57.1" + "@rollup/rollup-android-arm64" "4.57.1" + "@rollup/rollup-darwin-arm64" "4.57.1" + "@rollup/rollup-darwin-x64" "4.57.1" + "@rollup/rollup-freebsd-arm64" "4.57.1" + "@rollup/rollup-freebsd-x64" "4.57.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.57.1" + "@rollup/rollup-linux-arm-musleabihf" "4.57.1" + "@rollup/rollup-linux-arm64-gnu" "4.57.1" + "@rollup/rollup-linux-arm64-musl" "4.57.1" + "@rollup/rollup-linux-loong64-gnu" "4.57.1" + "@rollup/rollup-linux-loong64-musl" "4.57.1" + "@rollup/rollup-linux-ppc64-gnu" "4.57.1" + "@rollup/rollup-linux-ppc64-musl" "4.57.1" + "@rollup/rollup-linux-riscv64-gnu" "4.57.1" + "@rollup/rollup-linux-riscv64-musl" "4.57.1" + "@rollup/rollup-linux-s390x-gnu" "4.57.1" + "@rollup/rollup-linux-x64-gnu" "4.57.1" + "@rollup/rollup-linux-x64-musl" "4.57.1" + "@rollup/rollup-openbsd-x64" "4.57.1" + "@rollup/rollup-openharmony-arm64" "4.57.1" + "@rollup/rollup-win32-arm64-msvc" "4.57.1" + "@rollup/rollup-win32-ia32-msvc" "4.57.1" + "@rollup/rollup-win32-x64-gnu" "4.57.1" + "@rollup/rollup-win32-x64-msvc" "4.57.1" fsevents "~2.3.2" run-parallel@^1.1.9: @@ -9735,23 +9358,24 @@ run-parallel@^1.1.9: queue-microtask "^1.2.2" rxjs@^7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + version "7.8.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" + integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== dependencies: tslib "^2.1.0" -safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== +safe-array-concat@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" + integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" + call-bind "^1.0.8" + call-bound "^1.0.2" + get-intrinsic "^1.2.6" + has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@^5.1.1, safe-buffer@~5.2.0: +safe-buffer@^5.1.1, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -9761,14 +9385,22 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-regex-test@^1.0.0: +safe-push-apply@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + resolved "https://registry.yarnpkg.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz#01850e981c1602d398c85081f360e4e6d03d27f5" + integrity sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA== + dependencies: + es-errors "^1.3.0" + isarray "^2.0.5" + +safe-regex-test@^1.0.3, safe-regex-test@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" + integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" + call-bound "^1.0.2" + es-errors "^1.3.0" + is-regex "^1.2.1" "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" @@ -9783,14 +9415,14 @@ sanitize-filename@^1.6.3: truncate-utf8-bytes "^1.0.0" sax@^1.2.4: - version "1.3.0" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" - integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== + version "1.4.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.4.tgz#f29c2bba80ce5b86f4343b4c2be9f2b96627cf8b" + integrity sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw== scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: loose-envify "^1.1.0" @@ -9825,27 +9457,10 @@ semver@^6.2.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@^7.6.0, semver@^7.7.2: - version "7.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== - -semver@^7.6.3: - version "7.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" - integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== - -semver@^7.7.3: - version "7.7.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== +semver@^7.3.2, semver@^7.3.5, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3, semver@^7.7.1, semver@^7.7.2, semver@^7.7.3, semver@~7.7.3: + version "7.7.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" + integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== sentence-case@^3.0.4: version "3.0.4" @@ -9863,34 +9478,46 @@ serialize-error@^7.0.1: dependencies: type-fest "^0.13.1" -seroval-plugins@~1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/seroval-plugins/-/seroval-plugins-1.3.2.tgz#4200b538d699853c9bf5c3b7155c498c7c263a6a" - integrity sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ== +seroval-plugins@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/seroval-plugins/-/seroval-plugins-1.5.0.tgz#c02ba5f41d50b8105d4d9d4c553a4d01cec4226a" + integrity sha512-EAHqADIQondwRZIdeW2I636zgsODzoBDwb3PT/+7TLDWyw1Dy/Xv7iGUIEXXav7usHDE9HVhOU61irI3EnyyHA== -seroval@~1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/seroval/-/seroval-1.3.2.tgz#7e5be0dc1a3de020800ef013ceae3a313f20eca7" - integrity sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ== +seroval@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/seroval/-/seroval-1.5.0.tgz#aba4cffbd0c4c8a4351358362acf40ee8d74d97b" + integrity sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw== -set-function-length@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" - integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== +set-function-length@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== dependencies: - define-data-property "^1.1.1" - get-intrinsic "^1.2.1" + 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.0" + has-property-descriptors "^1.0.2" -set-function-name@^2.0.0, set-function-name@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== +set-function-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== dependencies: - define-data-property "^1.0.1" + define-data-property "^1.1.4" + es-errors "^1.3.0" functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" + has-property-descriptors "^1.0.2" + +set-proto@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/set-proto/-/set-proto-1.0.0.tgz#0760dbcff30b2d7e801fd6e19983e56da337565e" + integrity sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw== + dependencies: + dunder-proto "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" shallowequal@1.1.0: version "1.1.0" @@ -9976,32 +9603,63 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== shell-quote@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.2.tgz#d2d83e057959d53ec261311e9e9b8f51dcb2934a" - integrity sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA== + version "1.8.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" + integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== shiki@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-3.7.0.tgz#c27e214e48151ea0fca813d84cf2db87858a52d7" - integrity sha512-ZcI4UT9n6N2pDuM2n3Jbk0sR4Swzq43nLPgS/4h0E3B/NrFn2HKElrDtceSf8Zx/OWYOo7G1SAtBLypCp+YXqg== - dependencies: - "@shikijs/core" "3.7.0" - "@shikijs/engine-javascript" "3.7.0" - "@shikijs/engine-oniguruma" "3.7.0" - "@shikijs/langs" "3.7.0" - "@shikijs/themes" "3.7.0" - "@shikijs/types" "3.7.0" + version "3.22.0" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-3.22.0.tgz#3d590efee11feb75769354b1f64240915c3af827" + integrity sha512-LBnhsoYEe0Eou4e1VgJACes+O6S6QC0w71fCSp5Oya79inkwkm15gQ1UF6VtQ8j/taMDh79hAB49WUk8ALQW3g== + dependencies: + "@shikijs/core" "3.22.0" + "@shikijs/engine-javascript" "3.22.0" + "@shikijs/engine-oniguruma" "3.22.0" + "@shikijs/langs" "3.22.0" + "@shikijs/themes" "3.22.0" + "@shikijs/types" "3.22.0" "@shikijs/vscode-textmate" "^10.0.2" "@types/hast" "^3.0.4" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + es-errors "^1.3.0" + object-inspect "^1.13.3" + +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== + dependencies: + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + +side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" siginfo@^2.0.0: version "2.0.0" @@ -10019,9 +9677,9 @@ signal-exit@^4.0.1, signal-exit@^4.1.0: integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + version "0.2.4" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.4.tgz#a8d11a45a11600d6a1ecdff6363329e3648c3667" + integrity sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw== dependencies: is-arrayish "^0.3.1" @@ -10077,15 +9735,7 @@ socks-proxy-agent@^8.0.3: debug "^4.3.4" socks "^2.8.3" -socks@^2.6.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - -socks@^2.8.3: +socks@^2.6.2, socks@^2.8.3: version "2.8.7" resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea" integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A== @@ -10094,13 +9744,13 @@ socks@^2.8.3: smart-buffer "^4.2.0" solid-js@^1.9.5: - version "1.9.7" - resolved "https://registry.yarnpkg.com/solid-js/-/solid-js-1.9.7.tgz#96ff7800648a30f22d29275264375589f3a725e9" - integrity sha512-/saTKi8iWEM233n5OSi1YHCCuh66ZIQ7aK2hsToPe4tqGm7qAejU1SwNuTPivbWAYq7SjuHVVYxxuZQNRbICiw== + version "1.9.11" + resolved "https://registry.yarnpkg.com/solid-js/-/solid-js-1.9.11.tgz#1d36c755d10b7d5f7d016d2421c7e39b5b84f99e" + integrity sha512-WEJtcc5mkh/BnHA6Yrg4whlF8g6QwpmXXRg4P2ztPmcKeHHlH4+djYecBLhSpecZY2RRECXYUwIc/C2r3yzQ4Q== dependencies: csstype "^3.1.0" - seroval "~1.3.0" - seroval-plugins "~1.3.0" + seroval "~1.5.0" + seroval-plugins "~1.5.0" solid-refresh@^0.6.3: version "0.6.3" @@ -10112,21 +9762,16 @@ solid-refresh@^0.6.3: "@babel/types" "^7.23.6" sonner@^1.4.41: - version "1.4.41" - resolved "https://registry.yarnpkg.com/sonner/-/sonner-1.4.41.tgz#ff085ae4f4244713daf294959beaa3e90f842d2c" - integrity sha512-uG511ggnnsw6gcn/X+YKkWPo5ep9il9wYi3QJxHsYe7yTZ4+cOd1wuodOUmOpFuXL+/RE3R04LczdNCDygTDgQ== + version "1.7.4" + resolved "https://registry.yarnpkg.com/sonner/-/sonner-1.7.4.tgz#4c39820db86623800a17115c8970796aa862133a" + integrity sha512-DIS8z4PfJRbIyfVFDVnK9rO3eYDtse4Omcm6bt0oEr5/jtLgysmjuBl1frJ9E/EQZrFmKx2A8m/s5s9CRXIzhw== sonner@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/sonner/-/sonner-2.0.6.tgz#623b73faec55229d63ec35226d42021f2119bfa7" - integrity sha512-yHFhk8T/DK3YxjFQXIrcHT1rGEeTLliVzWbO0xN8GberVun2RiBnxAjXAYpZrqwEVHBG9asI/Li8TAAhN9m59Q== - -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + version "2.0.7" + resolved "https://registry.yarnpkg.com/sonner/-/sonner-2.0.7.tgz#810c1487a67ec3370126e0f400dfb9edddc3e4f6" + integrity sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w== -source-map-js@^1.2.1: +source-map-js@^1.0.2, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -10180,6 +9825,11 @@ ssri@^9.0.0: dependencies: minipass "^3.1.1" +stable-hash@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stable-hash/-/stable-hash-0.0.5.tgz#94e8837aaeac5b4d0f631d2972adef2924b40269" + integrity sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA== + stackback@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" @@ -10200,6 +9850,14 @@ stdin-discarder@^0.2.2: resolved "https://registry.yarnpkg.com/stdin-discarder/-/stdin-discarder-0.2.2.tgz#390037f44c4ae1a1ae535c5fe38dc3aba8d997be" integrity sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ== +stop-iteration-iterator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz#f481ff70a548f6124d0312c3aa14cbfa7aa542ad" + integrity sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ== + dependencies: + es-errors "^1.3.0" + internal-slot "^1.1.0" + stream-combiner@~0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" @@ -10240,54 +9898,80 @@ string-width@^5.1.2: strip-ansi "^7.0.1" string-width@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-8.1.0.tgz#9e9fb305174947cf45c30529414b5da916e9e8d1" - integrity sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg== + version "8.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-8.1.1.tgz#9b5aa0df72e3f232611c57fd47eb41dd97866bd3" + integrity sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw== dependencies: get-east-asian-width "^1.3.0" strip-ansi "^7.1.0" -string.prototype.matchall@^4.0.8: - version "4.0.10" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" - integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== +string.prototype.includes@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz#eceef21283640761a81dbe16d6c7171a4edf7d92" + integrity sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - regexp.prototype.flags "^1.5.0" - set-function-name "^2.0.0" - side-channel "^1.0.4" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== +string.prototype.matchall@^4.0.12: + version "4.0.12" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz#6c88740e49ad4956b1332a911e949583a275d4c0" + integrity sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA== + dependencies: + call-bind "^1.0.8" + call-bound "^1.0.3" + define-properties "^1.2.1" + es-abstract "^1.23.6" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.6" + gopd "^1.2.0" + has-symbols "^1.1.0" + internal-slot "^1.1.0" + regexp.prototype.flags "^1.5.3" + set-function-name "^2.0.2" + side-channel "^1.1.0" + +string.prototype.repeat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a" + integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + define-properties "^1.1.3" + es-abstract "^1.17.5" -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== +string.prototype.trim@^1.2.10: + version "1.2.10" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz#40b2dd5ee94c959b4dcfb1d65ce72e90da480c81" + integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.8" + call-bound "^1.0.2" + define-data-property "^1.1.4" + define-properties "^1.2.1" + es-abstract "^1.23.5" + es-object-atoms "^1.0.0" + has-property-descriptors "^1.0.2" -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== +string.prototype.trimend@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz#62e2731272cd285041b36596054e9f66569b6942" + integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ== + dependencies: + call-bind "^1.0.8" + call-bound "^1.0.2" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" string_decoder@^1.1.1: version "1.3.0" @@ -10325,14 +10009,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-ansi@^7.1.0: +strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.2" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba" integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== @@ -10369,19 +10046,19 @@ strnum@^2.1.0: integrity sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ== styled-components@^6.1.2: - version "6.1.6" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.6.tgz#c75c4f994136545b3bcc11608db5363710b78c0e" - integrity sha512-DgTLULSC29xpabJ24bbn1+hulU6vvGFQf4RPwBOJrm8WJFnN42yXpo5voBt3jDSJBa5tBd1L6PqswJjQ0wRKdg== + version "6.3.9" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.3.9.tgz#b03c36606e7fa449028af1433d86a849ab289931" + integrity sha512-J72R4ltw0UBVUlEjTzI0gg2STOqlI9JBhQOL4Dxt7aJOnnSesy0qJDn4PYfMCafk9cWOaVg129Pesl5o+DIh0Q== dependencies: - "@emotion/is-prop-valid" "1.2.1" - "@emotion/unitless" "0.8.0" - "@types/stylis" "4.2.0" + "@emotion/is-prop-valid" "1.4.0" + "@emotion/unitless" "0.10.0" + "@types/stylis" "4.2.7" css-to-react-native "3.2.0" - csstype "3.1.2" - postcss "8.4.31" + csstype "3.2.3" + postcss "8.4.49" shallowequal "1.1.0" - stylis "4.3.1" - tslib "2.5.0" + stylis "4.3.6" + tslib "2.8.1" styled-jsx@5.1.6: version "5.1.6" @@ -10395,22 +10072,22 @@ stylis@4.2.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== -stylis@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.1.tgz#ed8a9ebf9f76fe1e12d462f5cc3c4c980b23a7eb" - integrity sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ== +stylis@4.3.6: + version "4.3.6" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.6.tgz#7c7b97191cb4f195f03ecab7d52f7902ed378320" + integrity sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ== sucrase@^3.32.0: - version "3.35.0" - resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263" - integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA== + version "3.35.1" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.1.tgz#4619ea50393fe8bd0ae5071c26abd9b2e346bfe1" + integrity sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw== dependencies: "@jridgewell/gen-mapping" "^0.3.2" commander "^4.0.0" - glob "^10.3.10" lines-and-columns "^1.1.6" mz "^2.7.0" pirates "^4.0.1" + tinyglobby "^0.2.11" ts-interface-checker "^0.1.9" sumchecker@^3.0.1: @@ -10420,13 +10097,6 @@ sumchecker@^3.0.1: dependencies: debug "^4.1.0" -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -10447,16 +10117,14 @@ supports-preserve-symlinks-flag@^1.0.0: integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== tailwind-merge@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.2.1.tgz#3f10f296a2dba1d88769de8244fafd95c3324aeb" - integrity sha512-o+2GTLkthfa5YUt4JxPfzMIpQzZ3adD1vLVkvKE1Twl9UAhGsEbIZhHHZVRttyW177S8PDJI3bTQNaebyofK3Q== - dependencies: - "@babel/runtime" "^7.23.7" + version "2.6.1" + resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.6.1.tgz#a9d58240f664d21c33c379a092d9a273f833443b" + integrity sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ== tailwind-merge@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-3.0.2.tgz#567eff76de12211e24dd909da0f5ed6f4f422b0c" - integrity sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw== + version "3.4.0" + resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-3.4.0.tgz#5a264e131a096879965f1175d11f8c36e6b64eca" + integrity sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g== tailwindcss-animate@^1.0.7: version "1.0.7" @@ -10496,10 +10164,10 @@ tailwindcss@4.1.18: resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.1.18.tgz#f488ba47853abdb5354daf9679d3e7791fc4f4e3" integrity sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw== -tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== tar-stream@^1.5.2: version "1.6.2" @@ -10527,9 +10195,9 @@ tar@^6.0.5, tar@^6.1.11, tar@^6.1.12, tar@^6.2.1: yallist "^4.0.0" tar@^7.4.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.3.tgz#e1a41236e32446f75e63b720222112c4ffe5b3a1" - integrity sha512-ENg5JUHUm2rDD7IvKNFGzyElLXNjachNLp6RaGf4+JOgxXHkqA+gq81ZAMCUmtMtqBsoU62lcp6S27g1LCYGGQ== + version "7.5.7" + resolved "https://registry.yarnpkg.com/tar/-/tar-7.5.7.tgz#adf99774008ba1c89819f15dbd6019c630539405" + integrity sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ== dependencies: "@isaacs/fs-minipass" "^4.0.0" chownr "^3.0.0" @@ -10591,7 +10259,7 @@ tinyexec@^1.0.2: resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.0.2.tgz#bdd2737fe2ba40bd6f918ae26642f264b99ca251" integrity sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg== -tinyglobby@^0.2.12, tinyglobby@^0.2.15: +tinyglobby@^0.2.11, tinyglobby@^0.2.12, tinyglobby@^0.2.13, tinyglobby@^0.2.15: version "0.2.15" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== @@ -10612,19 +10280,18 @@ tmp-promise@^3.0.2: tmp "^0.2.0" tmp@^0.2.0: - version "0.2.4" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.4.tgz#c6db987a2ccc97f812f17137b36af2b6521b0d13" - integrity sha512-UdiSoX6ypifLmrfQ/XfiawN6hkjSBpCjhKxxZcWlUUmoXLaCKQU0bx4HF/tdDK2uzRuchf1txGvrWBzYREssoQ== + version "0.2.5" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" + integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow== to-buffer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" - integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + version "1.2.2" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133" + integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== + dependencies: + isarray "^2.0.5" + safe-buffer "^5.2.1" + typed-array-buffer "^1.0.3" to-regex-range@^5.0.1: version "5.0.1" @@ -10658,14 +10325,14 @@ truncate-utf8-bytes@^1.0.0: utf8-byte-length "^1.0.1" ts-api-utils@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" - integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + version "1.4.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" + integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== ts-api-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" - integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== + version "2.4.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.4.0.tgz#2690579f96d2790253bdcf1ca35d569ad78f9ad8" + integrity sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA== ts-interface-checker@^0.1.9: version "0.1.13" @@ -10692,21 +10359,16 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== - -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@~2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - -tslib@^2.6.2, tslib@^2.8.0: +tslib@2.8.1, tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== +tslib@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -10719,64 +10381,65 @@ type-fest@^0.13.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== +typed-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" + integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" + call-bound "^1.0.3" + es-errors "^1.3.0" + is-typed-array "^1.1.14" -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== +typed-array-byte-length@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz#8407a04f7d78684f3d252aa1a143d2b77b4160ce" + integrity sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.8" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.2.0" + has-proto "^1.2.0" + is-typed-array "^1.1.14" -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== +typed-array-byte-offset@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz#ae3698b8ec91a8ab945016108aef00d5bff12355" + integrity sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + available-typed-arrays "^1.0.7" + call-bind "^1.0.8" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.2.0" + has-proto "^1.2.0" + is-typed-array "^1.1.15" + reflect.getprototypeof "^1.0.9" -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== +typed-array-length@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.7.tgz#ee4deff984b64be1e118b0de8c9c877d5ce73d3d" + integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" for-each "^0.3.3" - is-typed-array "^1.1.9" + gopd "^1.0.1" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" + reflect.getprototypeof "^1.0.6" -typescript@5.9.3: +typescript@5.9.3, typescript@^5.4.3: version "5.9.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== -typescript@^5.4.3: - version "5.5.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba" - integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== +unbox-primitive@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz#8d9d2c9edeea8460c7f35033a88867944934d1e2" + integrity sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw== dependencies: - call-bind "^1.0.2" + call-bound "^1.0.3" has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" + has-symbols "^1.1.0" + which-boxed-primitive "^1.1.1" unbzip2-stream@^1.0.9: version "1.4.3" @@ -10791,6 +10454,11 @@ undici-types@~6.21.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== +undici-types@~7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" + integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== + unique-filename@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" @@ -10820,9 +10488,9 @@ unique-slug@^5.0.0: imurmurhash "^0.1.4" unist-util-is@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" - integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.1.tgz#d0a3f86f2dd0db7acd7d8c2478080b5c67f9c6a9" + integrity sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g== dependencies: "@types/unist" "^3.0.0" @@ -10841,17 +10509,17 @@ unist-util-stringify-position@^4.0.0: "@types/unist" "^3.0.0" unist-util-visit-parents@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" - integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + version "6.0.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz#777df7fb98652ce16b4b7cd999d0a1a40efa3a02" + integrity sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ== dependencies: "@types/unist" "^3.0.0" unist-util-is "^6.0.0" unist-util-visit@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" - integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + version "5.1.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.1.0.tgz#9a2a28b0aa76a15e0da70a08a5863a2f060e2468" + integrity sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg== dependencies: "@types/unist" "^3.0.0" unist-util-is "^6.0.0" @@ -10867,18 +10535,37 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== +unrs-resolver@^1.6.2: + version "1.11.1" + resolved "https://registry.yarnpkg.com/unrs-resolver/-/unrs-resolver-1.11.1.tgz#be9cd8686c99ef53ecb96df2a473c64d304048a9" + integrity sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg== dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -update-browserslist-db@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" - integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== + napi-postinstall "^0.3.0" + optionalDependencies: + "@unrs/resolver-binding-android-arm-eabi" "1.11.1" + "@unrs/resolver-binding-android-arm64" "1.11.1" + "@unrs/resolver-binding-darwin-arm64" "1.11.1" + "@unrs/resolver-binding-darwin-x64" "1.11.1" + "@unrs/resolver-binding-freebsd-x64" "1.11.1" + "@unrs/resolver-binding-linux-arm-gnueabihf" "1.11.1" + "@unrs/resolver-binding-linux-arm-musleabihf" "1.11.1" + "@unrs/resolver-binding-linux-arm64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-arm64-musl" "1.11.1" + "@unrs/resolver-binding-linux-ppc64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-riscv64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-riscv64-musl" "1.11.1" + "@unrs/resolver-binding-linux-s390x-gnu" "1.11.1" + "@unrs/resolver-binding-linux-x64-gnu" "1.11.1" + "@unrs/resolver-binding-linux-x64-musl" "1.11.1" + "@unrs/resolver-binding-wasm32-wasi" "1.11.1" + "@unrs/resolver-binding-win32-arm64-msvc" "1.11.1" + "@unrs/resolver-binding-win32-ia32-msvc" "1.11.1" + "@unrs/resolver-binding-win32-x64-msvc" "1.11.1" + +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -10904,48 +10591,43 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -use-callback-ref@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.1.tgz#9be64c3902cbd72b07fe55e56408ae3a26036fd0" - integrity sha512-Lg4Vx1XZQauB42Hw3kK7JM6yjVjgFmFC5/Ab797s79aARomD2nEErc4mCgM8EZrARLmmbWpi5DGCadmK50DcAQ== +use-callback-ref@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.3.tgz#98d9fab067075841c5b2c6852090d5d0feabe2bf" + integrity sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg== dependencies: tslib "^2.0.0" -use-sidecar@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" - integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== +use-sidecar@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.3.tgz#10e7fd897d130b896e2c546c63a5e8233d00efdb" + integrity sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ== dependencies: detect-node-es "^1.1.0" tslib "^2.0.0" use-sync-external-store@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + version "1.6.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" + integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== usehooks-ts@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-3.1.0.tgz#156119f36efc85f1b1952616c02580f140950eca" - integrity sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw== + version "3.1.1" + resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-3.1.1.tgz#0bb7f38f36f8219ee4509cc5e944ae610fb97656" + integrity sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA== dependencies: lodash.debounce "^4.0.8" utf8-byte-length@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" - integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz#f9f63910d15536ee2b2d5dd4665389715eac5c1e" + integrity sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA== util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -validate-html-nesting@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/validate-html-nesting/-/validate-html-nesting-1.2.3.tgz#22edb5c77de247f9b2b20f6becee3d8c614f24cb" - integrity sha512-kdkWdCl6eCeLlRShJKbjVOU2kFKxMF8Ghu50n+crEoyx+VKm3FxAxF9z4DCy6+bbTOqNW0+jcIYRnjoIRzigRw== - verror@^1.10.0: version "1.10.1" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb" @@ -10956,9 +10638,9 @@ verror@^1.10.0: extsprintf "^1.2.0" vfile-message@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181" - integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + version "4.0.3" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.3.tgz#87b44dddd7b70f0641c2e3ed0864ba73e2ea8df4" + integrity sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw== dependencies: "@types/unist" "^3.0.0" unist-util-stringify-position "^4.0.0" @@ -10972,9 +10654,9 @@ vfile@^6.0.0: vfile-message "^4.0.0" vite-plugin-solid@^2.11.6: - version "2.11.7" - resolved "https://registry.yarnpkg.com/vite-plugin-solid/-/vite-plugin-solid-2.11.7.tgz#be53fce2eab6e3709759160fcfd0373b2bea87d5" - integrity sha512-5TgK1RnE449g0Ryxb9BXqem89RSy7fE8XGVCo+Gw84IHgPuPVP7nYNP6WBVAaY/0xw+OqfdQee+kusL0y3XYNg== + version "2.11.10" + resolved "https://registry.yarnpkg.com/vite-plugin-solid/-/vite-plugin-solid-2.11.10.tgz#5646d1aa20162837959957cc4b47ed8b925d3604" + integrity sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw== dependencies: "@babel/core" "^7.23.3" "@types/babel__core" "^7.20.4" @@ -10983,7 +10665,7 @@ vite-plugin-solid@^2.11.6: solid-refresh "^0.6.3" vitefu "^1.0.4" -vite@7.3.1: +vite@7.3.1, "vite@^6.0.0 || ^7.0.0": version "7.3.1" resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.1.tgz#7f6cfe8fb9074138605e822a75d9d30b814d6507" integrity sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA== @@ -10997,20 +10679,6 @@ vite@7.3.1: optionalDependencies: fsevents "~2.3.3" -"vite@^6.0.0 || ^7.0.0": - version "7.2.4" - resolved "https://registry.yarnpkg.com/vite/-/vite-7.2.4.tgz#a3a09c7e25487612ecc1119c7d412c73da35bd4e" - integrity sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w== - dependencies: - esbuild "^0.25.0" - fdir "^6.5.0" - picomatch "^4.0.3" - postcss "^8.5.6" - rollup "^4.43.0" - tinyglobby "^0.2.15" - optionalDependencies: - fsevents "~2.3.3" - vitefu@^1.0.4: version "1.1.1" resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-1.1.1.tgz#c39b7e4c91bf2f6c590fb96e0758f394dff5795b" @@ -11057,62 +10725,65 @@ wcwidth@^1.0.1: defaults "^1.0.3" webm-muxer@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/webm-muxer/-/webm-muxer-5.0.2.tgz#57ce83caafe7942678ce1d123b09a37fd30c7563" - integrity sha512-/1m0ZGOcx8TvEmqY+U7GromXTKtto4pi5ou+ZvaQXEjb+G/v1cln2ZbKK3T4fpWhLBYjKBeYWza/y1Nxccm5pg== + version "5.1.4" + resolved "https://registry.yarnpkg.com/webm-muxer/-/webm-muxer-5.1.4.tgz#9fa307bad3fb6e836c2a24d8fb729e4982ea88bc" + integrity sha512-ditzgFVFbfqPaugkIr4mGhAdob5K9HY6Rzlh7TRsA368yA1sp/m5O7nQCcMLdgFDeNGtFPg8B+MeXLtpzKWX6Q== dependencies: "@types/dom-webcodecs" "^0.1.4" "@types/wicg-file-system-access" "^2020.9.5" -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== +which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e" + integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA== 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" + is-bigint "^1.1.0" + is-boolean-object "^1.2.1" + is-number-object "^1.1.1" + is-string "^1.1.1" + is-symbol "^1.1.1" -which-builtin-type@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" - integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== +which-builtin-type@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz#89183da1b4907ab089a6b02029cc5d8d6574270e" + integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q== dependencies: - function.prototype.name "^1.1.5" - has-tostringtag "^1.0.0" + call-bound "^1.0.2" + function.prototype.name "^1.1.6" + has-tostringtag "^1.0.2" is-async-function "^2.0.0" - is-date-object "^1.0.5" - is-finalizationregistry "^1.0.2" + is-date-object "^1.1.0" + is-finalizationregistry "^1.1.0" is-generator-function "^1.0.10" - is-regex "^1.1.4" + is-regex "^1.2.1" is-weakref "^1.0.2" isarray "^2.0.5" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" + which-boxed-primitive "^1.1.0" + which-collection "^1.0.2" + which-typed-array "^1.1.16" -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: - version "1.1.13" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" +which-collection@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== + dependencies: + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" + +which-typed-array@^1.1.16, which-typed-array@^1.1.19: + version "1.1.20" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.20.tgz#3fdb7adfafe0ea69157b1509f3a1cd892bd1d122" + integrity sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.8" + call-bound "^1.0.4" + for-each "^0.3.5" + get-proto "^1.0.1" + gopd "^1.2.0" + has-tostringtag "^1.0.2" which@^1.1.1: version "1.3.1" @@ -11143,6 +10814,11 @@ why-is-node-running@^2.3.0: siginfo "^2.0.0" stackback "0.0.2" +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -11202,9 +10878,9 @@ yaml@^1.10.0: integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yaml@^2.3.4: - version "2.3.4" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" - integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== + version "2.8.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.2.tgz#5694f25eca0ce9c3e7a9d9e00ce0ddabbd9e35c5" + integrity sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A== yargs-parser@^21.1.1: version "21.1.1"